[
  {
    "path": ".bowerrc",
    "content": "{\n    \"directory\": \"bower_components/\"\n}\n"
  },
  {
    "path": ".editorconfig",
    "content": "# EditorConfig: https://EditorConfig.org\n# Notepad++ Plugin: https://github.com/editorconfig/editorconfig-notepad-plus-plus\n# Visual Studio Code Plugin: https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig\n\nroot = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 4\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[{*.json,*.yml,*.yaml,*.md}]\nindent_size = 2\n\n# Ignore paths\n[{docs/css/**,docs/scss/_normalize.scss,**/vendor/**,dist/**}]\ncharset = unset\nend_of_line = unset\ninsert_final_newline = unset\ntrim_trailing_whitespace = unset\nindent_style = unset\nindent_size = unset\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# SCSS and JS files must always use LF for tools to work\n*.js eol=lf\n*.scss eol=lf\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: Alex-D\npatreon: AlexandreDemode\ncustom: https://paypal.me/demodealexandre\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!--- Provide a general summary of the issue in the Title above -->\n\n\n### Description\n<!--\nProvide relevant details according to the context:\n  - OS\n  - Browser + version\n  - Screen resolution\n  - ...\n-->\n\n\n### How to reproduce?\n<!--\nIf relevant, provide a link to a live example based on: https://jsfiddle.net/AlexandreDemode/p7hb3x6u/\n  - Edit\n  - Ctrl + S\n  - Copy/Paste the URL here\n-->\n"
  },
  {
    "path": ".github/workflows/lint.yml",
    "content": "name: Lint\n\non:\n  push:\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n\n      - run: npm ci\n\n      - run: npm run lint\n\n  editorconfig:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: editorconfig-checker/action-editorconfig-checker@main\n\n      - run: editorconfig-checker\n"
  },
  {
    "path": ".github/workflows/website.yml",
    "content": "name: Deploy Website\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n\n      - run: npm ci\n\n      - run: npm run build\n        working-directory: docs/\n\n      - uses: actions/upload-pages-artifact@v3\n        with:\n          path: docs/\n\n  deploy:\n    needs: build\n\n    # Grant GITHUB_TOKEN the permissions required to make a Pages deployment\n    permissions:\n      pages: write      # to deploy to Pages\n      id-token: write   # to verify the deployment originates from an appropriate source\n\n    # Deploy to the github-pages environment\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n\n    runs-on: ubuntu-latest\n    steps:\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions/deploy-pages@v4\n"
  },
  {
    "path": ".gitignore",
    "content": "# Others\n~$*\n/.sass-cache\n/uploaded-files\n/node_modules\n/bower_components\n/dist\n/src/ui/sass/_sprite*\n/plugins/**/ui/sass/_sprite*\n\n# We use npm: ignore yarn\nyarn.lock\n\n# Windows image file caches\nThumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Mac crap\n.DS_Store\n\n# IDEA\n.idea\n/nbproject\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n    \"bitwise\": true,\n    \"camelcase\": true,\n    \"esnext\": true,\n    \"curly\": true,\n    \"eqeqeq\": true,\n    \"forin\": true,\n    \"indent\": 4,\n    \"latedef\": false,\n    \"newcap\": false,\n    \"noarg\": true,\n    \"noempty\": true,\n    \"plusplus\": true,\n    \"quotmark\": \"single\",\n    \"undef\": true,\n    \"unused\": true,\n    \"strict\": true,\n    \"trailing\": true,\n    \"maxparams\": 5,\n    \"maxdepth\": 5,\n    \"maxstatements\": 40,\n    \"maxcomplexity\": 20,\n    \"maxlen\": 1200,\n    \"eqnull\": true,\n    \"browser\": true,\n    \"globals\": {\n        \"jQuery\": false\n    }\n}\n"
  },
  {
    "path": ".npmignore",
    "content": "Gulpfile.js\nbanner.jpg\nbower.json\nsrc\ndocs\nbower_components\n.gitattributes\n.gitignore\n.jshintrc\n.github\n.idea\n.bowerrc\nsponsors\nBACKERS.md\nCONTRIBUTORS.md\n"
  },
  {
    "path": "BACKERS.md",
    "content": "<h1 align=\"center\">Sponsors &amp; Backers</h1>\n\nTrumbowyg is an MIT-licensed open source project and completely free to use.\n\nHowever, the amount of effort needed to maintain and develop new features for\nthe project is not sustainable without proper financial backing.\nYou can support it's ongoing development by being a backer or a sponsor:\n\n- [Become a backer or sponsor on Patreon](https://www.patreon.com/alexandredemode)\n- [One-time donation via PayPal](https://www.paypal.me/demodealexandre/20eur)\n\n<h2 align=\"center\">Gold sponsors</h2>\n\n<p align=\"center\">\n    <a href=\"https://avot.nl/?ref=trumbowyg\">\n        <img src=\"https://rawcdn.githack.com/Alex-D/Trumbowyg/develop/sponsors/avot.svg\" alt=\"avot®\" width=\"200px\"/>\n    </a>\n</p>\n\n<p align=\"center\">\n    <a href=\"https://www.patreon.com/bePatron?c=1176005&rid=1940456\">\n        Become a Sponsor\n    </a>\n</p>\n\n<h2 align=\"center\">Silver sponsors</h2>\n\n<p align=\"center\">\n    <a href=\"https://socialoptic.com/?ref=trumbowyg\">\n        <img src=\"https://rawcdn.githack.com/Alex-D/Trumbowyg/develop/sponsors/socialoptic.png\" alt=\"SocialOptic\" width=\"150px\"/>\n    </a>\n</p>\n\n<p align=\"center\">\n    <a href=\"https://www.patreon.com/bePatron?c=1176005&rid=1940456\">\n        Become a Sponsor\n    </a>\n</p>\n\n<h2 align=\"center\">Backers</h2>\n\n- Johan Rosenson\n- Integrious Ltd\n\n<p align=\"center\">\n    <a href=\"https://www.patreon.com/bePatron?c=1176005&rid=1940349\">\n        Become a Backer\n    </a>\n</p>\n"
  },
  {
    "path": "CONTRIBUTORS.md",
    "content": "# Contributors\n\nTrumbowyg is the result of many people who made translations or the code better.\n\nSpecial thanks to [Adrien Gervaix](https://dribbble.com/adriengervaix) for the Trumbowyg v2 icon set.\n\n- Alex-D\n- Steve Rackham\n- Lawrence\n- Ra100\n- lizardK\n- Ulrich Mayring\n- Kirill Urgant\n- VeeeneX\n- Nicolas Pion\n- Sven Dunemann\n- Zane Chua\n- freekpost\n- Blufish Technologies\n- Civil\n- Danny Hiemstra\n- Edwin Veldhuizen\n- Florian\n- Michael Holroyd\n- Nicklas\n- Nicolás Moncada\n- Don Desroches\n- Jan Svoboda\n- Martin\n- Max Seelig\n- Stufingo\n- Alexander van Eerd\n- AragurDEV\n- Davor Budimir\n- Eduardo Russo\n- Fathi Anshory\n- Fyers\n- Hirokazu Kutsu\n- Justas Brazauskas\n- Jérôme Steunou\n- Manfred62\n- Merianos Nikos\n- Nikola Trifunovic\n- Paul Pritchard\n- Richard Kiewiet\n- Stef Kariotidis\n- Vijay Jagadeesan\n- Vlad Radulescu\n- Vladimir\n- foo9\n- g2010a\n- hiendv\n- jake johns\n- matopeter\n- ronan\n- sinjuice\n- Adam Balogh\n- AdamHess\n- Aleksandar Dimitrov\n- Aleksandr-ru\n- Alessio Dionisi\n- Alex Gotardi\n- Andreas Kohn\n- Andrei\n- Andrey Kogut\n- Antoine Leblanc\n- Anton Morozov\n- Artur\n- Benjamin Bourot\n- Bennett\n- Boylett\n- Burak Erdem\n- Burak Ozdemir\n- Carlos Barros\n- Chitoku\n- Christian\n- Christopher Kirk-Nielsen\n- maxom\n- Dariush Abbasi\n- Delvallée\n- Denis Jacquemin\n- Elisha Witte\n- Eric Radin\n- Ersin Guvenc\n- François Houlbrèque\n- Freek Post\n- Gabriel S. L\n- Grafikart\n- Henio Tierra\n- Hunor Karamán\n- Ian Mustafa\n- John Pozy\n- Jonathan Hedrén\n- Jonathan del Strother\n- JoongSeob Vito Kim\n- Jorrit Schippers\n- Karalkou\n- Ken Cheung\n- Kim Trolle Wadum\n- Lars Boldt\n- Leo Gono\n- Leopard Ho\n- MIRK0\n- Marcin Wieprzkowicz\n- Markus Spallek\n- Matt Johnson\n- Mattias Hagberg\n- Mike Goodfellow\n- Mike Richmond\n- Mitja Šlenc\n- Moisés Márquez\n- Nathan Rosquist\n- Nenad Novkovic\n- Nikki Locke\n- OBernard2\n- Oguzhan Inan\n- Oleg Berman\n- Paweł Abramowicz\n- Peter Dave Hello\n- Petr Čech\n- Philipp Palmtag\n- Ramiro Varandas Jr\n- Rezha Julio\n- Ricardo Cardeña\n- Roberto\n- Rodrigo Boratto\n- Sergey Golomedov\n- Stéphane Lavergne\n- TheGeekTortoise\n- Tiago Alves\n- TikiTDO\n- Tim\n- Timo Jarventausta\n- Todd Graham\n- Val\n- Vietworm\n- Vinzgore\n- Wisse Jelgersma\n- Zane J. Chua\n- abomokhahmed\n- adalenv\n- akai\n- basteyy\n- brainfogz\n- brentanalexander\n- chadidi\n- cleoo\n- de Oliveira Prado\n- dev.hibiki\n- dominiczaq\n- figroc\n- gonatee\n- joey91133\n- jsejakobsen\n- kingdido999\n- loclamor\n- luetge\n- munzur\n- naoh\n- root\n- slackwalker\n- teppokoivula\n- udidoron\n- Игорь\n- Михаил Гущин\n- Олег Ильин\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2012-2016 Alexandre Demode (Alex-D)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <a href=\"http://alex-d.github.io/Trumbowyg/\"><img src=\"banner.jpg\" alt=\"\" /></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://bundlephobia.com/result?p=trumbowyg\"><img src=\"https://img.shields.io/bundlephobia/minzip/trumbowyg.svg?style=for-the-badge\" alt=\"Downloads\" /></a>\n  <a href=\"https://www.npmjs.com/package/trumbowyg\"><img src=\"https://img.shields.io/npm/dm/trumbowyg.svg?color=blue&label=npm%20downloads&style=for-the-badge\" alt=\"Downloads\" /></a>\n  <a href=\"https://github.com/Alex-D/Trumbowyg/blob/develop/LICENSE\"><img src=\"https://img.shields.io/npm/l/trumbowyg.svg?color=blue&style=for-the-badge\" alt=\"Licence\" /></a>\n  <br>\n  <a href=\"https://www.npmjs.com/package/trumbowyg\"><img src=\"https://img.shields.io/npm/v/trumbowyg.svg?color=blue&style=for-the-badge\" alt=\"Version on npm\" /></a>\n  <a href=\"https://cdnjs.com/libraries/Trumbowyg\"><img src=\"https://img.shields.io/cdnjs/v/Trumbowyg.svg?color=blue&style=for-the-badge\" alt=\"CDNJS\" /></a>\n  <img src=\"https://img.shields.io/bower/v/trumbowyg.svg?color=blue&style=for-the-badge\" alt=\"Version on bower\" />\n</p>\n\n\n<h2 align=\"center\">Supporting Trumbowyg</h2>\n\nTrumbowyg is an MIT-licensed open source project and completely free to use.\n\nHowever, the amount of effort needed to maintain and develop new features for\nthe project is not sustainable without proper financial backing.\nYou can support its ongoing development by being a backer or a sponsor:\n\n- [Become a backer or sponsor on Patreon](https://www.patreon.com/alexandredemode)\n- [One-time donation via PayPal](https://www.paypal.me/demodealexandre/20eur)\n\n<h3 align=\"center\">Sponsors</h3>\n\n<h4 align=\"center\">Gold</h4>\n\n<p align=\"center\">\n    <a href=\"https://www.premirus.com/?ref=trumbowyg\">Premirus Corporation</a>\n</p>\n\n<p align=\"center\">\n    &bull;&bull;&bull;<br>\n    <a href=\"https://www.patreon.com/bePatron?c=1176005&rid=1940456\">\n        Become a Sponsor\n    </a>\n</p>\n\n------------------------------------\n\n## Introduction\n\nTrumbowyg is a simple and lightweight WYSIWYG editor, weight only 30kB minified (10kB gzip) for faster page loading.\n\nVisit presentation page: http://alex-d.github.io/Trumbowyg/\n\n## Documentation\n\nAll you need to know about Trumbowyg is here:\n\n- [Get started](https://alex-d.github.io/Trumbowyg/documentation/)\n- [25+ Demos](https://alex-d.github.io/Trumbowyg/demos/)\n- [45+ Supported languages](https://alex-d.github.io/Trumbowyg/#languages)\n- [All Options explained](https://alex-d.github.io/Trumbowyg/documentation/#basic-options)\n- [All existing Plugins](https://alex-d.github.io/Trumbowyg/documentation/plugins/)\n- [Create your own Plugin](https://alex-d.github.io/Trumbowyg/documentation/plugins/#create-your-own)\n\n## Contribution\n\nYou can contribute to Trumbowyg with translations in languages you know.\nThanks to `node` and `gulp`, you can improve core script, style or icons easily.\n\nFirst, fork and clone the repository\n\n```bash\ncd Trumbowyg # go into the project's root directory\nnpm install # install development dependencies\nnpm run dev # watch mode\nnpm run build # to build the project\n```\n\n## Author\n\n<table>\n  <tr width=\"100%\">\n    <td align=\"center\" width=\"100%\">\n      <a href=\"https://github.com/Alex-D\">\n        <img src=\"https://avatars2.githubusercontent.com/u/426843?s=150&v=4\"><br>\n        @Alex-D\n      </a> <br>\n      <strong>Alexandre Demode</strong><br>\n      &bull; &bull; &bull;<br>\n      <em>Latest release and announcements</em><br>\n      https://x.com/AlexandreDemode\n    </td>\n  </tr>\n</table>\n\n## License\n\nThis project is under [MIT license](LICENSE).\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"trumbowyg\",\n  \"version\": \"2.28.0\",\n  \"homepage\": \"https://github.com/Alex-D/Trumbowyg\",\n  \"authors\": [\n    {\n      \"name\": \"Alexandre Demode (Alex-D)\",\n      \"email\": \"contact@alex-d.fr\",\n      \"homepage\": \"https://alex-d.fr\"\n    }\n  ],\n  \"description\": \"A lightweight WYSIWYG editor\",\n  \"main\": \"dist/trumbowyg.js\",\n  \"keywords\": [\n    \"wysiwyg\",\n    \"editor\",\n    \"rich text\",\n    \"contenteditable\",\n    \"trumbowyg\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"bower_components\",\n    \"node_modules\",\n    \"plugins\",\n    \"!dist/plugins\",\n    \"test\",\n    \"tests\",\n    \"src\",\n    \"docs\",\n    \"sponsors\",\n    \"banner.jpg\",\n    \"gulpfile.js\",\n    \"package.json\"\n  ],\n  \"dependencies\": {\n    \"jquery\": \">=1.8\"\n  }\n}\n"
  },
  {
    "path": "docs/.gitignore",
    "content": "/node_modules/\n/bower_components\n/dist\n/src\n/plugins\nuploaded-files/\n"
  },
  {
    "path": "docs/.jshintrc",
    "content": "{\n    \"bitwise\": true,\n    \"camelcase\": true,\n    \"esnext\": true,\n    \"curly\": true,\n    \"eqeqeq\": true,\n    \"forin\": true,\n    \"indent\": 4,\n    \"latedef\": false,\n    \"newcap\": false,\n    \"noarg\": true,\n    \"noempty\": true,\n    \"plusplus\": true,\n    \"quotmark\": \"single\",\n    \"undef\": true,\n    \"unused\": true,\n    \"strict\": true,\n    \"trailing\": true,\n    \"maxparams\": 5,\n    \"maxdepth\": 5,\n    \"maxstatements\": 40,\n    \"maxcomplexity\": 20,\n    \"maxlen\": 1200,\n    \"eqnull\": true,\n    \"browser\": true,\n    \"node\": true,\n    \"globals\": {\n        \"jQuery\": false,\n        \"hljs\": false\n    }\n}\n"
  },
  {
    "path": "docs/css/main.css",
    "content": "/*! normalize.css v1.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}button,html,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:after,q:before{content:\"\";content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ol,nav ul{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@font-face{font-family:Panton;src:url(../fonts/panton.woff2) format(\"woff2\");font-weight:300;font-style:normal;font-display:swap}@font-face{font-family:\"Open Sans\";src:url(../fonts/open-sans-light.woff2) format(\"woff2\");font-weight:300;font-style:normal;font-display:swap}@font-face{font-family:\"Open Sans\";src:url(../fonts/open-sans-regular.woff2) format(\"woff2\");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:\"Open Sans\";src:url(../fonts/open-sans-semibold.woff2) format(\"woff2\");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:\"JetBrains Mono\";src:url(../fonts/jetbrains-mono-regular.woff2) format(\"woff2\");font-weight:400;font-style:normal;font-display:swap}/*! HTML5 Boilerplate v4.3.0 | MIT License | http://h5bp.com/ */button,html,input,select,textarea{color:#222}html{font-size:1em;line-height:1.4}body,html{background:#fff}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}audio,canvas,img,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}html{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*,:after,:before{-webkit-box-sizing:inherit;-moz-box-sizing:inherit;box-sizing:inherit}body,button,input,select,textarea{font-family:\"Open Sans\",sans-serif;font-size:18px;font-weight:300}.wrapper{max-width:1200px;margin:0 auto;clear:both}.wrapper p:last-child{margin-bottom:0}.wrapper h4{font-size:30px}.wrapper code.console{background:#392813;color:#fff;font-size:16px;padding:3px 7px}.wrapper .note{display:table;color:#666;background:rgba(0,0,0,.02);padding:8px 12px;border-left:3px solid #ffb864;border-radius:8px;font-size:15px;-webkit-margin-before:.5em;margin-block-start:.5em;-webkit-margin-after:.5em;margin-block-end:.5em}.wrapper .note>:first-child{margin-top:6px}.wrapper .note>:last-child{margin-bottom:6px}.wrapper .note code{margin-left:2px;margin-right:2px}.section a{text-decoration:none;color:#ff974a}.section a:focus,.section a:hover{text-decoration:underline}h1,h2,h3,h4,h5,h6{font-weight:300;margin:0;padding:0}hr.clearfix{display:block;border:none;background:0 0;margin:0;padding:0;height:0;clear:both}code,kbd,pre,samp{font-family:\"JetBrains Mono\",monospace;font-size:15px;line-height:1.5}:root{--tbw-cell-vertical-padding:4px;--tbw-cell-horizontal-padding:8px;--tbw-cell-line-height:1.5em}table{margin-bottom:var(--tbw-cell-line-height)}td,th{height:calc(var(--tbw-cell-vertical-padding) * 2 + var(--tbw-cell-line-height));min-width:calc(var(--tbw-cell-horizontal-padding) * 2);padding:var(--tbw-cell-vertical-padding) var(--tbw-cell-horizontal-padding);border:1px solid #e7eaec}thead{background:#fff}.button{display:inline-block;position:relative;width:250px;border:2px solid transparent;margin:0 auto;padding:23px 30px;color:#fff;font-weight:400;font-size:16px;line-height:1.2;text-decoration:none;border-radius:50px;text-align:center;-webkit-transition:color 150ms,background-color 150ms;-o-transition:color 150ms,background-color 150ms;transition:color 150ms,background-color 150ms}.button-primary{background:#ff974a}.button-secondary{background:#f48d40}.button-ghost{border-color:rgba(255,255,255,.4)}.button:not(:last-child){margin-right:20px}.button:focus,.button:hover{background:#fff;color:#ff974a;outline:0}.header-landing{position:relative;background:#ff974a -webkit-gradient(linear,right top,left bottom,from(#ff974a),to(#ffb864));background:#ff974a -webkit-linear-gradient(top right,#ff974a,#ffb864);background:#ff974a -o-linear-gradient(top right,#ff974a,#ffb864);background:#ff974a linear-gradient(to bottom left,#ff974a,#ffb864);text-align:center;color:#fff;padding-bottom:200px}.header-nav{float:right;width:100%;margin:0;padding:25px 40px 0;font-weight:400}.header-nav li{list-style:none;float:right;margin-right:30px}.header-nav li:first-child{float:left}.header-nav li:nth-child(2){margin-right:0}.header-nav li a{display:block;text-decoration:none;color:#b65207;font-size:16px;padding:10px 0;-webkit-transition:color 150ms;-o-transition:color 150ms;transition:color 150ms}.header-nav li a:hover{color:#fff}.header-nav li a.view-on-github{-webkit-transform:translateY(-11px);-ms-transform:translateY(-11px);-o-transform:translateY(-11px);transform:translateY(-11px)}.header-nav li a.view-on-github svg{width:25px;height:25px;fill:currentColor;margin-right:10px;vertical-align:baseline;-webkit-transform:translateY(5px);-ms-transform:translateY(5px);-o-transform:translateY(5px);transform:translateY(5px)}.header-nav li a.view-on-github .star{font-size:18px}.header-logo-container{margin:0 auto;padding-top:calc(80px + 4%);text-align:center}.header-logo-container .header-logo-h1{position:relative;margin:0 auto;width:1000px;max-width:100%}.header-logo-container .header-logo{margin-right:-3%;width:1000px;max-width:80%}.header-subtitle{font-size:28px;padding:0 20px}.header-description{font-size:18px;line-height:1.6;padding:0 20px;font-weight:300}.header-buttons{margin:50px 0}.header-install{font-size:18px;line-height:1.6;font-weight:300}#demonstration{padding-bottom:0;margin-bottom:80px}#demonstration .trumbowyg-editor,#demonstration .trumbowyg-textarea{padding:25px}#demonstration .trumbowyg:not(.trumbowyg-fullscreen),#trumbowyg-demo:not(.trumbowyg-textarea){margin:-150px auto 0;width:100%;height:340px;max-width:900px;background:#fff;-webkit-box-shadow:0 0 27px rgba(0,0,0,.03);box-shadow:0 0 27px rgba(0,0,0,.03);resize:none}#demonstration .trumbowyg{font-size:16px;line-height:2}#demonstration .trumbowyg p{margin:0 0 32px}#demonstration .trumbowyg button{font-weight:400}#trumbowyg-demo:not(.trumbowyg-textarea){color:transparent;overflow:hidden;border:1px solid #dbdfe0}.demo-switcher{position:absolute;bottom:-20px;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);-o-transform:translateX(-50%);transform:translateX(-50%);z-index:10;margin:0 auto;width:250px;height:40px;border-radius:50px;border:1px solid #dbdfe0;background:#fff}.demo-switcher .button{display:block;float:left;padding:10px;margin:0;border:none;width:50%;background:0 0;color:#392813;font-weight:300;-webkit-transition:color 150ms,text-indent 150ms;-o-transition:color 150ms,text-indent 150ms;transition:color 150ms,text-indent 150ms}.demo-switcher .button:first-child{text-indent:5px}.demo-switcher .button:last-child{text-indent:-5px}.demo-switcher .button.current{text-indent:0;color:#fff}.demo-switcher::after{content:\"\";display:block;width:50%;height:100%;border-radius:50px;background:#ff974a;-webkit-transition:margin-left 150ms;-o-transition:margin-left 150ms;transition:margin-left 150ms}.demo-switcher.current-plugins::after{margin-left:50%}.header-logo-animation{position:absolute;overflow:hidden;top:-30px;left:91.5%;width:150px;height:150px}.header-logo-animation svg{position:absolute;top:0;left:0;fill:#fff;height:25px;width:25px}.header-logo-animation .header-logo-animation-strong{-webkit-animation:headerLogoStrong 1s linear infinite;-o-animation:headerLogoStrong 1s linear infinite;animation:headerLogoStrong 1s linear infinite;-webkit-animation-delay:-.85s;-o-animation-delay:-.85s;animation-delay:-.85s}.header-logo-animation .header-logo-animation-p{-webkit-animation:headerLogoP 1s linear infinite;-o-animation:headerLogoP 1s linear infinite;animation:headerLogoP 1s linear infinite;-webkit-animation-delay:-.2s;-o-animation-delay:-.2s;animation-delay:-.2s}.header-logo-animation .header-logo-animation-link{-webkit-animation:headerLogoLink 1s linear infinite;-o-animation:headerLogoLink 1s linear infinite;animation:headerLogoLink 1s linear infinite;-webkit-animation-delay:-.4s;-o-animation-delay:-.4s;animation-delay:-.4s}.header-logo-animation .header-logo-animation-blockquote{-webkit-animation:headerLogoBlockquote 1s linear infinite;-o-animation:headerLogoBlockquote 1s linear infinite;animation:headerLogoBlockquote 1s linear infinite;-webkit-animation-delay:-.6s;-o-animation-delay:-.6s;animation-delay:-.6s}.header-logo-animation .header-logo-animation-view-html{-webkit-animation:headerLogoViewHtml 1s linear infinite;-o-animation:headerLogoViewHtml 1s linear infinite;animation:headerLogoViewHtml 1s linear infinite;-webkit-animation-delay:-.3s;-o-animation-delay:-.3s;animation-delay:-.3s}@-webkit-keyframes headerLogoStrong{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(70px);transform:translateX(-30px) translateY(70px)}20%{-webkit-transform:translateX(15px) translateY(80px);transform:translateX(15px) translateY(80px)}30%{-webkit-transform:translateX(35px) translateY(75px);transform:translateX(35px) translateY(75px)}40%{-webkit-transform:translateX(40px) translateY(60px);transform:translateX(40px) translateY(60px)}50%{opacity:1;-webkit-transform:translateX(35px) translateY(40px);transform:translateX(35px) translateY(40px)}100%{opacity:0;-webkit-transform:translateX(10px) translateY(0) scale(.5);transform:translateX(10px) translateY(0) scale(.5)}}@-o-keyframes headerLogoStrong{0%{opacity:1;-o-transform:translateX(-30px) translateY(70px);transform:translateX(-30px) translateY(70px)}20%{-o-transform:translateX(15px) translateY(80px);transform:translateX(15px) translateY(80px)}30%{-o-transform:translateX(35px) translateY(75px);transform:translateX(35px) translateY(75px)}40%{-o-transform:translateX(40px) translateY(60px);transform:translateX(40px) translateY(60px)}50%{opacity:1;-o-transform:translateX(35px) translateY(40px);transform:translateX(35px) translateY(40px)}100%{opacity:0;-o-transform:translateX(10px) translateY(0) scale(.5);transform:translateX(10px) translateY(0) scale(.5)}}@keyframes headerLogoStrong{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(70px);-o-transform:translateX(-30px) translateY(70px);transform:translateX(-30px) translateY(70px)}20%{-webkit-transform:translateX(15px) translateY(80px);-o-transform:translateX(15px) translateY(80px);transform:translateX(15px) translateY(80px)}30%{-webkit-transform:translateX(35px) translateY(75px);-o-transform:translateX(35px) translateY(75px);transform:translateX(35px) translateY(75px)}40%{-webkit-transform:translateX(40px) translateY(60px);-o-transform:translateX(40px) translateY(60px);transform:translateX(40px) translateY(60px)}50%{opacity:1;-webkit-transform:translateX(35px) translateY(40px);-o-transform:translateX(35px) translateY(40px);transform:translateX(35px) translateY(40px)}100%{opacity:0;-webkit-transform:translateX(10px) translateY(0) scale(.5);-o-transform:translateX(10px) translateY(0) scale(.5);transform:translateX(10px) translateY(0) scale(.5)}}@-webkit-keyframes headerLogoP{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(60px);transform:translateX(-30px) translateY(60px)}20%{-webkit-transform:translateX(10px) translateY(60px);transform:translateX(10px) translateY(60px)}30%{-webkit-transform:translateX(20px) translateY(60px);transform:translateX(20px) translateY(60px)}40%{-webkit-transform:translateX(25px) translateY(55px);transform:translateX(25px) translateY(55px)}50%{opacity:1;-webkit-transform:translateX(32px) translateY(40px);transform:translateX(32px) translateY(40px)}100%,90%{opacity:0;-webkit-transform:translateX(35px) translateY(20px) scale(.5);transform:translateX(35px) translateY(20px) scale(.5)}}@-o-keyframes headerLogoP{0%{opacity:1;-o-transform:translateX(-30px) translateY(60px);transform:translateX(-30px) translateY(60px)}20%{-o-transform:translateX(10px) translateY(60px);transform:translateX(10px) translateY(60px)}30%{-o-transform:translateX(20px) translateY(60px);transform:translateX(20px) translateY(60px)}40%{-o-transform:translateX(25px) translateY(55px);transform:translateX(25px) translateY(55px)}50%{opacity:1;-o-transform:translateX(32px) translateY(40px);transform:translateX(32px) translateY(40px)}100%,90%{opacity:0;-o-transform:translateX(35px) translateY(20px) scale(.5);transform:translateX(35px) translateY(20px) scale(.5)}}@keyframes headerLogoP{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(60px);-o-transform:translateX(-30px) translateY(60px);transform:translateX(-30px) translateY(60px)}20%{-webkit-transform:translateX(10px) translateY(60px);-o-transform:translateX(10px) translateY(60px);transform:translateX(10px) translateY(60px)}30%{-webkit-transform:translateX(20px) translateY(60px);-o-transform:translateX(20px) translateY(60px);transform:translateX(20px) translateY(60px)}40%{-webkit-transform:translateX(25px) translateY(55px);-o-transform:translateX(25px) translateY(55px);transform:translateX(25px) translateY(55px)}50%{opacity:1;-webkit-transform:translateX(32px) translateY(40px);-o-transform:translateX(32px) translateY(40px);transform:translateX(32px) translateY(40px)}100%,90%{opacity:0;-webkit-transform:translateX(35px) translateY(20px) scale(.5);-o-transform:translateX(35px) translateY(20px) scale(.5);transform:translateX(35px) translateY(20px) scale(.5)}}@-webkit-keyframes headerLogoLink{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(90px);transform:translateX(-30px) translateY(90px)}20%{-webkit-transform:translateX(15px) translateY(100px);transform:translateX(15px) translateY(100px)}30%{-webkit-transform:translateX(25px) translateY(95px);transform:translateX(25px) translateY(95px)}40%{-webkit-transform:translateX(30px) translateY(80px);transform:translateX(30px) translateY(80px)}50%{opacity:1;-webkit-transform:translateX(30px) translateY(70px);transform:translateX(30px) translateY(70px)}100%,90%{opacity:0;-webkit-transform:translateX(10px) translateY(0) scale(.5);transform:translateX(10px) translateY(0) scale(.5)}}@-o-keyframes headerLogoLink{0%{opacity:1;-o-transform:translateX(-30px) translateY(90px);transform:translateX(-30px) translateY(90px)}20%{-o-transform:translateX(15px) translateY(100px);transform:translateX(15px) translateY(100px)}30%{-o-transform:translateX(25px) translateY(95px);transform:translateX(25px) translateY(95px)}40%{-o-transform:translateX(30px) translateY(80px);transform:translateX(30px) translateY(80px)}50%{opacity:1;-o-transform:translateX(30px) translateY(70px);transform:translateX(30px) translateY(70px)}100%,90%{opacity:0;-o-transform:translateX(10px) translateY(0) scale(.5);transform:translateX(10px) translateY(0) scale(.5)}}@keyframes headerLogoLink{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(90px);-o-transform:translateX(-30px) translateY(90px);transform:translateX(-30px) translateY(90px)}20%{-webkit-transform:translateX(15px) translateY(100px);-o-transform:translateX(15px) translateY(100px);transform:translateX(15px) translateY(100px)}30%{-webkit-transform:translateX(25px) translateY(95px);-o-transform:translateX(25px) translateY(95px);transform:translateX(25px) translateY(95px)}40%{-webkit-transform:translateX(30px) translateY(80px);-o-transform:translateX(30px) translateY(80px);transform:translateX(30px) translateY(80px)}50%{opacity:1;-webkit-transform:translateX(30px) translateY(70px);-o-transform:translateX(30px) translateY(70px);transform:translateX(30px) translateY(70px)}100%,90%{opacity:0;-webkit-transform:translateX(10px) translateY(0) scale(.5);-o-transform:translateX(10px) translateY(0) scale(.5);transform:translateX(10px) translateY(0) scale(.5)}}@-webkit-keyframes headerLogoBlockquote{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(55px);transform:translateX(-30px) translateY(55px)}30%{-webkit-transform:translateX(5px) translateY(50px);transform:translateX(5px) translateY(50px)}40%{-webkit-transform:translateX(10px) translateY(45px);transform:translateX(10px) translateY(45px)}50%{opacity:1;-webkit-transform:translateX(13px) translateY(40px);transform:translateX(13px) translateY(40px)}100%{opacity:0;-webkit-transform:translateX(10px) translateY(10px) scale(.5);transform:translateX(10px) translateY(10px) scale(.5)}}@-o-keyframes headerLogoBlockquote{0%{opacity:1;-o-transform:translateX(-30px) translateY(55px);transform:translateX(-30px) translateY(55px)}30%{-o-transform:translateX(5px) translateY(50px);transform:translateX(5px) translateY(50px)}40%{-o-transform:translateX(10px) translateY(45px);transform:translateX(10px) translateY(45px)}50%{opacity:1;-o-transform:translateX(13px) translateY(40px);transform:translateX(13px) translateY(40px)}100%{opacity:0;-o-transform:translateX(10px) translateY(10px) scale(.5);transform:translateX(10px) translateY(10px) scale(.5)}}@keyframes headerLogoBlockquote{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(55px);-o-transform:translateX(-30px) translateY(55px);transform:translateX(-30px) translateY(55px)}30%{-webkit-transform:translateX(5px) translateY(50px);-o-transform:translateX(5px) translateY(50px);transform:translateX(5px) translateY(50px)}40%{-webkit-transform:translateX(10px) translateY(45px);-o-transform:translateX(10px) translateY(45px);transform:translateX(10px) translateY(45px)}50%{opacity:1;-webkit-transform:translateX(13px) translateY(40px);-o-transform:translateX(13px) translateY(40px);transform:translateX(13px) translateY(40px)}100%{opacity:0;-webkit-transform:translateX(10px) translateY(10px) scale(.5);-o-transform:translateX(10px) translateY(10px) scale(.5);transform:translateX(10px) translateY(10px) scale(.5)}}@-webkit-keyframes headerLogoViewHtml{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(90px);transform:translateX(-30px) translateY(90px)}40%{-webkit-transform:translateX(30px) translateY(105px);transform:translateX(30px) translateY(105px)}50%{-webkit-transform:translateX(40px) translateY(100px);transform:translateX(40px) translateY(100px)}60%{opacity:1;-webkit-transform:translateX(50px) translateY(90px);transform:translateX(50px) translateY(90px)}100%{opacity:0;-webkit-transform:translateX(70px) translateY(70px) scale(.5);transform:translateX(70px) translateY(70px) scale(.5)}}@-o-keyframes headerLogoViewHtml{0%{opacity:1;-o-transform:translateX(-30px) translateY(90px);transform:translateX(-30px) translateY(90px)}40%{-o-transform:translateX(30px) translateY(105px);transform:translateX(30px) translateY(105px)}50%{-o-transform:translateX(40px) translateY(100px);transform:translateX(40px) translateY(100px)}60%{opacity:1;-o-transform:translateX(50px) translateY(90px);transform:translateX(50px) translateY(90px)}100%{opacity:0;-o-transform:translateX(70px) translateY(70px) scale(.5);transform:translateX(70px) translateY(70px) scale(.5)}}@keyframes headerLogoViewHtml{0%{opacity:1;-webkit-transform:translateX(-30px) translateY(90px);-o-transform:translateX(-30px) translateY(90px);transform:translateX(-30px) translateY(90px)}40%{-webkit-transform:translateX(30px) translateY(105px);-o-transform:translateX(30px) translateY(105px);transform:translateX(30px) translateY(105px)}50%{-webkit-transform:translateX(40px) translateY(100px);-o-transform:translateX(40px) translateY(100px);transform:translateX(40px) translateY(100px)}60%{opacity:1;-webkit-transform:translateX(50px) translateY(90px);-o-transform:translateX(50px) translateY(90px);transform:translateX(50px) translateY(90px)}100%{opacity:0;-webkit-transform:translateX(70px) translateY(70px) scale(.5);-o-transform:translateX(70px) translateY(70px) scale(.5);transform:translateX(70px) translateY(70px) scale(.5)}}.section{position:relative;padding-bottom:100px}.section-primary{color:#b65207;background:-webkit-gradient(linear,right top,left bottom,from(#ff974a),to(#ffb864));background:-webkit-linear-gradient(top right,#ff974a,#ffb864);background:-o-linear-gradient(top right,#ff974a,#ffb864);background:linear-gradient(to bottom left,#ff974a,#ffb864)}.section-primary .section-title{color:#fff}.section-primary a{color:#fff}.section-secondary{background:#f4f7fa}.section h4{font-weight:400;color:#392813;font-size:28px;padding-top:80px}.section-title{text-align:center;font-family:Panton,sans-serif;font-size:100px;color:#ff974a;padding-top:100px;padding-bottom:30px}.section-subtitle{margin-top:-22px;font-size:23px;color:#392813;font-weight:400}.section-introduction{margin-top:50px;padding-bottom:70px}.section-introduction .introduction-section{height:300px}.section-introduction .introduction-section-col{position:relative;float:left;width:30%;margin-right:5%}.section-introduction .introduction-section-col:last-child{margin-right:0}.section-introduction .introduction-section-col-title{font-size:28px;font-weight:300;margin-bottom:0;padding-top:50px}.section-introduction .introduction-section-col-title img{height:40px;margin-right:8px;-webkit-transform:translateY(-3px);-ms-transform:translateY(-3px);-o-transform:translateY(-3px);transform:translateY(-3px)}.section-introduction .introduction-section-col-title img.illu-lightweight{-webkit-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}.section-introduction .introduction-section-col-description{font-size:18px;line-height:28px;margin-top:10px}.installation-first-step{height:400px;color:#392813;text-align:center;padding-top:10px;margin:20px 0 50px;border:1px solid rgba(0,0,0,.15);border-radius:8px}.installation-first-step code{display:block}.installation-first-step .installation-download,.installation-first-step .installation-package-managers{width:48%;float:left}.installation-first-step .installation-col-title{font-size:22px;padding:30px 0;color:#392813}.installation-first-step .button{display:block;color:#392813;border-color:rgba(0,0,0,.07);background-color:transparent;-webkit-box-shadow:0 0 50px rgba(0,0,0,.03);box-shadow:0 0 50px rgba(0,0,0,.03);-webkit-transition:background-color 150ms,color 150ms,-webkit-box-shadow 150ms;transition:background-color 150ms,color 150ms,-webkit-box-shadow 150ms;-o-transition:background-color 150ms,box-shadow 150ms,color 150ms;transition:background-color 150ms,box-shadow 150ms,color 150ms;transition:background-color 150ms,box-shadow 150ms,color 150ms,-webkit-box-shadow 150ms}.installation-first-step .button:hover{text-decoration:none;color:#fff;border-color:transparent;background-color:#ff974a;-webkit-box-shadow:0 0 50px rgba(255,151,74,.4);box-shadow:0 0 50px rgba(255,151,74,.4)}.installation-first-step .installation-or{position:relative;font-weight:700;text-transform:uppercase;width:4%;float:left;font-size:18px;margin:140px 0 20px;border-radius:50px;z-index:0}.installation-first-step .installation-or::before{content:\"\";display:block;position:absolute;top:50%;left:50%;z-index:-1;width:100%;padding-top:100%;min-width:45px;min-height:45px;background:#fff;border-radius:100%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.installation-first-step .installation-package-managers{font-size:18px}.installation-first-step .installation-package-managers code{padding-top:5px;line-height:1.6}.installation-first-step .installation-package-managers code+code{padding-top:0}.installation-first-step .installation-cdn{clear:both;width:100%}.languages p{text-align:center;margin:0 0 5px;font-size:18px;color:#fff}.languages p a{color:#b65207}.languages .languages-columns{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.languages .col-globe{-webkit-box-flex:1.07;-webkit-flex:1.07;-moz-box-flex:1.07;-ms-flex:1.07;flex:1.07;margin-top:30px}.languages .col-globe .globe{width:90%;-webkit-transform:translateX(-40px);-ms-transform:translateX(-40px);-o-transform:translateX(-40px);transform:translateX(-40px)}.languages .col-list{-webkit-box-flex:.93;-webkit-flex:.93;-moz-box-flex:.93;-ms-flex:.93;flex:.93;padding-top:80px;line-height:1.6;font-weight:400}.languages .col-list .continent-name{color:#fff;font-size:22px;font-weight:400;background:0 0;border:none;padding:0;margin:0}.languages .col-list .continent-name:focus{outline:0}.languages .col-list .continent-name::after{content:\"\";display:inline-block;height:0;width:0;border:6px solid transparent;border-left-color:#fff;-webkit-transform:translateX(5px) translateY(-1px);-ms-transform:translateX(5px) translateY(-1px);-o-transform:translateX(5px) translateY(-1px);transform:translateX(5px) translateY(-1px)}.languages .col-list li[style] .continent-name::after{border-left-color:transparent;border-top-color:#fff;-webkit-transform:translateX(2px) translateY(2px);-ms-transform:translateX(2px) translateY(2px);-o-transform:translateX(2px) translateY(2px);transform:translateX(2px) translateY(2px)}.languages .col-list .lang-code{display:inline-block;min-width:30px;padding-right:8px;opacity:.6;-webkit-transition:opacity 150ms;-o-transition:opacity 150ms;transition:opacity 150ms}.languages .col-list .lang-name{-webkit-transition:padding-left 150ms;-o-transition:padding-left 150ms;transition:padding-left 150ms}.languages .col-list a{color:#b65207;-webkit-transition:color 150ms;-o-transition:color 150ms;transition:color 150ms}.languages .col-list a:hover{color:#fff;text-decoration:none}.languages .col-list a:hover .lang-code{opacity:1}.languages .col-list a:hover .lang-name{padding-left:8px}.languages .col-list li,.languages .col-list ul{margin:0;padding:0;list-style:none}.languages .col-list>ul{padding-right:50px}.languages .col-list>ul>li{overflow:hidden;-webkit-transition:height 150ms linear;-o-transition:height 150ms linear;transition:height 150ms linear}.languages .col-list>ul>li[data-height]{height:30px}.languages .col-list>ul>li ul{padding:15px 0;-webkit-columns:2;-moz-columns:2;columns:2;line-height:1.8}.plugins-packages .wrapper{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.plugins-packages .col-plugins{-webkit-box-flex:1.07;-webkit-flex:1.07;-moz-box-flex:1.07;-ms-flex:1.07;flex:1.07}.plugins-packages .col-packages{-webkit-box-flex:.93;-webkit-flex:.93;-moz-box-flex:.93;-ms-flex:.93;flex:.93}.plugins-packages .section-title{text-align:left;-webkit-transform:translateX(-5px);-ms-transform:translateX(-5px);-o-transform:translateX(-5px);transform:translateX(-5px)}.plugins-packages p{padding:0 100px 0 0;line-height:1.6}.plugins-packages li,.plugins-packages ul{margin:0;padding:0;list-style:none}.plugins-packages ul{-webkit-columns:2;-moz-columns:2;columns:2;margin:50px 0 0;max-width:500px}.plugins-packages li a{position:relative;display:inline-block;overflow:visible;color:#392813;-webkit-transition:color 150ms,-webkit-transform 150ms;transition:color 150ms,-webkit-transform 150ms;-o-transition:color 150ms,-o-transform 150ms;transition:color 150ms,transform 150ms;transition:color 150ms,transform 150ms,-webkit-transform 150ms,-o-transform 150ms;line-height:1.8}.plugins-packages li a:hover{color:#ff974a;text-decoration:none}.plugins-packages li a img,.plugins-packages li a svg{display:inline-block;color:#ff974a;fill:#ff974a;width:20px;height:20px;margin-right:8px;vertical-align:sub}.donate-container{position:relative;max-width:800px;margin:0 auto}.donate-container .donate-description{width:100%;padding:30px 50px 50px;background:#f4f7fa;border-top-left-radius:6px;border-top-right-radius:6px}.donate-container .donate-footer{text-align:center;padding:50px 0;background:#ff974a -webkit-gradient(linear,right top,left bottom,from(#ff974a),to(#ffb864));background:#ff974a -webkit-linear-gradient(top right,#ff974a,#ffb864);background:#ff974a -o-linear-gradient(top right,#ff974a,#ffb864);background:#ff974a linear-gradient(to bottom left,#ff974a,#ffb864);border-bottom-left-radius:6px;border-bottom-right-radius:6px}.donate-container .donate-beer{position:absolute;left:-190px;bottom:-30px;width:250px}.donate-container .button{color:#fff;text-decoration:none}.donate-container .button:focus,.donate-container .button:hover{text-decoration:none;background:#fff;color:#ff974a}.sponsors-container{margin:150px 0 0;text-align:center}.sponsors-container a{padding:0 20px}.footer{margin-top:40px;text-align:center;color:#fff;background:-webkit-gradient(linear,right top,left bottom,from(#ff974a),to(#ffb864));background:-webkit-linear-gradient(top right,#ff974a,#ffb864);background:-o-linear-gradient(top right,#ff974a,#ffb864);background:linear-gradient(to bottom left,#ff974a,#ffb864);clear:both}.footer .footer-link,.footer .footer-text{display:inline-block;padding:40px}.footer .footer-text{padding-bottom:0}.footer .footer-text .hearts{font-size:18px;color:#b65207}.footer .footer-link{text-decoration:none;color:#fff;-webkit-transition:color .15s;-o-transition:color .15s;transition:color .15s}.footer .footer-link:focus,.footer .footer-link:hover{color:#b65207}/*!\n    Theme: GitHub\n    Description: Light theme as seen on github.com\n    Author: github.com\n    Maintainer: @Hirse\n    Updated: 2021-05-15\n\n    Outdated base version: https://github.com/primer/github-syntax-light\n    Current colors taken from GitHub's CSS\n*/pre code.hljs{display:block;overflow-x:auto;padding:0 1.5em;border-radius:8px;-webkit-box-shadow:0 4px 16px rgba(0,0,0,.02);box-shadow:0 4px 16px rgba(0,0,0,.02)}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-comment{font-style:italic}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}.documentation-body{background:#f4f7fa;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.documentation-body .main{padding:0 60px;height:100vh;width:78%;overflow:auto}.documentation-body .main-demos{padding:0;overflow:hidden}.documentation-body .main-demos iframe{width:100%;height:100vh;background:#f4f7fa}.documentation-body .main-demo-inner{width:100%}.documentation-body .section-title{padding:50px 0 0}.documentation-body h3{display:inline-block;font-weight:700;font-size:26px}.documentation-body h4{padding:20px 0 0}.documentation-body dd :not(pre)>code,.documentation-body dd>code,.documentation-body p :not(pre)>code,.documentation-body p>code,.documentation-body ul :not(pre)>code,.documentation-body ul>code{color:#616870;background:#dfe5eb;padding:0 5px;border-radius:4px}.documentation-body dd a code,.documentation-body p a code,.documentation-body ul a code{color:inherit}.documentation-body code.type{padding:0 3px;color:#b65207}.documentation-body code.type::before{content:\"<\"}.documentation-body code.type::after{content:\">\"}.documentation-body .button.button-demo{border-color:rgba(244,141,64,.6);color:#f48d40;width:auto;padding:10px 30px}.documentation-body .button.button-demo:focus,.documentation-body .button.button-demo:hover{text-decoration:none;border-color:#f48d40;background:#f48d40;color:#fff}.documentation-body ::-webkit-scrollbar{width:17px}.documentation-body ::-webkit-scrollbar-track{background:#f4f7fa}.documentation-body ::-webkit-scrollbar-thumb{background:#cfd7de;border:2px solid #f4f7fa}.documentation-body ::-webkit-scrollbar-thumb:hover{background:#616870}.header-documentation{margin-top:50px}.header-documentation .documentation-logo-link{display:block;margin:0 auto;width:80%;max-width:350px}.header-documentation .documentation-logo-link .documentation-logo{width:100%}.header-documentation .documentation-title{text-align:center;font-family:Panton,sans-serif;font-weight:100;line-height:1}@media (max-width:1290px){.header-documentation .documentation-title{font-size:2.5vw}}.header-documentation .documentation-menu{text-align:center;margin-top:40px;background:#f48d40}.header-documentation .documentation-menu a{display:inline-block;padding:20px 5px}.header-documentation .documentation-menu a:focus,.header-documentation .documentation-menu a:hover{text-decoration:underline}@media (max-width:1550px){.header-documentation .documentation-menu{padding:5px 7%}.header-documentation .documentation-menu a{width:48%;padding:10px 0}.header-documentation .documentation-menu .documentation-menu-dot{display:none}}.sidebar{position:relative;top:0;left:0;height:100vh;color:#fff;background:#ff974a -webkit-gradient(linear,right top,left bottom,from(#ff974a),to(#ffb864));background:#ff974a -webkit-linear-gradient(top right,#ff974a,#ffb864);background:#ff974a -o-linear-gradient(top right,#ff974a,#ffb864);background:#ff974a linear-gradient(to bottom left,#ff974a,#ffb864);width:22%}.sidebar ::-webkit-scrollbar-track{background:0 0}.sidebar ::-webkit-scrollbar-thumb{background:#ffb864;border:1px solid #ffb864;border-right:none}.sidebar ::-webkit-scrollbar-thumb:hover{background:#fff}.sidebar::after{content:\"\";display:block;position:absolute;left:0;bottom:70px;width:calc(100% - 17px);height:100px;background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,184,100,0)),to(#ffb864));background:-webkit-linear-gradient(top,rgba(255,184,100,0),#ffb864);background:-o-linear-gradient(top,rgba(255,184,100,0),#ffb864);background:linear-gradient(to bottom,rgba(255,184,100,0),#ffb864);pointer-events:none}.sidebar .sidebar-inner{overflow:auto;overflow-y:scroll;overflow-x:hidden;height:calc(100vh - 70px)}.sidebar li,.sidebar ul{padding:0;margin:0;list-style:none}.sidebar a{text-decoration:none;color:#fff;-webkit-transition:color 150ms,text-indent 150ms;-o-transition:color 150ms,text-indent 150ms;transition:color 150ms,text-indent 150ms}.sidebar .documentation-summary{position:relative;font-size:18px;margin-bottom:100px}.sidebar .documentation-summary>ul{max-width:340px;margin:0 auto;padding:0 30px}.sidebar .documentation-summary>ul .documentation-summary-title,.sidebar .documentation-summary>ul a{display:block;height:30px;line-height:30px;text-overflow:ellipsis;width:100%;white-space:nowrap;overflow:hidden}.sidebar .documentation-summary>ul>li{margin-top:30px}.sidebar .documentation-summary>ul>li:first-child{margin-top:50px}.sidebar .documentation-summary>ul>li .documentation-summary-title,.sidebar .documentation-summary>ul>li>a{font-weight:600;text-transform:uppercase;margin-bottom:5px}.sidebar .documentation-summary>ul>li>a:focus,.sidebar .documentation-summary>ul>li>a:hover{color:#b65207}.sidebar .documentation-summary>ul>li ul li a:focus,.sidebar .documentation-summary>ul>li ul li a:hover{color:#b65207;text-indent:10px}.sidebar .documentation-sidebar-beer{position:fixed;width:22%;bottom:0;left:0;background:#fff;height:70px}.sidebar .documentation-sidebar-beer a{position:relative;display:block;height:70px;width:100%;text-align:left;padding:10px 17px 0 0;background:0 0;border:none;border-top:1px solid #e9eef3;color:#9ca4ac}.sidebar .documentation-sidebar-beer a:focus{outline:0}.sidebar .documentation-sidebar-beer a .beer-icon{display:none}@media (min-width:1700px){.sidebar .documentation-sidebar-beer a .beer-icon{position:absolute;display:block;width:calc((100% - 236px)/ 2);height:50px;margin:0 auto}}.sidebar .documentation-sidebar-beer a .beer-label{position:relative;display:block;max-width:236px;margin:0 auto}@media (max-width:1290px){.sidebar .documentation-sidebar-beer a .beer-label{font-size:14px;margin:0;padding:7px 0 0 15px;width:200px}}.added-feature,.deprecated-feature{display:inline-block;padding:3px 13px;margin:0;color:#fff;font-size:14px;border-radius:50px;-webkit-transform:translateX(10px) translateY(-4px);-ms-transform:translateX(10px) translateY(-4px);-o-transform:translateX(10px) translateY(-4px);transform:translateX(10px) translateY(-4px)}.added-feature{background:#5ecb0e}.deprecated-feature{background:#ff9a4d}.deprecated-info{padding:7px 15px;border-radius:4px;background:#f2dfc1;border:1px solid #ff9a4d}.deprecated-info a{color:#ff9a4d}.version-tag{display:inline-block;padding:2px 6px;background:#5ecb0e;color:#fff;font-size:12px;font-style:normal;border-radius:20px}.note .version-tag{-webkit-transform:translateY(-1px);-ms-transform:translateY(-1px);-o-transform:translateY(-1px);transform:translateY(-1px)}.feature{position:relative;padding-bottom:60px}.feature::after{content:\" \";display:block;position:absolute;bottom:0;left:50%;width:40%;height:0;border-bottom:1px solid #ffb864;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);-o-transform:translateX(-50%);transform:translateX(-50%)}.feature h3,.feature h4{display:inline-block;position:relative}.feature h3{padding-top:50px;margin-left:-15px;padding-left:15px}.feature h4{font-size:20px;font-weight:700}.feature h3+a+h4,.feature h3+h4{display:block}.feature .title-link{display:block;position:absolute;left:-45px;height:30px;width:30px;opacity:0;text-align:center;text-decoration:none;background:#ff974a;border-radius:50%;-webkit-transform:translateY(-36px);-ms-transform:translateY(-36px);-o-transform:translateY(-36px);transform:translateY(-36px);-webkit-transition:opacity 150ms,background 150ms,color 150ms;-o-transition:opacity 150ms,background 150ms,color 150ms;transition:opacity 150ms,background 150ms,color 150ms}.feature .title-link:focus,.feature .title-link:hover{background:#fff;text-decoration:none}.feature .title-link:focus svg,.feature .title-link:hover svg{fill:#ff974a}.feature .title-link svg{fill:#fff;width:70%;height:100%}.feature h4+.title-link{-webkit-transform:translateY(-30px);-ms-transform:translateY(-30px);-o-transform:translateY(-30px);transform:translateY(-30px)}.feature:hover .title-link{opacity:1}.feature .trumbowyg-box,.feature .trumbowyg-editor{margin:24px auto}.sample-data{background:#fff;padding:25px}.sample-data h4{padding:0}.sample-data input{width:100%;border:none;padding:5px 7px;color:#616870;background:#dfe5eb}.sample-data input:not(:last-child){margin-bottom:10px}dl dt{display:inline-block;color:#1b2126;background:#dfe5eb;padding:0 4px 0 6px;border-radius:4px}dl dd{padding:5px 0 15px;margin-left:15px}dl dd ul{margin:.5em 0}.tree{list-style:none;background:#fff;padding:1em 1.5em;border-radius:8px;-webkit-box-shadow:0 4px 16px rgba(0,0,0,.02);box-shadow:0 4px 16px rgba(0,0,0,.02)}.tree ul{position:relative;list-style:none;margin:0;padding-left:8px;overflow:hidden}.tree li{padding-top:8px}.tree>li{padding-top:0}.tree ul li{position:relative;padding-left:16px}.tree ul li::after,.tree ul li::before{content:\"\";display:block;position:absolute;background:#ff974a}.tree ul li::before{top:20px;left:0;width:12px;height:1px}.tree ul li::after{left:0;bottom:calc(100% - 20px);width:1px;height:500px}"
  },
  {
    "path": "docs/demos/core/dark-theme.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Trumbowyg by Alex-D</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n    <style>\n        .documentation-body {\n            background: #1a1a1a;\n            color: #f4f7fa;\n        }\n\n        .documentation-body .section-title {\n            opacity: 0.9;\n        }\n\n        .section h4 {\n            color: #ccc;\n        }\n\n        .wrapper .note {\n            color: #ccc;\n            border-left-color: rgba(255, 184, 100, 0.7);\n        }\n\n        .hljs {\n            filter: invert(92%);\n        }\n    </style>\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Dark theme</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                Gives you a dark button pane.\n            </p>\n            <p class=\"note\">\n                For demo purpose, this page has been forced to be in dark mode.\n            </p>\n\n            <div class=\"trumbowyg-dark\">\n                <textarea id=\"editor\">\n<h2>Welcome to the dark side of Trumbowyg!</h2>\n<p>\n    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n    optio nam reiciendis eius beatae quibusdam!\n</p>\n<p>\n    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n    alternatively [About] The Purposes of Good and Evil). The original passage began: Neque porro quisquam est\n    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n</p>\n                </textarea>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"html\">\n&lt;!-- Wrap the editor with an element with the class trumbowyg-dark -->\n&lt;div class=\"trumbowyg-dark\">\n    &lt;textarea id=\"editor\">&lt;/textarea>\n&lt;/div>\n            </code></pre>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor').trumbowyg();\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THIS LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PRUPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/core/default.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Trumbowyg by Alex-D</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Default</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                No plugin, no options. Just naked Trumbowyg.\n            </p>\n\n            <div id=\"editor\">\n                <h2>This editor is the default build of Trumbowyg.</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor').trumbowyg();\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THIS LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PRUPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/core/simple.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Trumbowyg by Alex-D</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Simple</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                Only strong (bold), emphasis (italic), some align, image and link.\n            </p>\n\n            <div id=\"editor\">\n                <p style=\"text-align: center;\">\n                    <strong>Colllect</strong> &mdash; See <em>more</em> at <a href=\"https://colllect.io/?ref=trumbowyg\">https://colllect.io</a>\n                </p>\n                <p style=\"text-align: center;\">\n                    <img src=\"http://getcollect.io/images/install/ui.png\" alt=\"Colllect\" width=\"50%\">\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor').trumbowyg({\n    btns: [\n        ['strong', 'em'],\n        ['justifyLeft', 'justifyCenter'],\n        ['insertImage', 'link']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THIS LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PRUPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <title>Demos | Trumbowyg: A lightweight WYSIWYG editor | Alex-D / Alexandre Demode</title>\n    <meta name=\"description\" content=\"Trumbowyg is a jQuery plugin for create WYSIWYG editor\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <link rel=\"icon\" type=\"image/png\" href=\"../favicon.png\">\n\n    <link rel=\"stylesheet\" href=\"../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"overflow: hidden;visibility: hidden;height: 0;width: 0;\">\n    <symbol id=\"trumbowyg-link\" viewBox=\"0 0 72 72\">\n        <path d=\"M30.9 49.1l-6.7 6.7c-.8.8-1.6.9-2.1.9s-1.4-.1-2.1-.9l-5.2-5.2c-1.1-1.1-1.1-3.1 0-4.2l6.1-6.1.2-.2 6.5-6.5c-1.2-.6-2.5-.9-3.8-.9-2.3 0-4.6.9-6.3 2.6L10.8 42c-3.5 3.5-3.5 9.2 0 12.7l5.2 5.2c1.7 1.7 4 2.6 6.3 2.6s4.6-.9 6.3-2.6l6.7-6.7C38 50.5 38.6 46.3 37 43l-6.1 6.1zM38.5 22.7l6.7-6.7c.8-.8 1.6-.9 2.1-.9s1.4.1 2.1.9l5.2 5.2c1.1 1.1 1.1 3.1 0 4.2l-6.1 6.1-.2.2-6.5 6.5c1.2.6 2.5.9 3.8.9 2.3 0 4.6-.9 6.3-2.6l6.7-6.7c3.5-3.5 3.5-9.2 0-12.7l-5.2-5.2c-1.7-1.7-4-2.6-6.3-2.6s-4.6.9-6.3 2.6l-6.7 6.7c-2.7 2.7-3.3 6.9-1.7 10.2l6.1-6.1z\"></path>\n        <path d=\"M44.1 30.7c.2-.2.4-.6.4-.9 0-.3-.1-.6-.4-.9l-2.3-2.3c-.2-.2-.6-.4-.9-.4-.3 0-.6.1-.9.4L25.8 40.8c-.2.2-.4.6-.4.9 0 .3.1.6.4.9l2.3 2.3c.2.2.6.4.9.4.3 0 .6-.1.9-.4l14.2-14.2z\"></path>\n    </symbol>\n</svg>\n<div class=\"sidebar\">\n    <div class=\"sidebar-inner\">\n        <header class=\"header-documentation\">\n            <a href=\"../\" class=\"documentation-logo-link\" title=\"Back to Trumbowyg landing\">\n                <img src=\"../img/logo-doc.svg\" alt=\"\" class=\"documentation-logo\">\n            </a>\n            <h1 class=\"documentation-title\">\n                Demos\n            </h1>\n            <nav class=\"documentation-menu\">\n                <a href=\"../documentation/\">Docs</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"../documentation/plugins/\">Plugins</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"../documentation/core/\">Core</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"../demos/\">Demos</a>\n            </nav>\n        </header>\n\n        <aside class=\"documentation-summary\">\n            <ul>\n                <li>\n                    <span class=\"documentation-summary-title\">Core</span>\n                    <ul>\n                        <li><a href=\"./core/default.html\">Default</a></li>\n                        <li><a href=\"./core/simple.html\">Simple</a></li>\n                        <li><a href=\"./core/dark-theme.html\">Dark theme</a></li>\n                    </ul>\n                </li>\n                <li>\n                    <span class=\"documentation-summary-title\">Plugins</span>\n                    <ul>\n                        <li><a href=\"./plugins/allowtagsfrompaste.html\">Allow tags from paste</a></li>\n                        <li><a href=\"./plugins/base64.html\">Base 64</a></li>\n                        <li><a href=\"./plugins/cleanpaste.html\">Clean paste</a></li>\n                        <li><a href=\"./plugins/colors.html\">Colors</a></li>\n                        <li><a href=\"./plugins/emoji.html\">Emoji</a></li>\n                        <li><a href=\"./plugins/fontfamily.html\">Font family</a></li>\n                        <li><a href=\"./plugins/fontsize.html\">Font size</a></li>\n                        <li><a href=\"./plugins/giphy.html\">Giphy</a></li>\n                        <li><a href=\"./plugins/highlight.html\">Highlight</a></li>\n                        <li><a href=\"./plugins/history.html\">History</a></li>\n                        <li><a href=\"./plugins/indent.html\">Indent</a></li>\n                        <li><a href=\"./plugins/insertaudio.html\">Insert audio</a></li>\n                        <li><a href=\"./plugins/lineheight.html\">Line height</a></li>\n                        <li><a href=\"./plugins/mathml.html\">MathML</a></li>\n                        <li><a href=\"./plugins/mention.html\">Mention</a></li>\n                        <li><a href=\"./plugins/noembed.html\">Noembed</a></li>\n                        <li><a href=\"./plugins/pasteembed.html\">Paste embed</a></li>\n                        <li><a href=\"./plugins/pasteimage.html\">Paste image</a></li>\n                        <li><a href=\"./plugins/preformatted.html\">Preformatted</a></li>\n                        <li><a href=\"./plugins/resizimg.html\">Resizimg</a></li>\n                        <li><a href=\"./plugins/ruby.html\">Ruby</a></li>\n                        <li><a href=\"./plugins/specialchars.html\">Special chars</a></li>\n                        <li><a href=\"./plugins/speechrecognition.html\">Speech recognition</a></li>\n                        <li><a href=\"./plugins/table.html\">Table</a></li>\n                        <li><a href=\"./plugins/template.html\">Template</a></li>\n                        <li><a href=\"./plugins/tenor.html\">Tenor</a></li>\n                        <li><a href=\"./plugins/upload.html\">Upload</a></li>\n                    </ul>\n                </li>\n            </ul>\n        </aside>\n\n        <div class=\"documentation-sidebar-beer\">\n            <a href=\"../#donate\">\n                <img src=\"../img/beer.svg\" alt=\"\" class=\"beer-icon\">\n                <span class=\"beer-label\">\n                    Do you enjoy Trumbowyg? <br>\n                    Buy me some beers :)\n                </span>\n            </a>\n        </div>\n    </div>\n</div>\n\n<main class=\"main main-demos\">\n    <iframe src=\"./core/default.html\" frameborder=\"0\"></iframe>\n</main>\n\n\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<script src=\"../js/vendor/highlight.js\"></script>\n<script src=\"../js/main.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/js/highlight.js",
    "content": "!function(e){\"undefined\"!=typeof exports?e(exports):(window.hljs=e({}),\"function\"==typeof define&&define.amd&&define([],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,\"&amp;\").replace(/</gm,\"&lt;\").replace(/>/gm,\"&gt;\")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){var n=(e.className+\" \"+(e.parentNode?e.parentNode.className:\"\")).split(/\\s+/);return n=n.map(function(e){return e.replace(/^lang(uage)?-/,\"\")}),n.filter(function(e){return N(e)||/no(-?)highlight/.test(e)})[0]}function o(e,n){var t={};for(var r in e)t[r]=e[r];if(n)for(var r in n)t[r]=n[r];return t}function i(e){var n=[];return function r(e,a){for(var o=e.firstChild;o;o=o.nextSibling)3==o.nodeType?a+=o.nodeValue.length:1==o.nodeType&&(n.push({event:\"start\",offset:a,node:o}),a=r(o,a),t(o).match(/br|hr|img|input/)||n.push({event:\"stop\",offset:a,node:o}));return a}(e,0),n}function c(e,r,a){function o(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset<r[0].offset?e:r:\"start\"==r[0].event?e:r:e.length?e:r}function i(e){function r(e){return\" \"+e.nodeName+'=\"'+n(e.value)+'\"'}l+=\"<\"+t(e)+Array.prototype.map.call(e.attributes,r).join(\"\")+\">\"}function c(e){l+=\"</\"+t(e)+\">\"}function u(e){(\"start\"==e.event?i:c)(e.node)}for(var s=0,l=\"\",f=[];e.length||r.length;){var g=o();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=o();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(i)}else\"start\"==g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function u(e){function n(e){return e&&e.source||e}function t(t,r){return RegExp(n(t),\"m\"+(e.cI?\"i\":\"\")+(r?\"g\":\"\"))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var c={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(\" \").forEach(function(e){var t=e.split(\"|\");c[t[0]]=[n,t[1]?Number(t[1]):1]})};\"string\"==typeof a.k?u(\"keyword\",a.k):Object.keys(a.k).forEach(function(e){u(e,a.k[e])}),a.k=c}a.lR=t(a.l||/\\b[A-Za-z0-9_]+\\b/,!0),i&&(a.bK&&(a.b=\"\\\\b(\"+a.bK.split(\" \").join(\"|\")+\")\\\\b\"),a.b||(a.b=/\\B|\\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\\B|\\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||\"\",a.eW&&i.tE&&(a.tE+=(a.e?\"|\":\"\")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push(\"self\"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?\"\\\\.?(\"+e.b+\")\\\\.?\":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join(\"|\"),!0):{exec:function(){return null}}}}r(e)}function s(e,t,a,o){function i(e,n){for(var t=0;t<n.c.length;t++)if(r(n.c[t].bR,e))return n.c[t]}function c(e,n){return r(e.eR,n)?e:e.eW?c(e.parent,n):void 0}function f(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=x.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?\"\":E.classPrefix,o='<span class=\"'+a,i=t?\"\":\"</span>\";return o+=e+'\">',o+n+i}function d(){if(!w.k)return n(y);var e=\"\",t=0;w.lR.lastIndex=0;for(var r=w.lR.exec(y);r;){e+=n(y.substr(t,r.index-t));var a=g(w,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=w.lR.lastIndex,r=w.lR.exec(y)}return e+n(y.substr(t))}function h(){if(w.sL&&!R[w.sL])return n(y);var e=w.sL?s(w.sL,y,!0,L[w.sL]):l(y);return w.r>0&&(B+=e.r),\"continuous\"==w.subLanguageMode&&(L[w.sL]=e.top),p(e.language,e.value,!1,!0)}function v(){return void 0!==w.sL?h():d()}function b(e,t){var r=e.cN?p(e.cN,\"\",!0):\"\";e.rB?(M+=r,y=\"\"):e.eB?(M+=n(t)+r,y=\"\"):(M+=r,y=t),w=Object.create(e,{parent:{value:w}})}function m(e,t){if(y+=e,void 0===t)return M+=v(),0;var r=i(t,w);if(r)return M+=v(),b(r,t),r.rB?0:t.length;var a=c(w,t);if(a){var o=w;o.rE||o.eE||(y+=t),M+=v();do w.cN&&(M+=\"</span>\"),B+=w.r,w=w.parent;while(w!=a.parent);return o.eE&&(M+=n(t)),y=\"\",a.starts&&b(a.starts,\"\"),o.rE?0:t.length}if(f(t,w))throw new Error('Illegal lexeme \"'+t+'\" for mode \"'+(w.cN||\"<unnamed>\")+'\"');return y+=t,t.length||1}var x=N(e);if(!x)throw new Error('Unknown language: \"'+e+'\"');u(x);for(var w=o||x,L={},M=\"\",k=w;k!=x;k=k.parent)k.cN&&(M=p(k.cN,\"\",!0)+M);var y=\"\",B=0;try{for(var C,j,I=0;;){if(w.t.lastIndex=I,C=w.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}m(t.substr(I));for(var k=w;k.parent;k=k.parent)k.cN&&(M+=\"</span>\");return{r:B,value:M,language:e,top:w}}catch(A){if(-1!=A.message.indexOf(\"Illegal\"))return{r:0,value:n(t)};throw A}}function l(e,t){t=t||E.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(N(n)){var t=s(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function f(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\\t)+)/gm,function(e,n){return n.replace(/\\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\\n/g,\"<br>\")),e}function g(e,n,t){var r=n?x[n]:t,a=[e.trim()];return e.match(/(\\s|^)hljs(\\s|$)/)||a.push(\"hljs\"),r&&a.push(r),a.join(\" \").trim()}function p(e){var n=a(e);if(!/no(-?)highlight/.test(n)){var t;E.useBR?(t=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\"),t.innerHTML=e.innerHTML.replace(/\\n/g,\"\").replace(/<br[ \\/]*>/g,\"\\n\")):t=e;var r=t.textContent,o=n?s(n,r,!0):l(r),u=i(t);if(u.length){var p=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\");p.innerHTML=o.value,o.value=c(u,i(p),r)}o.value=f(o.value),e.innerHTML=o.value,e.className=g(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function h(){if(!h.called){h.called=!0;var e=document.querySelectorAll(\"pre code\");Array.prototype.forEach.call(e,p)}}function v(){addEventListener(\"DOMContentLoaded\",h,!1),addEventListener(\"load\",h,!1)}function b(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){x[e]=n})}function m(){return Object.keys(R)}function N(e){return R[e]||R[x[e]]}var E={classPrefix:\"hljs-\",tabReplace:null,useBR:!1,languages:void 0},R={},x={};return e.highlight=s,e.highlightAuto=l,e.fixMarkup=f,e.highlightBlock=p,e.configure=d,e.initHighlighting=h,e.initHighlightingOnLoad=v,e.registerLanguage=b,e.listLanguages=m,e.getLanguage=N,e.inherit=o,e.IR=\"[a-zA-Z][a-zA-Z0-9_]*\",e.UIR=\"[a-zA-Z_][a-zA-Z0-9_]*\",e.NR=\"\\\\b\\\\d+(\\\\.\\\\d+)?\",e.CNR=\"(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)\",e.BNR=\"\\\\b(0b[01]+)\",e.RSR=\"!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~\",e.BE={b:\"\\\\\\\\[\\\\s\\\\S]\",r:0},e.ASM={cN:\"string\",b:\"'\",e:\"'\",i:\"\\\\n\",c:[e.BE]},e.QSM={cN:\"string\",b:'\"',e:'\"',i:\"\\\\n\",c:[e.BE]},e.PWM={b:/\\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\\b/},e.CLCM={cN:\"comment\",b:\"//\",e:\"$\",c:[e.PWM]},e.CBCM={cN:\"comment\",b:\"/\\\\*\",e:\"\\\\*/\",c:[e.PWM]},e.HCM={cN:\"comment\",b:\"#\",e:\"$\",c:[e.PWM]},e.NM={cN:\"number\",b:e.NR,r:0},e.CNM={cN:\"number\",b:e.CNR,r:0},e.BNM={cN:\"number\",b:e.BNR,r:0},e.CSSNM={cN:\"number\",b:e.NR+\"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?\",r:0},e.RM={cN:\"regexp\",b:/\\//,e:/\\/[gimuy]*/,i:/\\n/,c:[e.BE,{b:/\\[/,e:/\\]/,r:0,c:[e.BE]}]},e.TM={cN:\"title\",b:e.IR,r:0},e.UTM={cN:\"title\",b:e.UIR,r:0},e});hljs.registerLanguage(\"xml\",function(){var t=\"[A-Za-z0-9\\\\._:-]+\",e={b:/<\\?(php)?(?!\\w)/,e:/\\?>/,sL:\"php\",subLanguageMode:\"continuous\"},c={eW:!0,i:/</,r:0,c:[e,{cN:\"attribute\",b:t,r:0},{b:\"=\",r:0,c:[{cN:\"value\",c:[e],v:[{b:/\"/,e:/\"/},{b:/'/,e:/'/},{b:/[^\\s\\/>]+/}]}]}]};return{aliases:[\"html\",\"xhtml\",\"rss\",\"atom\",\"xsl\",\"plist\"],cI:!0,c:[{cN:\"doctype\",b:\"<!DOCTYPE\",e:\">\",r:10,c:[{b:\"\\\\[\",e:\"\\\\]\"}]},{cN:\"comment\",b:\"<!--\",e:\"-->\",r:10},{cN:\"cdata\",b:\"<\\\\!\\\\[CDATA\\\\[\",e:\"\\\\]\\\\]>\",r:10},{cN:\"tag\",b:\"<style(?=\\\\s|>|$)\",e:\">\",k:{title:\"style\"},c:[c],starts:{e:\"</style>\",rE:!0,sL:\"css\"}},{cN:\"tag\",b:\"<script(?=\\\\s|>|$)\",e:\">\",k:{title:\"script\"},c:[c],starts:{e:\"</script>\",rE:!0,sL:\"javascript\"}},e,{cN:\"pi\",b:/<\\?\\w+/,e:/\\?>/,r:10},{cN:\"tag\",b:\"</?\",e:\"/?>\",c:[{cN:\"title\",b:/[^ \\/><\\n\\t]+/,r:0},c]}]}});hljs.registerLanguage(\"javascript\",function(r){return{aliases:[\"js\"],k:{keyword:\"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class\",literal:\"true false null undefined NaN Infinity\",built_in:\"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document\"},c:[{cN:\"pi\",r:10,v:[{b:/^\\s*('|\")use strict('|\")/},{b:/^\\s*('|\")use asm('|\")/}]},r.ASM,r.QSM,r.CLCM,r.CBCM,r.CNM,{b:\"(\"+r.RSR+\"|\\\\b(case|return|throw)\\\\b)\\\\s*\",k:\"return throw case\",c:[r.CLCM,r.CBCM,r.RM,{b:/</,e:/>;/,r:0,sL:\"xml\"}],r:0},{cN:\"function\",bK:\"function\",e:/\\{/,eE:!0,c:[r.inherit(r.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:\"params\",b:/\\(/,e:/\\)/,c:[r.CLCM,r.CBCM],i:/[\"'\\(]/}],i:/\\[|%/},{b:/\\$[(.]/},{b:\"\\\\.\"+r.IR,r:0}]}});\n\nhljs.initHighlightingOnLoad();\n"
  },
  {
    "path": "docs/demos/js/loader.js",
    "content": "var isOnline = window.location.hostname.indexOf('github.io') !== -1;\nvar baseURL = isOnline ? '//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/' : '../../../';\nvar styleLoadingContainer = document.querySelector('.loading-head');\nvar scriptLoadingContainer = document.querySelector('.loading-body');\n\nfunction loadTag(tagToInsert, container, comment, tagForDocumentation) {\n    'use strict';\n\n    document.write(tagToInsert);\n\n    var html = '';\n    if (container.innerHTML.trim().length > 0) {\n        html = '\\n' + container.innerHTML.trim() + '\\n';\n    }\n\n    if (comment !== undefined) {\n        html += '\\n&lt;!-- ' + comment + ' -->';\n    }\n    html += tagForDocumentation.replace(/</g, '&lt;');\n\n    container.innerHTML = html;\n}\n\nfunction loadStyle(stylePath, comment) {\n    'use strict';\n\n    loadTag(\n        '<link rel=\"stylesheet\" href=\"' + baseURL + stylePath + '\"/>',\n        styleLoadingContainer,\n        comment,\n'\\n<link rel=\"stylesheet\" href=\"trumbowyg/' + stylePath + '\">\\n\\n'\n    );\n}\n\nfunction loadScript(scriptPath, comment) {\n    'use strict';\n\n    if (!isOnline) {\n        scriptPath = scriptPath.replace('.min', '');\n    }\n\n    loadTag(\n        '<script src=\"' + baseURL + scriptPath + '\"></script>',\n        scriptLoadingContainer,\n        comment,\n'\\n<script src=\"trumbowyg/' + scriptPath + '\"></script>\\n\\n'\n    );\n}\n\n(function($) {\n    'use strict';\n\n    $('a').click(function() {\n        window.top.location = $(this).attr('href');\n        return false;\n    });\n})(jQuery);\n"
  },
  {
    "path": "docs/demos/js/runExampleCode.js",
    "content": "(function ($) {\n    'use strict';\n\n    $('.js-code-to-eval').each(function () {\n        eval($(this).text()); // jshint ignore:line\n        $(this).text(\n            $(this).text()\n                .replace(/'Client-ID\\s[a-z0-9]+'/, '\\'Client-ID xxxxxxxxxxxx\\'')\n                .replace(/apiKey:\\s+'.*'/, 'apiKey: \\'xxxxxxxxxxxx\\'')\n        );\n    });\n})(jQuery);\n"
  },
  {
    "path": "docs/demos/plugins/allowtagsfrompaste.html",
    "content": "﻿<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Allow tags from paste plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Allow tags from paste plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allows you to filter tags allowed when an user paste some code into the editor.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-allowtagsfrompaste\" class=\"button button-demo\">Read allow tags from paste plugin documentation</a>\n\n            <div id=\"editor\">\n                <h4>Try to paste something!</h4>\n                <p>\n                    Only `h2`, `p` `strong` and `br` tags are allowed!\n                    All other tags will be removed.\n                </p>\n            </div>\n\n            <div class=\"sample-data\">\n                <h4 style=\"padding: 0;\">Some text to copy to test</h4>\n                <p>\n                    This table will be not pasted:\n                </p>\n                <table style=\"margin: 0;\">\n                    <tr>\n                        <td>h4 must be kept</td>\n                        <td>but not</td>\n                        <td>this table</td>\n                    </tr>\n                    <tr>\n                        <td>Second line</td>\n                        <td>will be</td>\n                        <td>striped out too</td>\n                    </tr>\n                </table>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        'viewHTML',\n        'h4'\n    ],\n    plugins: {\n        allowTagsFromPaste: {\n            allowedTags: ['h4', 'p', 'br']\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/allowtagsfrompaste/trumbowyg.allowtagsfrompaste.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/base64.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Base64 plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Base64 plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                You can insert an image in <em>base64</em> in src attribute of <code>img</code> tag.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-base64\" class=\"button button-demo\">Read base64 plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Insert your base64 image!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: ['base64']\n});\n                </code></pre>\n        </div>\n\n\n        <div class=\"feature\">\n            <h3>base64 in dropdown</h3>\n\n            <div id=\"editor-dropdown\">\n                <h2>Insert your base64 image through image dropdown!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-dropdown')\n.trumbowyg({\n    btnsDef: {\n        // Create a new dropdown\n        image: {\n            dropdown: ['insertImage', 'base64'],\n            ico: 'insertImage'\n        }\n    },\n    // Redefine the button pane\n    btns: [\n        ['viewHTML'],\n        ['formatting'],\n        ['strong', 'em', 'del'],\n        ['superscript', 'subscript'],\n        ['link'],\n        ['image'], // Our fresh created dropdown\n        ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n        ['unorderedList', 'orderedList'],\n        ['horizontalRule'],\n        ['removeformat'],\n        ['fullscreen']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/base64/trumbowyg.base64.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/cleanpaste.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Clean paste plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Clean paste plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                Clean paste plugin handle paste events, clean the HTML code before insert content into the editor.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-cleanpaste\" class=\"button button-demo\">Read clean paste plugin documentation</a>\n\n            <div id=\"editor\">\n                <h4>Try to paste something from Microsoft Word or something!</h4>\n                <p>\n                    Then, check the markup. Should be cleaner than original.\n                </p>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor').trumbowyg();\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/cleanpaste/trumbowyg.cleanpaste.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/colors.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Colors plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Colors plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allow you to add a foreground and/or background color picker.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-colors\" class=\"button button-demo\">Read colors plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>You can color me!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['foreColor', 'backColor']\n    ],\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Custom color list</h3>\n            <p>\n                You can customize the color list used by both dropdowns.\n            </p>\n\n            <div id=\"editor-custom-color-list\">\n                <h2>You can color me with custom color list!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-custom-color-list').trumbowyg({\n    btns: [\n        ['foreColor', 'backColor']\n    ],\n    plugins: {\n        colors: {\n            colorList: [\n                '000', '111', '222', 'ffea00'\n            ]\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Custom color list for each button</h3>\n            <p>\n                You can customize the color list used by each dropdown independently.\n            </p>\n\n            <div id=\"editor-custom-color-list-for-each\">\n                <h2>You can color me with custom color list!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-custom-color-list-for-each').trumbowyg({\n    btns: [\n        ['foreColor', 'backColor']\n    ],\n    plugins: {\n        colors: {\n            foreColorList: [\n                'ff0000', '00ff00', '0000ff'\n            ],\n            backColorList: [\n                '000', '333', '555'\n            ]\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Display colors as a list like other dropdowns</h3>\n            <p>\n                The <code>displayAsList</code> option allows you to change the layout of the color dropdown from squares to list.\n            </p>\n\n            <div id=\"editor-display-as-list\">\n                <h2>Check the dropdown is not like other examples!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n            <pre><code class=\"js-code-to-eval javascript\">\n// Human labels for each hex color\nvar colorLabels = {\n    '#000': 'Black',\n    '#555': 'Dark grey',\n    '#ff0000': 'Red',\n    '#00ff00': 'Green',\n    '#0000ff': 'Blue',\n    '#ff1493': 'Pink',\n};\n\n$.each(colorLabels, function(colorHexCode, colorLabel) {\n    $.trumbowyg.langs.en[colorHexCode] = colorLabel;\n})\n\n$('#editor-display-as-list').trumbowyg({\n    btns: [\n        ['foreColor', 'backColor']\n    ],\n    plugins: {\n        colors: {\n            foreColorList: [\n                'ff0000', '00ff00', '0000ff', 'ff1493'\n            ],\n            backColorList: [\n                '000', '555', 'ff0000'\n            ],\n            displayAsList: true\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Loading</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadStyle('dist/plugins/colors/ui/trumbowyg.colors.min.css', 'Import color plugin specific stylesheet');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/colors/trumbowyg.colors.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/emoji.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Emoji plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Emoji plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allow you to add an emoji picker in Trumbowyg.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-emoji\" class=\"button button-demo\">Read emoji plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Select an emoji !</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: ['emoji']\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadStyle('dist/plugins/emoji/ui/trumbowyg.emoji.min.css', 'Import emoji plugin specific stylesheet');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/emoji/trumbowyg.emoji.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/fontfamily.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Font family plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Font family plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                User can pick some fonts in Trumbowyg.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-fontfamily\" class=\"button button-demo\">Read font family plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Change the font!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['fontfamily']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Custom font list</h3>\n\n            <div id=\"editor-custom-font-list\">\n                <h2>Change the font!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-custom-font-list')\n.trumbowyg({\n    btns: [\n        ['fontfamily']\n    ],\n    plugins: {\n        fontfamily: {\n            fontList: [\n                {name: 'Arial', family: 'Arial, Helvetica, sans-serif'},\n                {name: 'Comic Sans', family: '\\'Comic Sans MS\\', Textile, cursive, sans-serif'},\n                {name: 'Open Sans', family: '\\'Open Sans\\', sans-serif'}\n            ]\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/fontfamily/trumbowyg.fontfamily.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/fontsize.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Font size plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Font size plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                User can change font size in Trumbowyg.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-fontsize\" class=\"button button-demo\">Read font size plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Change the size!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['fontsize']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Custom font sizes</h3>\n\n            <div id=\"editor-custom-font-sizes\">\n                <h2>Change the font!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-custom-font-sizes')\n.trumbowyg({\n    btns: [\n        ['fontsize']\n    ],\n    plugins: {\n        fontsize: {\n            sizeList: [\n                '14px',\n                '18px',\n                '22px'\n            ],\n            allowCustomSize: false\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/fontsize/trumbowyg.fontsize.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/giphy.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Giphy plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Giphy plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                User can insert some GIFs from Giphy in Trumbowyg.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-giphy\" class=\"button button-demo\">Read Giphy plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Insert some GIFs</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['giphy']\n    ],\n    plugins: {\n        giphy: {\n            apiKey: 'dNhCbN6hrhpBMxXhIswM34wIR2UBpCns'\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadStyle('dist/plugins/giphy/ui/trumbowyg.giphy.min.css', 'Import Giphy plugin specific stylesheet');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/giphy/trumbowyg.giphy.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/highlight.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Highlight plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.13.0/themes/prism-tomorrow.css\">\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Highlight plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allow you to add an code highlighter in Trumbowyg.\n            </p>\n            <a href=\"../../documentation/plugins/#plugin-highlight\" class=\"button button-demo\">Read highlight plugin documentation</a>\n\n            <div id=\"editor\">\n                <p>Just press plugin button and paste code there!</p>\n                <p><br></p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['highlight']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n&lt;!-- Import prismjs stylesheet -->\n&lt;link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.13.0/themes/prism.css\">\n&lt;link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/plugins/line-highlight/prism-line-highlight.min.css\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n&lt;!-- Import prismjs -->\n&lt;script src=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js\">&lt;/script>\n&lt;!-- Import prismjs line highlight plugin -->\n&lt;script src=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/plugins/line-highlight/prism-line-highlight.min.js\">&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n<!-- Import highlight.js -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/plugins/line-highlight/prism-line-highlight.min.js\"></script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadStyle('dist/plugins/highlight/ui/trumbowyg.highlight.min.css', 'Import highlight plugin specific stylesheet');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/highlight/trumbowyg.highlight.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/history.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>History plugin | Trumbowyg by Alex-D</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">History plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin gives you an improved undo and redo functionality based on editor changes.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-history\" class=\"button button-demo\">Read history plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Lorem ipsum dolor sit amet</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [['historyUndo','historyRedo']]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/history/trumbowyg.history.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/indent.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Indent plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Indent plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allow you to indent or outdent into your page creating vibrante documents.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-indent\" class=\"button button-demo\">Read insert indent plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>You can make me come alive!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: ['indent', 'outdent']\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/indent/trumbowyg.indent.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/insertaudio.html",
    "content": "﻿<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Insert audio plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Insert audio plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allow you to insert audio files into your page creating vibrante documents.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-insertaudio\" class=\"button button-demo\">Read insert audio plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>You can make me come alive! Insert Audio</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: ['insertAudio']\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/insertaudio/trumbowyg.insertaudio.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/lineheight.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Line height plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Line height plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                User can change the line-height in Trumbowyg.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-lineheight\" class=\"button button-demo\">Read font size plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Change the size!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['lineheight']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Custom font sizes</h3>\n\n            <div id=\"editor-custom-font-sizes\">\n                <h2>Change the font!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-custom-font-sizes')\n.trumbowyg({\n    btns: [\n        ['lineheight']\n    ],\n    plugins: {\n        lineheight: {\n            sizeList: [\n                '14px',\n                '18px',\n                '22px'\n            ]\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/lineheight/trumbowyg.lineheight.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/mathml.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>MathML plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">MathML plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allows user to use MathML.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-mathml\" class=\"button button-demo\">Read MathML plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>You can try to insert some formulas</h2>\n            </div>\n\n            <div class=\"sample-data\">\n                <h4>Some formulas to copy/paste to try it</h4>\n                <p>\n                    <input type=\"text\" readonly value=\"\\left( \\sum_{k=1}^n a_k b_k \\right)^{\\!\\!2} \\leq  \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)\" onclick=\"this.select();\">\n                    <input type=\"text\" readonly value=\"P(E) = {n \\choose k} p^k (1-p)^{ n-k}\" onclick=\"this.select();\">\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n// MathJax inline configuration\nMathJax.Hub.Config({\n    tex2jax: {\n        inlineMath: [\n            ['$', '$'],\n            ['\\\\(', '\\\\)']\n        ]\n    }\n});\n\n// Trumbowyg initialization with MathML button\n$('#editor')\n.trumbowyg({\n    btns: [\n        'viewHTML',\n        'mathml'\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n\n&lt;!-- Import MathJax -->\n&lt;script src=\"//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML\">&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n<!-- Import MathJax -->\n<script src=\"//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML\"></script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadStyle('dist/plugins/mathml/ui/trumbowyg.mathml.min.css', 'Import MathML plugin specific stylesheet');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/mathml/trumbowyg.mathml.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/mention.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Mention plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Mention plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allows to mention an user from a source list.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-mention\" class=\"button button-demo\">Read Mention plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Check this out, there are lot of guys in the mention dropdown!</h2>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['mention']\n    ],\n    plugins: {\n        mention: {\n            source: [\n                {login: 'jdoe', name: 'John Doe (The Jean-Claude Van Damme\\'s intern)'},\n                {login: 'lgaga', name: 'Lady Gaga'},\n                {login: 'jcvd', name: 'Jean-Claude Van Damme'},\n                {login: 'nminaj', name: 'Nicki Minaj'},\n                {login: 'mshinoda', name: 'Mike Shinoda'},\n                {login: 'epiaf', name: 'Edith Piaf'},\n                {login: 'kwest', name: 'Kanye West'},\n                {login: 'jbalasko', name: 'Josiane Balasko'},\n                {login: 'jcesar', name: 'Julius Cesarius'},\n                {login: 'mlisa', name: 'Mona Lisa'},\n                {login: 'mjackson', name: 'Mickael Jackson'},\n                {login: 'fflament', name: 'Flavie Flament'},\n            ],\n            formatDropdownItem: function (item) {\n                return item.name + ' (@' + item.login + ')';\n            }\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n<!-- Import MathJax -->\n<script src=\"//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML\"></script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadStyle('dist/plugins/mention/ui/trumbowyg.mention.min.css', 'Import Mention plugin specific stylesheet');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/mention/trumbowyg.mention.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/noembed.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Noembed plugin | Trumbowyg</title>\n    <script src=\"../js/loader.js\"></script>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Noembed plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                You can insert embedded content via an embed proxy.\n                Plugin uses <a href=\"//noembed.com\">noembed</a> by default.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-noembed\" class=\"button button-demo\">Read noembed plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Embed Content!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <iframe width=\"100%\" height=\"400\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?visual=true&amp;url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F342548257&amp;show_artwork=true\"></iframe>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: ['noembed']\n});\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\">\n            <h3>Put in dropdown</h3>\n\n            <div id=\"editor-dropdown\">\n                <h2>Embed content through image dropdown!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-dropdown')\n.trumbowyg({\n    btnsDef: {\n        // Create a new dropdown\n        image: {\n            dropdown: ['insertImage', 'noembed'],\n            ico: 'insertImage'\n        }\n    },\n    // Redefine the button pane\n    btns: [\n        ['viewHTML'],\n        ['formatting'],\n        ['strong', 'em', 'del'],\n        ['superscript', 'subscript'],\n        ['link'],\n        ['image'], // Our fresh created dropdown\n        ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n        ['unorderedList', 'orderedList'],\n        ['horizontalRule'],\n        ['removeformat'],\n        ['fullscreen']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/noembed/trumbowyg.noembed.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/pasteembed.html",
    "content": "﻿<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Paste embed plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Paste embed plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allow you to insert iframes into your editor just by pasting an URL.<br/>\n                It uses <a href=\"https://noembed.com\">noembed.com</a> API to support X, YouTube, SoundCloud and more. Find all supported websites at <a href=\"https://noembed.com\">noembed.com</a>.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-pasteembed\" class=\"button button-demo\">Read paste embed plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Try to paste some urls!</h2>\n                <iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" allow=\"autoplay\" src=\"https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/376360739&amp;color=%23ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;show_teaser=true\"></iframe>\n                <p>Try pasting this one: https://www.youtube.com/watch?v=dQw4w9WgXcQ</p>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor').trumbowyg();\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/pasteembed/trumbowyg.pasteembed.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/pasteimage.html",
    "content": "﻿<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Paste image plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Paste image plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                Paste image plugin handle paste events, check if you have image files in your clipboard, then paste them\n                into the editor as base64. It do nothing on text or HTML paste.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-pasteimage\" class=\"button button-demo\">Read paste image plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Try to paste some image!</h2>\n                <p>For example, you can right-click > Copy Image on the Trumbowyg logo, then paste it here.</p>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor').trumbowyg();\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/pasteimage/trumbowyg.pasteimage.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/preformatted.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Preformatted plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Preformatted plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                Wraps/unwraps your code with <code>&lt;pre>&lt;code></code> tags.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-preformatted\" class=\"button button-demo\">Read preformatted plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>\n                    Some code to wrap\n                </h2>\n                <p>\n$('#editor')\n.trumbowyg({\n    btns: [\n        'viewHTML',\n        'preformatted'\n    ]\n});\n                </p>\n                <p>\n                    Then check the HTML, code is now wrapped into <code>pre</code> + <code>code</code> tags!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        'viewHTML',\n        'preformatted'\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/preformatted/trumbowyg.preformatted.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/resizimg.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Resizimg plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Resizimg plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                Images can be resized by click over the image and dragging their bottom-right corner (the white ones).\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-resizimg\" class=\"button button-demo\">Read resizimg plugin documentation</a>\n\n            <div id=\"editor\" style=\"margin: 1rem\">\n                <h2>Resize that image!</h2>\n                <img src=\"//rawcdn.githack.com/Alex-D/Trumbowyg/develop/banner.jpg\" style=\"height: 200px\">\n            </div>\n\n            <h4>The code</h4>\n            <p>\n                Nothing to do unless you want to change the default values of options, in which case you could:\n            </p>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor').trumbowyg({\n    plugins: {\n        resizimg: {\n            minSize: 64,\n            step: 16,\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <p>Note the additional requirement: the <a href=\"https://github.com/RickStrahl/jquery-resizable\" target=\"_blank\">jquery-resizable</a> plugin must be loaded for Resizimg to work.</p>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.4.0.min.js\">&lt;\\/script>')&lt;/script>\n\n&lt;!-- Import dependency for Resizimg (tested with version 0.35). For a production setup, follow install instructions here: https://github.com/RickStrahl/jquery-resizable -->\n&lt;script src=\"//rawcdn.githack.com/RickStrahl/jquery-resizable/0.35/dist/jquery-resizable.min.js\">&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n<!-- Import dependency for Resizimg -->\n<script src=\"//rawcdn.githack.com/RickStrahl/jquery-resizable/0.35/dist/jquery-resizable.min.js\"></script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.css');\n    loadScript('dist/trumbowyg.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/resizimg/trumbowyg.resizimg.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/ruby.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Ruby plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Ruby plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                You can insert Ruby markup.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-ruby\" class=\"button button-demo\">Read ruby plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Insert your ruby markup!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: ['ruby']\n});\n                </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/ruby/trumbowyg.ruby.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/specialchars.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Special chars plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Special chars plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allow you to add a picker for special character in Trumbowyg.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-specialchars\" class=\"button button-demo\">Read special chars plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Select a character!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['specialChars']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Custom char list</h3>\n\n            <div id=\"editor-custom-list\">\n                <h2>Select a character!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-custom-list')\n.trumbowyg({\n    btns: [\n        ['specialChars']\n    ],\n    plugins: {\n        specialchars: {\n            symbolList: [\n                '00A2', '00A5', '00A4', '2030',  null,\n                '00A9', '00AE',  '2122',  null,\n                '2023', '25B6', '2B29', '25C6', null,\n                '2211', '2243', '2264', '2265'\n            ]\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadStyle('dist/plugins/specialchars/ui/trumbowyg.specialchars.min.css', 'Import special chars plugin specific stylesheet');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/specialchars/trumbowyg.specialchars.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/speechrecognition.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Speech recognition plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Speech recognition plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugins allow you to enter text via speech recognition in Trumbowyg. Suddenly it does not work with Firefox which has not implemented the Web Speech API yet.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-speechrecognition\" class=\"button button-demo\">Read speech recognition plugin documentation</a>\n\n            <div id=\"editor\"></div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['speechrecognition']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Language setting</h3>\n\n            <div id=\"editor-settings-lang\"></div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-settings-lang')\n.trumbowyg({\n    btns: [\n        ['speechrecognition']\n    ],\n    plugins: {\n        speechrecognition: {\n            lang: 'de-DE'\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n        loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/speechrecognition/trumbowyg.speechrecognition.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/table.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Table plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Table plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allows you to add and manage a table.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-table\" class=\"button button-demo\">Read table plugin documentation</a>\n\n            <div id=\"editor\">\n                <h4>Add a table to the editor</h4>\n                <p>\n                    Below is an example of a simple table with a header row.\n                </p>\n                <table>\n                    <thead>\n                    <tr>\n                        <th scope=\"col\">Project & Pitch</th>\n                        <th scope=\"col\">Status</th>\n                        <th scope=\"col\">Technologies</th>\n                        <th scope=\"col\">Stars</th>\n                        <th scope=\"col\">Downloads</th>\n                        <th scope=\"col\">URL</th>\n                    </tr>\n                    </thead>\n                    <tbody>\n                    <tr>\n                        <td><strong>Trumbowyg</strong> <br> Lightweight WYSIWYG Editor</td>\n                        <td>Active</td>\n                        <td>JavaScript</td>\n                        <td>~4&nbsp;000&nbsp;★</td>\n                        <td>70&nbsp;000&nbsp;/&nbsp;month</td>\n                        <td>\n                            <a href=\"https://alex-d.github.io/Trumbowyg/\">Landing</a> <br>\n                            <a href=\"https://github.com/Alex-D/Trumbowyg/\">GitHub</a>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td><strong>Monitoror</strong> <br> Unified monitoring wallboard</td>\n                        <td>Maintenance</td>\n                        <td>Go <br> Vue</td>\n                        <td>~4&nbsp;000&nbsp;★</td>\n                        <td>100&nbsp;000&nbsp;+</td>\n                        <td>\n                            <a href=\"https://monitoror.com\">Landing</a> <br>\n                            <a href=\"https://github.com/monitoror/monitoror/\">GitHub</a>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td><strong>Cookies EU Banner</strong> <br> 1kb vanilla JS for cookie banner</td>\n                        <td>Maintenance</td>\n                        <td>JavaScript</td>\n                        <td>~420&nbsp;★</td>\n                        <td>4&nbsp;000&nbsp;/&nbsp;month</td>\n                        <td>\n                            <a href=\"https://alex-d.github.io/Cookies-EU-banner/\">Landing</a> <br>\n                            <a href=\"https://github.com/Alex-D/Cookies-EU-banner\">GitHub</a>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td><strong>Colllect</strong> <br> Bookmark Manager for Creatives</td>\n                        <td>Paused</td>\n                        <td>Symfony <br> Vue</td>\n                        <td>~340&nbsp;★</td>\n                        <td></td>\n                        <td>\n                            <a href=\"https://colllect.io\">Landing</a> <br>\n                            <a href=\"https://github.com/Colllect/Colllect\">GitHub</a>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td><strong>Check Disk Space</strong> <br> Multi-platform disk space checker for Node.js</td>\n                        <td>Maintenance</td>\n                        <td>TypeScript</td>\n                        <td>~78&nbsp;★</td>\n                        <td>2&nbsp;000&nbsp;000&nbsp;/&nbsp;month</td>\n                        <td>\n                            <a href=\"https://github.com/Alex-D/check-disk-space\">GitHub</a>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td><strong>Column View</strong> <br> Multi-columns page viewer</td>\n                        <td>Maintenance</td>\n                        <td>TypeScript <br> Snabbdom</td>\n                        <td>~7&nbsp;★</td>\n                        <td></td>\n                        <td>\n                            <a href=\"https://column-view.com\">Landing</a> <br>\n                            <a href=\"https://github.com/Alex-D/Column-View/\">GitHub</a>\n                        </td>\n                    </tr>\n                    </tbody>\n                </table>\n\n                <hr>\n                <h4>Tables with merged cells</h4>\n                <p>\n                    Example of a pricing table.\n                </p>\n                <table>\n                    <thead>\n                    <tr>\n                        <th scope=\"col\">Feature</th>\n                        <th scope=\"col\">Free</th>\n                        <th scope=\"col\">Premium</th>\n                        <th scope=\"col\">Business</th>\n                        <th scope=\"col\">Enterprise</th>\n                    </tr>\n                    </thead>\n                    <tbody>\n                    <tr>\n                        <td>Price</td>\n                        <td>Free</td>\n                        <td>5,99€ / user</td>\n                        <td>12,99€ / user</td>\n                        <td>22,99€ / user</td>\n                    </tr>\n                    <tr>\n                        <td>Users</td>\n                        <td>1</td>\n                        <td rowspan=\"3\" colspan=\"2\" style=\"text-align: center;\">Unlimited</td>\n                        <td>20 users minimum</td>\n                    </tr>\n                    <tr>\n                        <td>Items</td>\n                        <td>100</td>\n                        <td>Unlimited</td>\n                    </tr>\n                    <tr>\n                        <td>Bandwidth</td>\n                        <td>5&nbsp;Mbps</td>\n                        <td>On your charge</td>\n                    </tr>\n                    </tbody>\n                </table>\n            </div>\n\n            <div id=\"editor2\">\n                <p>\n                    Another tab with different merged cells:\n                </p>\n                <table>\n                    <tbody>\n                    <tr>\n                        <td>Those plugins allow you to merge cells</td>\n                        <td>And also unmerge</td>\n                        <td colspan=\"2\">Two cells merged</td>\n                    </tr>\n                    <tr>\n                        <td>You can see some examples on this page</td>\n                        <td colspan=\"2\">Two horizontally merged too</td>\n                        <td>Simple cell</td>\n                    </tr>\n                    <tr>\n                        <td>Upload image</td>\n                        <td>Pick, upload, and inserts an image</td>\n                        <td>Next is empty</td>\n                        <td></td>\n                    </tr>\n                    </tbody>\n                </table>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor, #editor2')\n.trumbowyg({\n    btns: [['table'], ['tableCellBackgroundColor', 'tableBorderColor']]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadStyle('dist/plugins/table/ui/trumbowyg.table.min.css', 'Import table plugin specific stylesheet');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/table/trumbowyg.table.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/template.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Template plugin | Trumbowyg by Alex-D</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Template plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                This plugin allows you to add a template-dropdown.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-template\" class=\"button button-demo\">Read template plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Lorem ipsum dolor sit amet</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h3>The code</h3>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: ['template'],\n    plugins: {\n        templates: [\n            {\n                name: 'Template 1',\n                html: '&lt;p&gt;I am a template!&lt;/p&gt;'\n            },\n            {\n                name: 'Template 2',\n                html: '&lt;p&gt;I am a different template!&lt;/p&gt;'\n            }\n        ]\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/template/trumbowyg.template.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/tenor.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Tenor plugin | Trumbowyg</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Tenor plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                User can insert some GIFs from Tenor in Trumbowyg.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-tenor\" class=\"button button-demo\">Read Tenor plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Insert some GIFs</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: [\n        ['tenor']\n    ],\n    plugins: {\n        tenor: {\n            apiKey: 'AIzaSyDSkXpGdEiI0OrQO9xZKbvTAvekZhmXW3c'\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadStyle('dist/plugins/tenor/ui/trumbowyg.tenor.min.css', 'Import Tenor plugin specific stylesheet');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/tenor/trumbowyg.tenor.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/demos/plugins/upload.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Upload plugin | Trumbowyg by Alex-D</title>\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<div class=\"main main-demo-inner\">\n    <section class=\"wrapper section\">\n        <h2 class=\"section-title\">Upload plugin</h2>\n\n        <div class=\"feature\">\n            <h3>Basic usage</h3>\n            <p>\n                You can insert an image by upload.\n            </p>\n\n            <a href=\"../../documentation/plugins/#plugin-upload\" class=\"button button-demo\">Read upload plugin documentation</a>\n\n            <div id=\"editor\">\n                <h2>Insert your uploaded image!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h2>The code</h2>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor')\n.trumbowyg({\n    btns: ['upload'],\n    plugins: {\n        // Add imgur parameters to upload plugin for demo purposes\n        upload: {\n            serverPath: 'https://api.imgur.com/3/image',\n            fileFieldName: 'image',\n            headers: {\n                'Authorization': 'Client-ID 9e57cb1c4791cea'\n            },\n            urlPropertyName: 'data.link'\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Upload in dropdown</h3>\n\n            <div id=\"editor-dropdown\">\n                <h2>Insert your uploaded image through image dropdown!</h2>\n                <p>\n                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n                    optio nam reiciendis eius beatae quibusdam!\n                </p>\n                <p>\n                    The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n                    alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n                    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n                    anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n                </p>\n            </div>\n\n            <h4>The code</h4>\n            <pre><code class=\"js-code-to-eval javascript\">\n$('#editor-dropdown')\n.trumbowyg({\n    btnsDef: {\n        // Create a new dropdown\n        image: {\n            dropdown: ['insertImage', 'upload'],\n            ico: 'insertImage'\n        }\n    },\n    // Redefine the button pane\n    btns: [\n        ['viewHTML'],\n        ['formatting'],\n        ['strong', 'em', 'del'],\n        ['superscript', 'subscript'],\n        ['link'],\n        ['image'], // Our fresh created dropdown\n        ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n        ['unorderedList', 'orderedList'],\n        ['horizontalRule'],\n        ['removeformat'],\n        ['fullscreen']\n    ],\n    plugins: {\n        // Add imgur parameters to upload plugin for demo purposes\n        upload: {\n            serverPath: 'https://api.imgur.com/3/image',\n            fileFieldName: 'image',\n            headers: {\n                'Authorization': 'Client-ID 9e57cb1c4791cea'\n            },\n            urlPropertyName: 'data.link'\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3>Setup</h3>\n\n            <h4>In head tag</h4>\n            <pre><code class=\"html loading-head\">\n            </code></pre>\n            <h4>At the end of body</h4>\n            <pre><code class=\"html loading-body\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n        </div>\n    </section>\n</div>\n\n\n<!-- Import jQuery -->\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<!-- DO NOT COPY THESE LINES IN YOUR PROJECT, THEY ARE THERE JUST FOR THE EXAMPLE PAGE PURPOSE -->\n<script src=\"../js/loader.js\"></script>\n<script>\n    loadStyle('dist/ui/trumbowyg.min.css');\n    loadScript('dist/trumbowyg.min.js', 'Import Trumbowyg');\n    loadScript('dist/plugins/upload/trumbowyg.upload.min.js', 'Import all plugins you want AFTER importing jQuery and Trumbowyg');\n</script>\n<script src=\"../js/runExampleCode.js\"></script>\n<script src=\"../js/highlight.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/documentation/core/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <title>Core | Trumbowyg: A lightweight WYSIWYG editor | Alex-D / Alexandre Demode</title>\n    <meta name=\"description\" content=\"Trumbowyg is a jQuery plugin for create WYSIWYG editor\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <link rel=\"icon\" type=\"image/png\" href=\"../../favicon.png\">\n\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"overflow: hidden;visibility: hidden;height: 0;width: 0;\">\n    <symbol id=\"trumbowyg-link\" viewBox=\"0 0 72 72\">\n        <path d=\"M30.9 49.1l-6.7 6.7c-.8.8-1.6.9-2.1.9s-1.4-.1-2.1-.9l-5.2-5.2c-1.1-1.1-1.1-3.1 0-4.2l6.1-6.1.2-.2 6.5-6.5c-1.2-.6-2.5-.9-3.8-.9-2.3 0-4.6.9-6.3 2.6L10.8 42c-3.5 3.5-3.5 9.2 0 12.7l5.2 5.2c1.7 1.7 4 2.6 6.3 2.6s4.6-.9 6.3-2.6l6.7-6.7C38 50.5 38.6 46.3 37 43l-6.1 6.1zM38.5 22.7l6.7-6.7c.8-.8 1.6-.9 2.1-.9s1.4.1 2.1.9l5.2 5.2c1.1 1.1 1.1 3.1 0 4.2l-6.1 6.1-.2.2-6.5 6.5c1.2.6 2.5.9 3.8.9 2.3 0 4.6-.9 6.3-2.6l6.7-6.7c3.5-3.5 3.5-9.2 0-12.7l-5.2-5.2c-1.7-1.7-4-2.6-6.3-2.6s-4.6.9-6.3 2.6l-6.7 6.7c-2.7 2.7-3.3 6.9-1.7 10.2l6.1-6.1z\"></path>\n        <path d=\"M44.1 30.7c.2-.2.4-.6.4-.9 0-.3-.1-.6-.4-.9l-2.3-2.3c-.2-.2-.6-.4-.9-.4-.3 0-.6.1-.9.4L25.8 40.8c-.2.2-.4.6-.4.9 0 .3.1.6.4.9l2.3 2.3c.2.2.6.4.9.4.3 0 .6-.1.9-.4l14.2-14.2z\"></path>\n    </symbol>\n</svg>\n<div class=\"sidebar\">\n    <div class=\"sidebar-inner\">\n        <header class=\"header-documentation\">\n            <a href=\"../../\" class=\"documentation-logo-link\">\n                <img src=\"../../img/logo-doc.svg\" alt=\"\" class=\"documentation-logo\">\n            </a>\n            <h1 class=\"documentation-title\">\n                Core\n            </h1>\n            <nav class=\"documentation-menu\">\n                <a href=\"../\">Docs</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"../plugins/\">Plugins</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"./\">Core</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"../../demos/\">Demos</a>\n            </nav>\n        </header>\n\n        <aside class=\"documentation-summary\">\n            <ul>\n                <li>\n                    <a href=\"#core\">Core</a>\n                    <ul>\n                        <li><a href=\"#modal-box\">Modal box</a></li>\n                        <li><a href=\"#range\">Range</a></li>\n                        <li><a href=\"#manage-content\">Manage content</a></li>\n                        <li><a href=\"#empty\">Empty</a></li>\n                        <li><a href=\"#enable-disable-edition\">Enable/disable edition</a></li>\n                        <li><a href=\"#toggle\">Toggle HTML/WYSIWYG</a></li>\n                    </ul>\n                </li>\n            </ul>\n        </aside>\n\n        <div class=\"documentation-sidebar-beer\">\n            <a href=\"../../#donate\">\n                <img src=\"../../img/beer.svg\" alt=\"\" class=\"beer-icon\">\n                <span class=\"beer-label\">\n                    Do you enjoy Trumbowyg? <br>\n                    Buy me some beers :)\n                </span>\n            </a>\n        </div>\n    </div>\n</div>\n\n<main class=\"main\">\n    <section id=\"core\" class=\"wrapper section\">\n        <h2 class=\"section-title\">Core</h2>\n\n        <div class=\"feature\">\n            <h3 id=\"modal-box\">Modal box</h3>\n            <p>\n                When you want create your custom extension for Trumbowyg, you can open and close a modal box with custom\n                inner HTML code, listen events and more.\n            </p>\n\n            <h4>Open and close</h4>\n            <p>\n                For that use the right method: <code>openModal</code> or <code>closeModal</code> like that:\n            </p>\n            <pre><code class=\"javascript\">\n// Open a modal box\nvar $modal = trumbowyg.openModal({\n    title: 'A title for modal box',\n    content: '&lt;p&gt;Content in HTML which you want include in created modal box&lt;/p&gt;'\n});\n\n// Close current modal box\ntrumbowyg.closeModal();\n            </code></pre>\n            <p>\n                An <code>openModal</code> call returns a jQuery object which contains the modal box. You need this\n                object if you want to use listen events (see below).\n            </p>\n            <p class=\"note\">\n                Only one modal box can open at any given moment. So, <code>openModal</code> return false if a modal is\n                currently opened.\n            </p>\n\n            <h4>Events on modal box</h4>\n            <p>\n                Modal boxes in Trumbowy come with two buttons: \"Confirm\" and \"Cancel\". An event is associated to each\n                one:\n            </p>\n            <ul>\n                <li><code>tbwsubmit</code>: triggered when form is submit</li>\n                <li><code>tbwreset</code>: triggered when user cancels operation</li>\n            </ul>\n            <pre><code class=\"javascript\">\n// Open a modal box\nvar $modal = trumbowyg.openModal({\n    title: 'A title for modal box',\n    content: '&lt;p&gt;Content in HTML which you want include in created modal box&lt;/p&gt;'\n});\n\n// Listen clicks on modal box buttons\n$modal.on('tbwconfirm', function(e){\n    // Do what you want\n    trumbowyg.closeModal();\n});\n$modal.on('tbwcancel', function(e){\n    trumbowyg.closeModal();\n});\n            </code></pre>\n\n            <h4>Only build inputs in modal</h4>\n            <p>\n                If you want to only add inputs in the modal box, this function is more simple. Indeed, you do not manage\n                confirm and close buttons, and get all input value on confirm.\n            </p>\n            <pre><code class=\"javascript\">\nvar img = $('img#an-img');\n$modal = trumbowyg.openModalInsert({\n    title: 'A title for modal box',\n    fields: {\n        url: {\n            value: img.attr('src')\n        },\n        alt: {\n            label: 'Alt',\n            name: 'alt',\n            value: img.attr('alt'),\n            type: 'text',\n            attributes: {}\n        },\n\n        // Build your own input by setting type as a function and returning the html\n        referrerpolicy: {\n            label: 'Referrer Policy',\n            name: 'referrerpolicy',\n            type: function(field, fieldId, prefix, lg) {\n                var html += '&lt;div class=\"' + prefix + 'input-row\"&gt;' +\n                    '&lt;div class=\"' + prefix + 'input-infos\"&gt;' +\n                        '&lt;label for=\"' + fieldId + '\"&gt;' +\n                            '&lt;span&gt;' + (lg[field.label] ? lg[field.label] : field.label) + '&lt;/span&gt;' +\n                        '&lt;/label&gt;' +\n                    '&lt;/div&gt;' +\n                    '&lt;div class=\"' + prefix + 'input-html\"&gt;' +\n                        '&lt;select id=\"' + fieldId + '\" name=\"' + field.name + '\"&gt;' +\n                            '&lt;option' + (field.value === 'no-referrer' ? ' selected=\"selected\"' : '') + '&gt;no-referrer&lt;/option&gt;' +\n                            '&lt;option' + (field.value === 'no-referrer-when-downgrade' ? ' selected=\"selected\"' : '') + '&gt;no-referrer-when-downgrade&lt;/option&gt;' +\n                            '&lt;option' + (field.value === 'origin' ? ' selected=\"selected\"' : '') + '&gt;origin&lt;/option&gt;' +\n                            '&lt;option' + (field.value === 'origin-when-cross-origin' ? ' selected=\"selected\"' : '') + '&gt;origin-when-cross-origin&lt;/option&gt;' +\n                            '&lt;option' + (field.value === 'unsafe-url' ? ' selected=\"selected\"' : '') + '&gt;unsafe-url&lt;/option&gt;' +\n                        '&lt;/select&gt;' +\n                    '&lt;/div&gt;' +\n                '&lt;/div&gt;';\n\n                return html;\n            }\n        },\n        example: {\n            // Missing label is replaced by the key of this object (here 'example')\n            // Missing name is the key\n            // When value is missing, value = ''\n            // When type is missing, 'text' is assumed. You can use all the input field types,\n            //   plus checkbox and radio (select and textarea are not supported)\n            // When attributes is missing, {} is used. Attributes are added as attributes to\n            //   the input element.\n            // For radio and checkbox fields, you will need to use attributes if you want it\n            //   to be checked by default.\n        }\n    },\n    // Callback is called when user confirms\n    callback: function(values){\n        img.attr('src', values['url']);\n        img.attr('alt', values['alt']);\n\n        return true; // Return true if you have finished with this modal box\n        // If you do not return anything, you must manage the closing of the modal box yourself\n    }\n});\n\n// You can also listen for modal confirm/cancel events to do some custom things\n// Note: the openModalInsert callback is called on tbwconfirm\n$modal.on('tbwconfirm', function(e){\n    // Do what you want\n});\n$modal.on('tbwcancel', function(e){\n    trumbowyg.closeModal();\n});\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\">\n            <h3 id=\"range\">Range</h3>\n\n            <p>\n                Managing correctly text range, is not so trivial. Trumbowyg has a system to save and restore\n                selection range which does not involve typical getter/setter.\n            </p>\n\n            <h4>Save and get current range</h4>\n            <pre><code class=\"javascript\">\n// Save current range\ntrumbowyg.saveRange();\n\n// Restore last saved range\ntrumbowyg.restoreRange();\n            </code></pre>\n\n            <h4>Get selection range</h4>\n            <pre><code class=\"javascript\">\n// range contains a JavaScript range\nvar range = trumbowyg.getRange();\n            </code></pre>\n\n            <h4>Get last saved range text (aka selected text)</h4>\n            <pre><code class=\"javascript\">\nvar text = trumbowyg.getRangeText();\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\">\n            <h3 id=\"manage-content\">Manage content</h3>\n            <p>\n                You can set and get current HTML content of the editor with a getter/setter:\n            </p>\n            <pre><code class=\"javascript\">\n// Get HTML content\ntrumbowyg.html();\n\n// Set HTML content\ntrumbowyg.html('&lt;p&gt;Your content here&lt;/p&gt;');\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\">\n            <h3 id=\"empty\">Empty</h3>\n            <p>\n                You can empty the content of the editor.\n            </p>\n            <pre><code class=\"javascript\">\ntrumbowyg.empty();\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\">\n            <h3 id=\"enable-disable-edition\">Enable/disable edition</h3>\n            <p class=\"added-feature\">Added in 2.1.0</p>\n            <p>\n                As you can disable editor by using <a href=\"../#disabled\">disabled</a> option, you can also switch between\n                enabled and disabled states by using API.\n            </p>\n            <pre><code class=\"javascript\">\ntrumbowyg.setDisabled(true);\ntrumbowyg.setDisabled(false);\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\">\n            <h3 id=\"toggle\">Toggle between HTML & WYSIWYG modes</h3>\n            <p>\n                You can switch between HTML view and WYSIWYG view via toggle method.\n            </p>\n            <pre><code class=\"javascript\">\ntrumbowyg.toggle();\n            </code></pre>\n        </div>\n    </section>\n</main>\n\n\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<script src=\"../../js/vendor/highlight.js\"></script>\n<script src=\"../../js/main.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/documentation/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <title>Documentation | Trumbowyg: A lightweight WYSIWYG editor | Alex-D / Alexandre Demode</title>\n    <meta name=\"description\" content=\"Trumbowyg is a jQuery plugin for create WYSIWYG editor\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <link rel=\"icon\" type=\"image/png\" href=\"../favicon.png\">\n\n    <link rel=\"stylesheet\" href=\"../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"overflow: hidden;visibility: hidden;height: 0;width: 0;\">\n    <symbol id=\"trumbowyg-link\" viewBox=\"0 0 72 72\">\n        <path d=\"M30.9 49.1l-6.7 6.7c-.8.8-1.6.9-2.1.9s-1.4-.1-2.1-.9l-5.2-5.2c-1.1-1.1-1.1-3.1 0-4.2l6.1-6.1.2-.2 6.5-6.5c-1.2-.6-2.5-.9-3.8-.9-2.3 0-4.6.9-6.3 2.6L10.8 42c-3.5 3.5-3.5 9.2 0 12.7l5.2 5.2c1.7 1.7 4 2.6 6.3 2.6s4.6-.9 6.3-2.6l6.7-6.7C38 50.5 38.6 46.3 37 43l-6.1 6.1zM38.5 22.7l6.7-6.7c.8-.8 1.6-.9 2.1-.9s1.4.1 2.1.9l5.2 5.2c1.1 1.1 1.1 3.1 0 4.2l-6.1 6.1-.2.2-6.5 6.5c1.2.6 2.5.9 3.8.9 2.3 0 4.6-.9 6.3-2.6l6.7-6.7c3.5-3.5 3.5-9.2 0-12.7l-5.2-5.2c-1.7-1.7-4-2.6-6.3-2.6s-4.6.9-6.3 2.6l-6.7 6.7c-2.7 2.7-3.3 6.9-1.7 10.2l6.1-6.1z\"></path>\n        <path d=\"M44.1 30.7c.2-.2.4-.6.4-.9 0-.3-.1-.6-.4-.9l-2.3-2.3c-.2-.2-.6-.4-.9-.4-.3 0-.6.1-.9.4L25.8 40.8c-.2.2-.4.6-.4.9 0 .3.1.6.4.9l2.3 2.3c.2.2.6.4.9.4.3 0 .6-.1.9-.4l14.2-14.2z\"></path>\n    </symbol>\n</svg>\n<div class=\"sidebar\">\n    <div class=\"sidebar-inner\">\n        <header class=\"header-documentation\">\n            <a href=\"../\" class=\"documentation-logo-link\" title=\"Back to Trumbowyg landing\">\n                <img src=\"../img/logo-doc.svg\" alt=\"\" class=\"documentation-logo\">\n            </a>\n            <h1 class=\"documentation-title\">\n                Documentation\n            </h1>\n            <nav class=\"documentation-menu\">\n                <a href=\"./\">Docs</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"./plugins/\">Plugins</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"./core/\">Core</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"../demos/\">Demos</a>\n            </nav>\n        </header>\n\n        <aside class=\"documentation-summary\">\n            <ul>\n                <li>\n                    <a href=\"#get-started\">Get started</a>\n                    <ul>\n                        <li><a href=\"#installation\">Installation</a></li>\n                        <li><a href=\"#basics\">Basics</a></li>\n                        <li><a href=\"#common-issues\">Common issues</a></li>\n                        <li><a href=\"#use-plugins\">Use plugins</a></li>\n                        <li><a href=\"./plugins/#create-your-own\">Create a plugin</a></li>\n                    </ul>\n                </li>\n                <li>\n                    <a href=\"#general\">General</a>\n                    <ul>\n                        <li><a href=\"#prefix\">Prefix</a></li>\n                        <li><a href=\"#localization\">Localization</a></li>\n                        <li><a href=\"#custom-skin\">Custom skin</a></li>\n                        <li><a href=\"#svg-icons\">SVG icons</a></li>\n                        <li><a href=\"#placeholder\">Placeholder</a></li>\n                        <li><a href=\"#disabled\">Disabled</a></li>\n                    </ul>\n                </li>\n                <li>\n                    <a href=\"#basic-options\">Basic Options</a>\n                    <ul>\n                        <li><a href=\"#button-pane\">Button pane</a></li>\n                        <li><a href=\"#change-active-dropdown-icon\">Active dropdown icon</a></li>\n                        <li><a href=\"#hide-button-texts\">Hide button texts</a></li>\n                        <li><a href=\"#semantic\">Semantic</a></li>\n                        <li><a href=\"#reset-css\">Reset CSS</a></li>\n                        <li><a href=\"#remove-format-pasted\">Remove format pasted</a></li>\n                        <li><a href=\"#tags-to-remove\">Tags to remove</a></li>\n                        <li><a href=\"#tags-to-keep\">Tags to keep</a></li>\n                        <li><a href=\"#auto-grow\">Auto grow</a></li>\n                        <li><a href=\"#auto-grow-on-enter\">Auto grow on enter</a></li>\n                        <li><a href=\"#image-width-modal-edit\">Image width modal edit</a></li>\n                        <li><a href=\"#url-protocol\">URL protocol</a></li>\n                        <li><a href=\"#minimal-links\">Minimal links</a></li>\n                        <li><a href=\"#link-targets\">Link targets</a></li>\n                        <li><a href=\"#tag-classes\">Tag classes</a></li>\n                    </ul>\n                </li>\n                <li>\n                    <a href=\"#advanced-options\">Advanced Options</a>\n                    <ul>\n                        <li><a href=\"#add-localization\">Add a localization</a></li>\n                        <li><a href=\"#custom-buttons\">Custom buttons</a></li>\n                        <li><a href=\"#custom-dropdowns\">Custom dropdowns</a></li>\n                    </ul>\n                </li>\n                <li>\n                    <a href=\"#api\">API</a>\n                    <ul>\n                        <li><a href=\"#modal-box\">Modal box</a></li>\n                        <li><a href=\"#range\">Range</a></li>\n                        <li><a href=\"#manage-content\">Manage content</a></li>\n                        <li><a href=\"#empty\">Empty</a></li>\n                        <li><a href=\"#enable-disable-edition\">Enable/disable edition</a></li>\n                        <li><a href=\"#toggle\">Toggle HTML/WYSIWYG</a></li>\n                        <li><a href=\"#destroy-editor\">Destroy editor</a></li>\n                        <li><a href=\"#events\">Events</a></li>\n                    </ul>\n                </li>\n            </ul>\n        </aside>\n\n        <div class=\"documentation-sidebar-beer\">\n            <a href=\"../#donate\">\n                <img src=\"../img/beer.svg\" alt=\"\" class=\"beer-icon\">\n                <span class=\"beer-label\">\n                    Do you enjoy Trumbowyg? <br>\n                    Consider supporting me :)\n                </span>\n            </a>\n        </div>\n    </div>\n</div>\n\n<main class=\"main\">\n    <section id=\"get-started\" class=\"wrapper section\">\n        <h2 class=\"section-title\">Get started</h2>\n\n        <div class=\"feature\">\n            <h3 id=\"installation\">Installation</h3>\n\n            <div class=\"installation-first-step\">\n                <div class=\"installation-package-managers\">\n                    <div class=\"installation-col-title\">\n                        Via a package manager\n                    </div>\n                    <code>npm install trumbowyg</code>\n                    <code>bower install trumbowyg</code>\n                </div>\n                <div class=\"installation-or\">\n                    or\n                </div>\n                <div class=\"installation-download\">\n                    <div class=\"installation-col-title\">\n                        Download the package\n                    </div>\n                    <a href=\"https://github.com/Alex-D/Trumbowyg/archive/main.zip\" class=\"button button-ghost\">Download</a>\n                </div>\n                <div class=\"installation-cdn\">\n                    <div class=\"installation-col-title\">\n                        Use CDNJS\n                    </div>\n                    <a href=\"https://cdnjs.com/libraries/Trumbowyg\" class=\"button button-ghost\">See all available files</a>\n                </div>\n            </div>\n\n            <p>\n                If you don't already do it, load jQuery at bottom of <code>&lt;body&gt;</code> like so:\n            </p>\n            <pre><code class=\"html\">\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n            </code></pre>\n            <p class=\"note\">\n                Trumbowyg requires jQuery >= 1.8\n            </p>\n\n            <p>\n                After these lines, you have to load Trumbowyg.\n            </p>\n            <pre><code class=\"html\">\n&lt;script src=\"trumbowyg/dist/trumbowyg.min.js\">&lt;/script>\n            </code></pre>\n\n            <p>\n                Don't forget to load Trumbowyg CSS in the <code>&lt;head&gt;</code>, or load your own style for the\n                editor.\n            </p>\n            <pre><code class=\"html\">\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/ui/trumbowyg.min.css\">\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\">\n            <h3 id=\"basics\">Basics</h3>\n\n            <p>\n                This the minimal code to transform a simple div into the amazing WYSIWYG editor which is Trumbowyg.\n            </p>\n            <pre><code class=\"javascript\">\n$('#trumbowyg-demo').trumbowyg();\n            </code></pre>\n            <p>\n                If you want to set options to Trumbowyg, add an object which contains your options as parameters.\n            </p>\n            <pre><code class=\"javascript\">\n$('#trumbowyg-demo').trumbowyg({\n    btns: [['strong', 'em',], ['insertImage']],\n    autogrow: true\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"common-issues\">Common issues</h3>\n\n            <h4>SVG icons does not load</h4>\n\n            <ul>\n                <li>check if you are in HTTP(S) protocol;</li>\n                <li>check if you do not have cross domain error (XHR request is used).</li>\n            </ul>\n            <p>\n                If your problem is not solved by these tips, check the\n                <a href=\"#svg-icons\">SVG icons section</a>.\n            </p>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"use-plugins\">Use plugins</h3>\n\n            <h4>Add a plugin to your page</h4>\n\n            <p>\n                Basically you need to add the plugin JS to your page, at the bottom of your <code>&lt;body></code>,\n                <strong>after</strong> jQuery and Trumbowyg imports (in this order), but before your custom JS which\n                initialize Trumbowyg:\n            </p>\n            <pre><code class=\"html\">\n&lt;!-- Import jQuery -->\n&lt;script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\">&lt;/script>\n&lt;script>window.jQuery || document.write('&lt;script src=\"js/vendor/jquery-3.3.1.min.js\">&lt;\\/script>')&lt;/script>\n\n&lt;!-- Import Trumbowyg -->\n&lt;script src=\"trumbowyg/dist/trumbowyg.min.js\">&lt;/script>\n\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/upload/trumbowyg.cleanpaste.min.js\">&lt;/script>\n&lt;script src=\"trumbowyg/dist/plugins/upload/trumbowyg.pasteimage.min.js\">&lt;/script>\n\n&lt;!-- Init Trumbowyg -->\n&lt;script>\n    // Doing this in a loaded JS file is better, I put this here for simplicity\n    $('#my-editor').trumbowyg();\n&lt;/script>\n            </code></pre>\n\n            <p>\n                In the previous case, plugins are \"auto registering\" themself into Trumbowyg and be activated in\n                <strong>all</strong> future Trumbowyg instances.\n            </p>\n            <p>\n                But most popular plugins are button-based, like\n                <a href=\"./plugins/#plugin-upload\">upload</a> or\n                <a href=\"./plugins/#plugin-colors\">colors</a> ones.\n                If you want to use these plugins, load them like explained before, then add the plugin button to your editor\n                by <a href=\"#button-pane\">checking the button pane doc section</a>.\n            </p>\n            <p>\n                For more information on plugins, check <a href=\"./plugins/\">the plugins documentation page.</a>\n            </p>\n        </div>\n    </section>\n\n\n    <section id=\"general\" class=\"wrapper section\">\n        <h2 class=\"section-title\">General</h2>\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"prefix\">Prefix</h3>\n            <p>\n                You can change prefix of all class added on elements of Trumbowyg using this option:\n            </p>\n            <pre><code class=\"javascript\">\n$('textarea').trumbowyg({\n    prefix: 'custom-prefix'\n});\n            </code></pre>\n            <p>\n                For example, the bold button class is now <code class=\"javascript\">custom-prefix-bold-button</code>\n            </p>\n            <p class=\"note\">\n                Default value is <code>trumbowyg</code>\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"localization\">Localization</h3>\n            <p>\n                Your users don't speak english? No problem, Trumbowyg has a language parameter. You have to load the\n                appropriate lang file. Search in <code>/dist/langs</code> folder to see if a language file already\n                exists, if not create it and share it :). See <a href=\"#add-localization\">add a localization</a> for\n                more details on language file.\n            </p>\n            <p>\n                Don't forget include the lang file in your pages:\n            </p>\n            <pre><code class=\"html\">\n&lt;script type=\"text/javascript\" src=\"js/dist/langs/fr.min.js\"&gt;&lt;/script&gt;\n            </code></pre>\n            <p class=\"note\">\n                Warning, include lang file after Trumbowyg and before instantiating the editor!\n            </p>\n            <p>\n                Usage of language parameter:\n            </p>\n            <pre><code class=\"javascript\">\n$('textarea').trumbowyg({\n    lang: 'fr'\n});\n            </code></pre>\n            <p class=\"note\">\n                If the lang was not found, english values are used by default.\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"custom-skin\">Custom skin</h3>\n            <p>\n                Trumbowyg is flexible and simple. You want a different look?\n            </p>\n\n            <h4>Replace existing CSS file</h4>\n            <p>\n                Copy <code>/src/ui/</code> folder somewhere and customize style. Finally, link your new CSS file and\n                remove link to Trumbowyg default style.\n            </p>\n            <p class=\"note\">\n                It is not recommended to directly edit the CSS file in the trumbowyg folder. When you update the plugin,\n                your modifications will be erased.\n            </p>\n\n            <br>\n\n            <h4>Multiple skins for multiple Trumbowyg</h4>\n            <p>\n                This is useful when you do not want same design for all instances of Trumbowyg.\n            </p>\n            <p>\n                Use the prefix option:\n            </p>\n            <pre><code class=\"javascript\">\n$('.editor-modern-ui').trumbowyg({\n    prefix: 'modern-ui'\n});\n            </code></pre>\n            <p>\n                In your CSS, you can now stylize <code>.modern-ui-link-button</code> for example, whitout conflicts with\n                the default skin. It's necessary to redefine style for all elements. If you want to start from the\n                default skin, copy <code>/src/ui/</code> folder, replace all <code>trumbowyg-</code> by your prefix and\n                work from here.\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.1.0\">\n            <h3 id=\"svg-icons\">SVG icons</h3>\n            <p class=\"added-feature\">Added in 2.1.0</p>\n            <p>\n                A pack of SVG icons is available and enabled by default. This file is loaded via XHR request\n                in JavaScript so it is possible the path is not matching with your assets file paths.\n                You can change the path of the SVG or disable this feature.\n            </p>\n\n            <h4>Change SVG path globally</h4>\n            <p>\n                To change SVG path, you need to set the path in global Trumbowyg configuration object:\n            </p>\n            <pre><code class=\"javascript\">\n$.trumbowyg.svgPath = '/assets/my-custom-path/icons.svg';\n            </code></pre>\n            <p class=\"note\">\n                This global way needs to be done before initialize any Trumbowyg instance.\n            </p>\n\n            <h4>Disable SVG icons globally</h4>\n            <p>\n                If you do not want SVG icons, you can set this option to false. Then, you can add your custom\n                icons by CSS or what you want.\n            </p>\n            <pre><code class=\"javascript\">\n$.trumbowyg.svgPath = false;\n            </code></pre>\n            <p>\n                Check <a href=\"#hide-button-texts\">hide button texts</a> option if you did not want button content at all\n                and customize it by yourself.\n            </p>\n            <p class=\"note\">\n                This global way needs to be done before initialize any Trumbowyg instance.\n            </p>\n\n            <h4>Change SVG path or disable SVG icons locally</h4>\n            <p>\n                You can also apply <code>svgPath</code> option for an isolated editor only.\n            </p>\n            <pre><code class=\"javascript\">\n$('.editor').trumbowyg({\n    svgPath: false // or a path like '/assets/my-custom-path/icons.svg'\n});\n            </code></pre>\n\n            <h4>Use absolute path to SVG sprite</h4>\n            <p class=\"added-feature\">Added in 2.22.0</p>\n            <p class=\"note\">\n                If you want to be IE-complient you should use this option.\n            </p>\n            <p>\n                This will load icons directly from the sprite file.\n                Instead of loading the sprite inline into the page, you can directly set this global option to true.\n            </p>\n            <pre><code class=\"javascript\">\n$.trumbowyg.svgAbsoluteUsePath = true;\n            </code></pre>\n            <p>\n                This option is useful to avoid issues with <code>baseURL</code>.\n            </p>\n            <p class=\"note\">\n                This global way needs to be done before initialize any Trumbowyg instance.\n            </p>\n            <p class=\"note\">\n                Default value for <code>svgAbsoluteUsePath</code> is <code>false</code>.\n            </p>\n\n            <h4>Use SVG icons without XHR or via an another protocol than HTTP(S)</h4>\n            <p class=\"note\">\n                If you want to be IE9-complient you should use this option.\n            </p>\n            <p>\n                If you do not want use HTTP(S) protocol or use XHR to load icons, you can load icons in your HTML\n                on your own. You just need to include the\n                <a href=\"https://raw.githubusercontent.com/Alex-D/Trumbowyg/main/dist/ui/icons.svg\">icons.svg file</a>\n                inline in your <code>&lt;body></code>:\n            </p>\n            <pre><code class=\"html\">\n&lt;div id=\"trumbowyg-icons\">\n    &lt;svg xmlns=\"http://www.w3.org/2000/svg\">\n        &lt;symbol id=\"trumbowyg-blockquote\" viewBox=\"0 0 72 72\">&lt;path d=\"...\">&lt;/path>&lt;/symbol>\n        &lt;symbol id=\"trumbowyg-bold\" viewBox=\"0 0 72 72\">&lt;path d=\"...\">&lt;/path>&lt;/symbol>\n        &lt;symbol id=\"trumbowyg-close\" viewBox=\"0 0 72 72\">&lt;path d=\"...\">&lt;/path>&lt;/symbol>\n        &lt;!-- ... all other icons here -->\n    &lt;/svg>\n&lt;/div>\n            </code></pre>\n            <p class=\"note\">\n                You need to use this id: <code>&lt;prefix&gt;-icons</code>.\n            </p>\n            <p>\n                Trumbowyg checks if a <code>#&lt;prefix&gt;-icons</code> exists. If not, it loads SVG icons file via\n                XHR and puts it in a div with this id. Next editor on the page does not load icons again. By adding\n                this div in the page, you \"hack\" this mechanism to load it on your own.\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.1.3\">\n            <h3 id=\"placeholder\">Placeholder</h3>\n            <p>\n                Like the HTML5 attribute on input and textarea, you can add a placeholder with Trumbowyg.\n            </p>\n            <pre><code class=\"html\">\n&lt;div class=\"my-editor\" placeholder=\"Your text as placeholder\">&lt;/div>\n            </code></pre>\n            <p class=\"note\">\n                Placeholder is visible only if the element is empty (no HTML/text).\n            </p>\n            <div class=\"note\">\n                <p>\n                    Placeholder is both managed in JS and CSS with the default style. If you create your own style, you\n                    need to apply the following style (replace <code>trumbowyg</code> by your prefix):\n                </p>\n                <pre><code class=\"css\">\n.trumbowyg-editor[contenteditable=true]:empty::before{\n    content: attr(placeholder);\n    color: #999;\n}\n                </code></pre>\n            </div>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.1.0\">\n            <h3 id=\"disabled\">Disabled</h3>\n            <p class=\"added-feature\">Added in 2.1.0</p>\n            <p>\n                Trumbowyg supports <code>disabled</code> attribute on a textarea and an option.\n            </p>\n            <pre><code class=\"html\">\n&lt;textarea class=\"my-editor\" disabled>&lt;/textarea>\n            </code></pre>\n            <pre><code class=\"javascript\">\n$('.a-disabled-editor').trumbowyg({\n    disabled: true\n});\n            </code></pre>\n            <p class=\"note\">\n                You can switch between disabled and enabled states by <a href=\"#enable-disable-edition\">using API</a>\n            </p>\n        </div>\n    </section>\n\n\n    <section id=\"basic-options\" class=\"wrapper section\">\n        <h2 class=\"section-title\">Basic Options</h2>\n\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"button-pane\">Button pane</h3>\n            <p>\n                It's probably the most interesting option, it allows you to choose the buttons that appears in the\n                button pane. This option is an array containing string values representing the buttons or vertical\n                separators (using the pipe character). To create your own custom button pane, define an array and pass\n                it to the <code>btns</code> option.\n            </p>\n            <pre><code class=\"javascript\">\n$('.simple-editor').trumbowyg({\n    btns: [['bold', 'italic'], ['link']]\n});\n            </code></pre>\n            <div class=\"note\">\n                <p>\n                    By default, <code>btns</code> option value is:\n                </p>\n                <pre><code class=\"javascript\">\n$('.simple-editor').trumbowyg({\n    btns: [\n        ['viewHTML'],\n        ['undo', 'redo'], // Only supported in Blink browsers\n        ['formatting'],\n        ['strong', 'em', 'del'],\n        ['superscript', 'subscript'],\n        ['link'],\n        ['insertImage'],\n        ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n        ['unorderedList', 'orderedList'],\n        ['horizontalRule'],\n        ['removeformat'],\n        ['fullscreen']\n    ]\n});\n                </code></pre>\n            </div>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.18.0\">\n            <h3 id=\"change-active-dropdown-icon\">Active dropdown icon</h3>\n            <p class=\"added-feature\">Added in 2.18.0</p>\n            <p>\n                Dropdown icon can change to the active sub-button icon with this option enabled.\n            </p>\n            <pre><code class=\"javascript\">\n$('.simple-editor').trumbowyg({\n    changeActiveDropdownIcon: true\n});\n            </code></pre>\n            <p class=\"note\">\n                By default, <code>changeActiveDropdownIcon</code> option value is: <code>false</code>\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.5.0\">\n            <h3 id=\"hide-button-texts\">Hide button texts</h3>\n            <p class=\"added-feature\">Added in 2.5.0</p>\n            <p>\n                You can hide button texts showed when you put <a href=\"#svg-icons\">svgPath to false</a>.\n            </p>\n            <pre><code class=\"javascript\">\n// Globally\n$.trumbowyg.hideButtonTexts = true\n\n// Or locally\n$('.trumbowyg').trumbowyg({\n    hideButtonTexts: true\n});\n            </code></pre>\n            <p class=\"note\">\n                If you disable SVG icons and button texts, you should design them by yourself.\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"semantic\">Semantic</h3>\n            <p>\n                Generates a better, more semantic oriented HTML (i.e. <code>&lt;em&gt;</code> instead of <code>\n                &lt;i&gt;</code>, <code>&lt;strong&gt;</code> instead of <code>&lt;b&gt;</code>, etc.). It's just a\n                boolean:\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    semantic: false\n});\n            </code></pre>\n            <p>\n                Enabling semantic mode deactivates the <em>underline</em> button by default because they do not convey any real\n                semantic. If you want to reactivate them, you have to do it explicitly, see <a href=\"#button-pane\">Button\n                pane</a>\n            </p>\n            <p>\n                Since 2.12.0 you can also put an object to customize the semantic tag mapping for each one of these tags:\n                <code>&lt;b&gt;</code>,\n                <code>&lt;i&gt;</code>,\n                <code>&lt;s&gt;</code>,\n                <code>&lt;strike&gt;</code>,\n                <code>&lt;div&gt;</code>.\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    semantic: {\n        'div': 'div' // Editor does nothing on div tags now\n    }\n});\n            </code></pre>\n            <p class=\"note\">\n                This option is set to <code>true</code> by default which is equivalent to:\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    semantic: {\n        'b': 'strong',\n        'i': 'em',\n        's': 'del',\n        'strike': 'del',\n        'div': 'p'\n    }\n});\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"reset-css\">Reset CSS</h3>\n            <p>\n                If you don't want the page style to impact on the look of the text in the editor, you will need to apply\n                a reset-css on the editor. You can activate this with the <code>resetCss</code> option:\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    resetCss: true\n});\n            </code></pre>\n            <p class=\"note\">\n                This option is set to <code>false</code> by default. The reset only applies to the editor, not to the\n                generated HTML code.\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.0.0\">\n            <h3 id=\"remove-format-pasted\">Remove format pasted</h3>\n            <p>\n                If you don't want styles pasted from clipboard (from Word or other webpage for example), pass the <code>removeformatPasted</code>\n                option to <code>true</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    removeformatPasted: true\n});\n            </code></pre>\n            <p class=\"note\">\n                In order to use this option, you need to define a font size in your CSS or use a reset like normalize.\n            </p>\n            <p class=\"note\">\n                Remove format pasted is not active by default (set to <code>false</code>).\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.0.0\">\n            <h3 id=\"tags-to-remove\">Tags to remove</h3>\n            <p>\n                Allow to sanitize the code by removing all tags you want. The <code>tagsToRemove</code>\n                option is an array.\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    tagsToRemove: ['script', 'link']\n});\n            </code></pre>\n            <p class=\"note\">\n                You must do the sanitize server-side too to avoid some security issues like XSS.\n            </p>\n            <p class=\"note\">\n                Tags to remove is an empty array by default (set to <code>[]</code>).\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.12.0\">\n            <h3 id=\"tags-to-keep\">Tags to keep</h3>\n            <p class=\"added-feature\">Added in 2.12.0</p>\n            <p>\n                Sometimes you want to keep some empty <code>i</code> tags for <em>Font Awesome</em> or anything else. You can define this list via the <code>tagsToKeep</code>\n                option.\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    tagsToKeep: ['i', 'script[src]']\n});\n            </code></pre>\n            <p class=\"note\">\n                Default tags to keep are <code>['hr', 'img', 'embed', 'iframe', 'input']</code>.\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"auto-grow\">Auto grow</h3>\n            <p>\n                The text editing zone can extend itself when writing a long text. To activate this feature, use the\n                autogrow option:\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    autogrow: true\n});\n            </code></pre>\n            <p class=\"note\">\n                Autogrow is not active by default (set to <code>false</code>).\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.7.0\">\n            <h3 id=\"auto-grow-on-enter\">Auto grow on enter</h3>\n            <p class=\"added-feature\">Added in 2.7.0</p>\n            <p>\n                The text editing zone can extend itself when editor get focus and reduce on blur.\n                To activate this feature, use the following option:\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    autogrowOnEnter: true\n});\n            </code></pre>\n            <p class=\"note\">\n                Autogrow on enter is not active by default (set to <code>false</code>).\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.9.0\">\n            <h3 id=\"image-width-modal-edit\">Image width modal edit</h3>\n            <p class=\"added-feature\">Added in 2.9.0</p>\n            <p>\n                Add a field in image insert/edit modal which allow users to set the image width.\n                To activate this feature, use the following option:\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    imageWidthModalEdit: true\n});\n            </code></pre>\n            <p class=\"note\">\n                Image width modal edit is not active by default (set to <code>false</code>).\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.9.4\">\n            <h3 id=\"url-protocol\">URL protocol</h3>\n            <p class=\"added-feature\">Added in 2.9.4</p>\n            <p>\n                An option to auto-prefix URLs with a protocol.\n            </p>\n            <p>\n                When this option\n                is set to <code>true</code>, URLs missing a protocol will be\n                prefixed with <code>https://</code>. Alternatively, a string can\n                be provided for a custom prefix.\n            </p>\n            <p>\n                For example, a value of <code>true</code> would convert\n                <code>example.com</code> to\n                <code>https://example.com</code>, while a value of\n                <code>ftp</code> converts to\n                <code>ftp://example.com</code>.\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    urlProtocol: true\n});\n            </code></pre>\n            <p class=\"note\">\n                Anchors, email addresses and relative links are left unchanged.\n            </p>\n            <p class=\"note\">\n                URL protocol is not active by default (set to <code>false</code>).\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.9.4\">\n            <h3 id=\"minimal-links\">Minimal links</h3>\n            <p class=\"added-feature\">Added in 2.9.4</p>\n            <p>\n                Reduce the link overlay to use only <code>url</code> and\n                <code>text</code> fields, omitting <code>title</code> and\n                <code>target</code>.\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    minimalLinks: true\n});\n            </code></pre>\n            <p class=\"note\">\n                The minimal links option is not active by default (set to\n                <code>false</code>).\n            </p>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.26.0\">\n            <h3 id=\"link-targets\">Link targets</h3>\n            <p class=\"added-feature\">Added in 2.26.0</p>\n            <p>\n                Allow to set link target attribute value to what you want, even if the <code>minimalLinks</code>\n                option is set to <code>true</code>.\n            </p>\n            <p>\n                First value is the default value (similar to previous <code>defaultLinkTarget</code> option).\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    linkTargets: ['_blank', '_self']\n});\n            </code></pre>\n            <p class=\"note\">\n                Link targets only list most used options by default (set to <code>['_self', '_blank']</code>).\n            </p>\n            <div>\n                <h4>\n                    Upgrade from <code>defaultLinkTarget</code>\n                </h4>\n\n                <pre><code class=\"diff javascript\">\n$('.trumbowyg').trumbowyg({\n-    defaultLinkTarget: '_blank',\n+    linkTargets: ['_blank', '_self', '_parent', '_top'],\n});\n                </code></pre>\n            </div>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.23.0\">\n            <h3 id=\"tag-classes\">Tag classes</h3>\n            <p class=\"added-feature\">Added in 2.23.0</p>\n            <p>\n                Add classes to any tag.\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    tagClasses: {\n        h1: 'h1', // Bootstrap example\n        blockquote: 'bg-grey-100 rounded-xl', // Tailwind CSS example\n    }\n});\n            </code></pre>\n            <p class=\"note\">\n                No classes are applied by default.\n            </p>\n        </div>\n    </section>\n\n\n    <section id=\"advanced-options\" class=\"wrapper section\">\n        <h2 class=\"section-title\">Advanced Options</h2>\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"add-localization\">Add a localization</h3>\n            <p>\n                The structure of a language file is simple, it is a JavaScript Object which associate a translation to\n                any key. For example:\n            </p>\n            <pre><code class=\"javascript\">\njQuery.trumbowyg.langs.fr = {\n    _dir: \"ltr\", // Changes the editor dir\n\n    bold: \"Gras\",\n    close: \"Fermer\"\n};\n            </code></pre>\n            <p>\n                Some localizations are added each day, you can find them in\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/main/dist/langs\">the langs folder on GitHub</a>\n            </p>\n            <p>\n                You can submit a new localization file by creating a new pull request on the Github repository.\n            </p>\n            <p class=\"note\">\n                English is the default localization, you don't need to include any file to get Trumbowyg in English.\n            </p>\n        </div>\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"custom-buttons\">Custom buttons</h3>\n            <p>\n                If Trumbowyg does not fit your needs, maybe you can create your very own custom button to solve this.\n                The following code (which does not works as is) show you all available button parameters.\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    btnsDef: {\n        buttonName: {\n            fn: 'functionName',\n            tag: 'tagName',\n            title: 'Button tooltip',\n            text: 'Displayed button name',\n            isSupported: function () { return true; },\n            key: 'K',\n            param: '' ,\n            forceCSS: false,\n            class: '',\n            hasIcon: true\n        }\n    }\n});\n            </code></pre>\n            <p>\n                The key (here <code>buttonName</code>) is the button name used in <code>btns</code> and in <code>dropdown</code>.\n                It is used as many default in options below.\n            </p>\n            <h4>Parameters</h4>\n            <dl>\n                <dt><strong><code>fn</code></strong> <code class=\"type\">string</code>|<code class=\"type\">function</code></dt>\n                <dd>\n                    The name of a Trumbowyg internal method OR a callable function OR browser native execCommand name.\n                    In any case, the function is called when the user click on the button or use the associated shortcut.\n                    <br>\n                    <strong>Default</strong>: button name\n                </dd>\n                <dt><strong><code>tag</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    The HTML tag name which highlight the button if cursor is in a tag which this tag name.\n                    <br>\n                    <strong>Default</strong>: button name\n                </dd>\n                <dt><strong><code>title</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    The text displayed in a tooltip on mouse over a button.\n                    <br>\n                    <strong>Default</strong>: <code>text</code> parameter OR translated button name OR raw button name\n                </dd>\n                <dt><strong><code>text</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    The text of the button used when <a href=\"#svg-icons\">svgPath is set to false</a>.\n                    This text can be hidden via <code><a href=\"#hide-button-texts\">hideButtonTexts</a></code> option.\n                    <br>\n                    <strong>Default</strong>: <code>title</code> parameter OR translated button name OR raw button name\n                </dd>\n                <dt><strong><code>isSupported</code></strong> <code class=\"type\">function</code></dt>\n                <dd>\n                    A function which returns a Boolean to know if the custom button is supported (browser compatibility\n                    check, context check, ...)\n                    <br>\n                    <strong>Default</strong>: <code>null</code> (no check)\n                </dd>\n                <dt><strong><code>key</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    Shortcut key which triggers the button function (<code>fn</code>)\n                    <br>\n                    <strong>Default</strong>: <code>null</code> (no shortcut defined)\n                </dd>\n                <dt><strong><code>param</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    In case of using browser native execCommand, give this as parameter.\n                    <br>\n                    <strong>Default</strong>: button name\n                </dd>\n                <dt><strong><code>forceCSS</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    In case of using browser native execCommand, force usage of inline CSS insteed of a tag.\n                    <br>\n                    <strong>Default</strong>: <code>false</code>\n                </dd>\n                <dt><strong><code>class</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    A string which is added to the button class attribute.\n                    <br>\n                    <strong>Default</strong>: Trumbowyg adds a <code>prefix + '-' + buttonName</code> class\n                </dd>\n                <dt><strong><code>hasIcon</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Allow us to force the display of the text for a specific button.\n                    <br>\n                    <strong>Default</strong>: <code>true</code>\n                </dd>\n            </dl>\n            <p>\n                Working example:\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    btnsDef: {\n        alert: {\n            fn: function() {\n                alert('some text')\n            },\n            ico: 'blockquote'\n        }\n    },\n    btns: [\n        ['alert']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"custom-dropdowns\">Custom dropdowns</h3>\n            <p>\n                You can also create your own dropdown, like buttons. The following code (which does not works as is)\n                show use all options which can be used to make our own customized dropdown.\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    btnsDef: {\n        dropdownButtonName: {\n            dropdown: ['btnA', 'btnB'],\n            title: 'Displayed dropdown button name',\n            ico: 'iconName',\n            hasIcon: true\n        }\n    }\n});\n            </code></pre>\n            <h4>Parameters</h4>\n            <dl>\n                <dt><strong><code>dropdown</code></strong> <code class=\"type\">array&lt;string></code></dt>\n                <dd>\n                    A list of button names to list in the dropdown.\n                    <br>\n                    <strong>Default</strong>: <code>[]</code>\n                </dd>\n                <dt><strong><code>title</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    The text displayed in a tooltip on mouse over the dropdown button.\n                    <br>\n                    <strong>Default</strong>: translated dropdown button name OR raw dropdown button name\n                </dd>\n                <dt><strong><code>ico</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    The icon name for the dropdown. You can reuse <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/src/ui/icons\">some existing icons from Trumbowyg</a>.\n                    <br>\n                    <strong>Default</strong>: icon with button name in snake case\n                </dd>\n                <dt><strong><code>hasIcon</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Allow us to force the display of the text for a specific button.\n                    <br>\n                    <strong>Default</strong>: <code>true</code>\n                </dd>\n            </dl>\n            <p>\n                Working example which groups all justify buttons in one dropdown:\n            </p>\n            <pre><code class=\"javascript\">\n$('.trumbowyg').trumbowyg({\n    btnsDef: {\n        align: {\n            dropdown: ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n            ico: 'justifyLeft'\n        }\n    },\n    btns: [\n        ['align']\n    ]\n});\n            </code></pre>\n        </div>\n    </section>\n\n\n    <section id=\"api\" class=\"wrapper section\">\n        <h2 class=\"section-title\">API</h2>\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"modal-box\">Modal box</h3>\n            <p>\n                When you want create your custom extension for Trumbowyg, you can open and close a modal box with custom\n                inner HTML code, listen events and more.\n            </p>\n\n            <h4>Open and close</h4>\n            <p>\n                For that use the <code class=\"javascript\">.trumbowyg()</code> method and give parameters <code>'openModal'</code>\n                or <code>'closeModal'</code> like that:\n            </p>\n            <pre><code class=\"javascript\">\n// Open a modal box\nvar $modal = $('#editor').trumbowyg('openModal', {\n    title: 'A title for modal box',\n    content: '&lt;p&gt;Content in HTML which you want include in created modal box&lt;/p&gt;'\n});\n\n// Close current modal box\n$('#editor').trumbowyg('closeModal');\n            </code></pre>\n            <p>\n                An <code>openModal</code> call returns a jQuery object which contains the modal box. You need this\n                object if you want to use listen events (see below).\n            </p>\n            <p class=\"note\">\n                Only one modal box can open at any given moment. So, <code>openModal</code> return false if a modal is\n                currently opened.\n            </p>\n\n            <h4>Events on modal box</h4>\n            <p>\n                Modal boxes in Trumbowy come with two buttons: \"Confirm\" and \"Cancel\". An event is associated to each\n                one:\n            </p>\n            <ul>\n                <li><code>tbwsubmit</code>: triggered when form is submit</li>\n                <li><code>tbwreset</code>: triggered when user cancel operation</li>\n            </ul>\n            <pre><code class=\"javascript\">\n// Open a modal box\nvar $modal = $('#editor').trumbowyg('openModal', {\n    title: 'A title for modal box',\n    content: '&lt;p&gt;Content in HTML which you want include in created modal box&lt;/p&gt;'\n});\n\n// Listen clicks on modal box buttons\n$modal.on('tbwconfirm', function(e){\n    // Save data\n    $(\"#editor\").trumbowyg('closeModal');\n});\n$modal.on('tbwcancel', function(e){\n    $('#editor').trumbowyg('closeModal');\n});\n            </code></pre>\n\n            <h4>Only build inputs in modal</h4>\n            <p>\n                If you want only add inputs in the modal box, this function is more simple. Indeed, you do not manage\n                confirm and close buttons, and get all input value on confirm.\n            </p>\n            <pre><code class=\"javascript\">\nvar img = $('img#an-img');\n$(\"#editor\").trumbowyg('openModalInsert', {\n    title: 'A title for modal box',\n    fields: {\n        url: {\n            value: img.attr('src')\n        },\n        alt: {\n            label: 'Alt',\n            name: 'alt',\n            value: img.attr('alt'),\n            type: 'text',\n            attributes: {}\n        },\n        example: {\n            // Missing label is replaced by the key of this object (here 'example')\n            // Missing name is the key\n            // When value is missing, value = ''\n            // When type is missing, 'text' is assumed. You can use all the input field types,\n            //   plus checkbox and radio (select and textarea are not supported)\n            // When attributes is missing, {} is used. Attributes are added as attributes to\n            //   the input element.\n            // For radio and checkbox fields, you will need to use attributes if you want it\n            //   to be checked by default.\n        }\n    },\n    // Callback is called when user confirms\n    callback: function(values){\n        img.attr('src', values['url']);\n        img.attr('alt', values['alt']);\n\n        return true; // Return true if you have finished with this modal box\n        // If you do not return anything, you must manage the closing of the modal box yourself\n    }\n});\n\n// You can also listen for modal confirm/cancel events to do some custom things\n// Note: the openModalInsert callback is called on tbwconfirm\n$modal.on('tbwconfirm', function(e){\n    // Do what you want\n});\n$modal.on('tbwcancel', function(e){\n    trumbowyg.closeModal();\n});\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.0.0\">\n            <h3 id=\"range\">Range</h3>\n\n            <p>\n                Managing correctly text range, is not so trivial. Trumbowyg has a system to save and restore\n                selection range which does not involves typical getter/setter.\n            </p>\n\n            <h4>Save and get current range</h4>\n            <pre><code class=\"javascript\">\n// Save current range\n$('#editor').trumbowyg('saveRange');\n\n// Restore last saved range\n$('#editor').trumbowyg('restoreRange');\n            </code></pre>\n\n            <h4>Get selection range</h4>\n            <pre><code class=\"javascript\">\n// range contains a JavaScript range\nvar range = $('#editor').trumbowyg('getRange');\n            </code></pre>\n\n            <h4>Get last saved range text</h4>\n            <pre><code class=\"javascript\">\nvar text = $('#editor').trumbowyg('getRangeText');\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"manage-content\">Manage content</h3>\n            <p>\n                You can set and get current HTML content of the editor with a getter/setter:\n            </p>\n            <pre><code class=\"javascript\">\n// Get HTML content\n$('#editor').trumbowyg('html');\n\n// Set HTML content\n$('#editor').trumbowyg('html', \"&lt;p&gt;Your content here&lt;/p&gt;\");\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"empty\">Empty</h3>\n            <p>\n                You can empty the content of the editor.\n            </p>\n            <pre><code class=\"javascript\">\n$('#editor').trumbowyg('empty');\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.1.0\">\n            <h3 id=\"enable-disable-edition\">Enable/disable edition</h3>\n            <p class=\"added-feature\">Added in 2.1.0</p>\n            <p>\n                As you can disable editor by using <a href=\"#disabled\">disabled</a> option, you can also switch between\n                enabled and disabled states by using API.\n            </p>\n            <pre><code class=\"javascript\">\n$('#editor').trumbowyg('disable');\n$('#editor').trumbowyg('enable');\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"2.9.0\">\n            <h3 id=\"toggle\">Toggle between HTML & WYSIWYG modes</h3>\n            <p class=\"added-feature\">Added in 2.9.0</p>\n            <p>\n                You can switch between HTML view and WYSIWYG view via toggle method.\n            </p>\n            <pre><code class=\"javascript\">\n$('#editor').trumbowyg('toggle');\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.0.0\">\n            <h3 id=\"destroy-editor\">Destroy editor</h3>\n            <p>\n                When you wish, you can restore the previous state of the element was used to create the editor.\n            </p>\n            <pre><code class=\"javascript\">\n$('#editor').trumbowyg('destroy');\n            </code></pre>\n        </div>\n\n\n        <div class=\"feature\" data-added=\"1.1.0\">\n            <h3 id=\"events\">Events</h3>\n            <p>\n                Some events are fired on the jQuery element which is used to build the editor.\n            </p>\n            <ul>\n                <li>Focus on editor: <code>tbwfocus</code></li>\n                <li>Blur on editor: <code>tbwblur</code></li>\n                <li>Editor is initialized: <code>tbwinit</code> <span class=\"version-tag\">2.0.0</span></li>\n                <li>Change in editor: <code>tbwchange</code> <span class=\"version-tag\">2.0.0</span></li>\n                <li>Resize the editor on autogrow: <code>tbwresize</code> <span class=\"version-tag\">2.0.0</span></li>\n                <li>Paste something in the editor: <code>tbwpaste</code> <span class=\"version-tag\">2.0.0</span></li>\n                <li>Switch to fullscreen mode: <code>tbwopenfullscreen</code> <span class=\"version-tag\">2.0.0</span>\n                </li>\n                <li>Leave editor's fullscreen mode: <code>tbwclosefullscreen</code> <span\n                        class=\"version-tag\">2.0.0</span></li>\n                <li>Close the editor: <code>tbwclose</code> <span class=\"version-tag\">2.0.0</span></li>\n                <li>Modal open: <code>tbwmodalopen</code> <span class=\"version-tag\">2.20.0</span></li>\n                <li>Modal close: <code>tbwmodalclose</code> <span class=\"version-tag\">2.20.0</span></li>\n            </ul>\n            <pre><code class=\"javascript\">\n$('#editor')\n.trumbowyg() // Build Trumbowyg on the #editor element\n.on('tbwfocus', function(){ console.log('Focus!'); }); // Listen for `tbwfocus` event\n.on('tbwblur', function(){ console.log('Blur!'); }); // Listen for `tbwblur` event\n            </code></pre>\n        </div>\n    </section>\n</main>\n\n\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<script src=\"../js/vendor/highlight.js\"></script>\n<script src=\"../js/main.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/documentation/plugins/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <title>Plugins | Trumbowyg: A lightweight WYSIWYG editor | Alex-D / Alexandre Demode</title>\n    <meta name=\"description\" content=\"Trumbowyg is a jQuery plugin for create WYSIWYG editor\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <link rel=\"icon\" type=\"image/png\" href=\"../../favicon.png\">\n\n    <link rel=\"stylesheet\" href=\"../../css/main.css\">\n</head>\n<body class=\"documentation-body\">\n<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"overflow: hidden;visibility: hidden;height: 0;width: 0;\">\n    <symbol id=\"trumbowyg-link\" viewBox=\"0 0 72 72\">\n        <path d=\"M30.9 49.1l-6.7 6.7c-.8.8-1.6.9-2.1.9s-1.4-.1-2.1-.9l-5.2-5.2c-1.1-1.1-1.1-3.1 0-4.2l6.1-6.1.2-.2 6.5-6.5c-1.2-.6-2.5-.9-3.8-.9-2.3 0-4.6.9-6.3 2.6L10.8 42c-3.5 3.5-3.5 9.2 0 12.7l5.2 5.2c1.7 1.7 4 2.6 6.3 2.6s4.6-.9 6.3-2.6l6.7-6.7C38 50.5 38.6 46.3 37 43l-6.1 6.1zM38.5 22.7l6.7-6.7c.8-.8 1.6-.9 2.1-.9s1.4.1 2.1.9l5.2 5.2c1.1 1.1 1.1 3.1 0 4.2l-6.1 6.1-.2.2-6.5 6.5c1.2.6 2.5.9 3.8.9 2.3 0 4.6-.9 6.3-2.6l6.7-6.7c3.5-3.5 3.5-9.2 0-12.7l-5.2-5.2c-1.7-1.7-4-2.6-6.3-2.6s-4.6.9-6.3 2.6l-6.7 6.7c-2.7 2.7-3.3 6.9-1.7 10.2l6.1-6.1z\"></path>\n        <path d=\"M44.1 30.7c.2-.2.4-.6.4-.9 0-.3-.1-.6-.4-.9l-2.3-2.3c-.2-.2-.6-.4-.9-.4-.3 0-.6.1-.9.4L25.8 40.8c-.2.2-.4.6-.4.9 0 .3.1.6.4.9l2.3 2.3c.2.2.6.4.9.4.3 0 .6-.1.9-.4l14.2-14.2z\"></path>\n    </symbol>\n</svg>\n<div class=\"sidebar\">\n    <div class=\"sidebar-inner\">\n        <header class=\"header-documentation\">\n            <a href=\"../../\" class=\"documentation-logo-link\">\n                <img src=\"../../img/logo-doc.svg\" alt=\"\" class=\"documentation-logo\">\n            </a>\n            <h1 class=\"documentation-title\">\n                Plugins\n            </h1>\n            <nav class=\"documentation-menu\">\n                <a href=\"../\">Docs</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"./\">Plugins</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"../core/\">Core</a><span class=\"documentation-menu-dot\"> &bull;</span>\n                <a href=\"../../demos/\">Demos</a>\n            </nav>\n        </header>\n\n        <aside class=\"documentation-summary\">\n            <ul>\n                <li>\n                    <a href=\"#existing-plugins\">Existing plugins</a>\n                    <ul>\n                        <li><a href=\"#plugin-allowtagsfrompaste\">Allow tags from paste</a></li>\n                        <li><a href=\"#plugin-base64\">Base 64</a></li>\n                        <li><a href=\"#plugin-cleanpaste\">Clean paste</a></li>\n                        <li><a href=\"#plugin-colors\">Colors</a></li>\n                        <li><a href=\"#plugin-emoji\">Emoji</a></li>\n                        <li><a href=\"#plugin-fontfamily\">Font family</a></li>\n                        <li><a href=\"#plugin-fontsize\">Font size</a></li>\n                        <li><a href=\"#plugin-giphy\">Giphy</a></li>\n                        <li><a href=\"#plugin-highlight\">Highlight</a></li>\n                        <li><a href=\"#plugin-history\">History</a></li>\n                        <li><a href=\"#plugin-indent\">Indent</a></li>\n                        <li><a href=\"#plugin-insertaudio\">Insert audio</a></li>\n                        <li><a href=\"#plugin-lineheight\">Line height</a></li>\n                        <li><a href=\"#plugin-mathml\">MathML</a></li>\n                        <li><a href=\"#plugin-mention\">Mention</a></li>\n                        <li><a href=\"#plugin-noembed\">Noembed</a></li>\n                        <li><a href=\"#plugin-pasteembed\">Paste embed</a></li>\n                        <li><a href=\"#plugin-pasteimage\">Paste image</a></li>\n                        <li><a href=\"#plugin-preformatted\">Preformatted</a></li>\n                        <li><a href=\"#plugin-resizimg\">Resizimg</a></li>\n                        <li><a href=\"#plugin-ruby\">Ruby</a></li>\n                        <li><a href=\"#plugin-specialchars\">Special Chars</a></li>\n                        <li><a href=\"#plugin-speechrecognition\">Speech recognition</a></li>\n                        <li><a href=\"#plugin-table\">Table</a></li>\n                        <li><a href=\"#plugin-template\">Template</a></li>\n                        <li><a href=\"#plugin-tenor\">Tenor</a></li>\n                        <li><a href=\"#plugin-upload\">Upload</a></li>\n                    </ul>\n                </li>\n                <li>\n                    <a href=\"#create-your-own\">Create your own</a>\n                    <ul>\n                        <li><a href=\"#introduction\">Introduction</a></li>\n                        <li><a href=\"#skeleton\">Skeleton</a></li>\n                        <li><a href=\"#interact-with-content\">Interact with content</a></li>\n                    </ul>\n                </li>\n            </ul>\n        </aside>\n\n        <div class=\"documentation-sidebar-beer\">\n            <a href=\"../../#donate\">\n                <img src=\"../../img/beer.svg\" alt=\"\" class=\"beer-icon\">\n                <span class=\"beer-label\">\n                    Do you enjoy Trumbowyg? <br>\n                    Buy me some beers :)\n                </span>\n            </a>\n        </div>\n    </div>\n</div>\n\n<main class=\"main\">\n    <section id=\"existing-plugins\" class=\"wrapper section\">\n        <h2 class=\"section-title\">Existing plugins</h2>\n        <p>\n            If you want to add a plugin, be sure to read the\n            <a href=\"../#use-plugins\">use plugins section of documentation</a> before continue.\n        </p>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-allowtagsfrompaste\">Allow tags from paste</h3>\n\n            <p>\n                Allow tags from paste plugin allows you to filter tags allowed when an user paste some code into the editor.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-allowtagsfrompaste\" class=\"button button-demo\">Try allow tags from paste live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/allowtagsfrompaste/trumbowyg.allowtagsfrompaste.js\" class=\"button button-demo\">\n                    View allow tags from paste plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/allowtagsfrompaste/trumbowyg.allowtagsfrompaste.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can configure your custom tag whitelist. Any tag pasted which is not in\n                <code>allowedTags</code> list will be unwrap, only the text will be kept.\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    plugins: {\n        allowTagsFromPaste: {\n            allowedTags: ['h4', 'p', 'br']\n        }\n    }\n});\n            </code></pre>\n\n            <p class=\"note\">\n                Enabling this plugin will force disable the <code>removeformatPasted</code> core option (set it to <code>false</code>).\n            </p>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-base64\">Base 64</h3>\n\n            <p>\n                Base 64 plugin allows you to insert images inline as base64.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-base64\" class=\"button button-demo\">Try base64 live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/base64/trumbowyg.base64.js\" class=\"button button-demo\">\n                    View base64 plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/base64/trumbowyg.base64.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>base64</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['base64']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-cleanpaste\">Clean paste</h3>\n\n            <p>\n                Clean paste plugin handle paste events, clean the HTML code before insert content into the editor.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-cleanpaste\" class=\"button button-demo\">Try cleanpaste live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/cleanpaste/trumbowyg.cleanpaste.js\" class=\"button button-demo\">\n                    View cleanpaste plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/cleanpaste/trumbowyg.cleanpaste.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Clean paste works now on every new Trumbowyg instance.\n            </p>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-colors\">Colors</h3>\n\n            <p>\n                Colors plugin allows you to change foreground and background color of your text.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-colors\" class=\"button button-demo\">Try colors live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/colors/trumbowyg.colors.js\" class=\"button button-demo\">\n                    View colors plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg colors style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/plugins/colors/ui/trumbowyg.colors.min.css\">\n            </code></pre>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg colors JS at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/colors/trumbowyg.colors.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definitions <code>foreColor</code> and <code>backColor</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['foreColor', 'backColor']\n    ]\n});\n            </code></pre>\n\n            <h4>Options</h4>\n            <dl>\n                <dt><strong><code>colorList</code></strong> <code class=\"type\">array&lt;string&gt;</code></dt>\n                <dd>\n                    List of colors available for both <code>foreColor</code> and <code>backColor</code> dropdowns.\n                    <br>\n                    <strong>Default</strong>:\n                    <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/colors/trumbowyg.colors.js\">check the code</a>\n                    or\n                    <a href=\"../../demos/#plugins-colors\">the demo</a>\n                </dd>\n                <dt><strong><code>foreColorList</code></strong> <code class=\"type\">array&lt;string&gt;</code></dt>\n                <dd>\n                    List of colors available used in the <code>foreColor</code> dropdown instead of <code>colorList</code>'s one.\n                    <br>\n                    <strong>Default</strong>: fallbacks on <code>colorList</code>\n                </dd>\n                <dt><strong><code>allowCustomForeColor</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Allow user to pick a color outside the list.\n                    <br>\n                    <strong>Default</strong>: <code>true</code>\n                </dd>\n                <dt><strong><code>backColorList</code></strong> <code class=\"type\">array&lt;string&gt;</code></dt>\n                <dd>\n                    List of colors available used in the <code>backColor</code> dropdown instead of <code>colorList</code>'s one.\n                    <br>\n                    <strong>Default</strong>: fallbacks on <code>colorList</code>\n                </dd>\n                <dt><strong><code>allowCustomBackColor</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Allow user to pick a color outside the list.\n                    <br>\n                    <strong>Default</strong>: <code>true</code>\n                </dd>\n                <dt><strong><code>displayAsList</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Switch from square to labelled list view. Default view is the square's one.\n                    <br>\n                    <strong>Default</strong>: <code>false</code>\n                </dd>\n            </dl>\n\n            <p>\n                Example with <code>colorList</code> parameter:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['foreColor', 'backColor']\n    ],\n    plugins: {\n        colors: {\n            colorList: [\n                '000', '111', '222', 'ffea00'\n            ]\n        }\n    }\n});\n            </code></pre>\n\n            <p>\n                Example with both <code>foreColorList</code> and <code>backColorList</code>, displayed as list:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['foreColor', 'backColor']\n    ],\n    plugins: {\n        colors: {\n            foreColorList: [\n                'ff0000', '00ff00', '0000ff'\n            ],\n            backColorList: [\n                '000', '333', '555'\n            ],\n            displayAsList: true\n        }\n    }\n});\n            </code></pre>\n\n            <p class=\"note\">\n                If both <code>foreColorList</code> and <code>backColorList</code> are set, <code>colorList</code> will be not used at all.\n            </p>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-emoji\">Emoji</h3>\n\n            <p>\n                Emoji plugin allows you to insert some emojis in your editor.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-emoji\" class=\"button button-demo\">Try emoji live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/emoji/trumbowyg.emoji.js\" class=\"button button-demo\">\n                    View emoji plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg emoji style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/plugins/emoji/ui/trumbowyg.emoji.min.css\">\n            </code></pre>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg emoji at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/emoji/trumbowyg.emoji.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>emoji</code>\n            </p>\n\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['emoji']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-fontfamily\">Font family</h3>\n\n            <p>\n                This plugin allows user to custom font family.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-fontfamily\" class=\"button button-demo\">Try font family live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/fontfamily/trumbowyg.fontfamily.js\" class=\"button button-demo\">\n                    View font family plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg fontfamily JS at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/fontfamily/trumbowyg.fontfamily.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>fontfamily</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['fontfamily']\n    ]\n});\n            </code></pre>\n            <p>\n                You can also choose custom font list:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['fontfamily']\n    ],\n    plugins: {\n        fontfamily: {\n            fontList: [\n                {name: 'Arial', family: 'Arial, Helvetica, sans-serif'},\n                {name: 'Open Sans', family: '\\'Open Sans\\', sans-serif'}\n            ]\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-fontsize\">Font size</h3>\n\n            <p>\n                This plugin allows user to custom font size.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-fontsize\" class=\"button button-demo\">Try font size live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/fontsize/trumbowyg.fontsize.js\" class=\"button button-demo\">\n                    View font size plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg font size JS at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/fontsize/trumbowyg.fontsize.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>fontsize</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['fontsize']\n    ]\n});\n            </code></pre>\n            <p>\n                You can also choose custom size list:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['fontsize']\n    ],\n    plugins: {\n        fontsize: {\n            sizeList: [\n                '12px',\n                '14px',\n                '16px'\n            ]\n        }\n    }\n});\n            </code></pre>\n            <p>\n                If you want to disable the custom font size option, use the <code>allowCustomSize</code> option:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['fontsize']\n    ],\n    plugins: {\n        fontsize: {\n            allowCustomSize: false\n        }\n    }\n});\n            </code></pre>\n            <p class=\"note\">\n                Default <code>allowCustomSize</code> value is <code>true</code>.\n            </p>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-giphy\">Giphy</h3>\n\n            <p>\n                User can search and pick gif to insert from Giphy\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-giphy\" class=\"button button-demo\">Try Giphy plugin live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/giphy/trumbowyg.giphy.js\" class=\"button button-demo\">\n                    View Giphy plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg Giphy style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/plugins/giphy/ui/trumbowyg.giphy.min.css\">\n            </code></pre>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg Giphy JS at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/giphy/trumbowyg.giphy.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then, you need to <a href=\"https://developers.giphy.com/dashboard/?create=true\">create a Giphy App to get an API Key</a>.\n            </p>\n            <p>\n                Use the new button definition <code>giphy</code> and your newly created Giphy API Key:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['giphy']\n    ],\n    plugins: {\n        giphy: {\n            apiKey: 'yourVeryOwnApiKey'\n        }\n    }\n});\n            </code></pre>\n\n\n            <h4>Options</h4>\n            <dl>\n                <dt><strong><code>apiKey</code></strong> <code class=\"type\">string</code> <strong>(required)</strong></dt>\n                <dd>\n                    Giphy API Key of your application.\n                    <a href=\"https://developers.giphy.com/dashboard/?create=true\">Create a Giphy App to get an API Key</a>.\n                </dd>\n                <dt><strong><code>rating</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    Giphy image rating filter.\n                    <a href=\"https://developers.giphy.com/docs/optional-settings/#rating\">See Giphy documentation for allowed rating value details</a>.\n                    <br>\n                    <strong>Default</strong>: <code>g</code>\n                </dd>\n                <dt><strong><code>throttleDelay</code></strong> <code class=\"type\">number</code> (in milliseconds)</dt>\n                <dd>\n                    It's the delay between each Giphy API requests while user is typing his query.\n                    <br>\n                    <strong>Default</strong>: <code>300</code>\n                </dd>\n                <dt><strong><code>limit</code></strong> <code class=\"type\">number</code></dt>\n                <dd>\n                    Number of images shown in result list.\n                    <br>\n                    <strong>Default</strong>: <code>50</code>\n                </dd>\n                <dt><strong><code>noResultGifUrl</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    The image URL shown when there is no result.\n                    <br>\n                    <strong>Default</strong>: <a href=\"https://media.giphy.com/media/2Faz9FbRzmwxY0pZS/giphy.gif\" rel=\"noreferrer noopener\"><code>https://media.giphy.com/media/2Faz9FbRzmwxY0pZS/giphy.gif</code></a>\n                </dd>\n            </dl>\n\n            <p>\n                Example with options:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['giphy']\n    ],\n    plugins: {\n        giphy: {\n            apiKey: 'yourVeryOwnApiKey',\n            rating: 'pg',\n            throttleDelay: 500,\n            noResultGifUrl: 'http://example.com/yourimage.gif'\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-highlight\">Code Highlight</h3>\n\n            <p>\n                This plugin allows user to add code highlight parts.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-highlight\" class=\"button button-demo\">Try highlight plugin live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/highlight/trumbowyg.highlight.js\" class=\"button button-demo\">\n                    View highlight plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <p>\n                This plugin require <strong>Prism</strong> which can be installed with:\n                <code>npm&nbsp;install&nbsp;prismjs</code>\n            </p>\n            <pre><code class=\"html\">\n&lt;!-- Import prismjs style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"node_modules/prismjs/themes/prism.css\">\n&lt;!-- Import highlight plugin style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/plugins/highlight/ui/trumbowyg.highlight.min.css\">\n&lt;!-- Import prismjs and Trumbowyg highlight at the end of &lt;body>... -->\n&lt;script src=\"node_modules/prismjs/prism.js\">&lt;/script>\n&lt;script src=\"trumbowyg/dist/plugins/highlight/trumbowyg.highlight.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                You also can add another prism language syntaxes for example:\n            </p>\n            <pre><code class=\"html\">\n&lt;!-- Import prismjs and Trumbowyg highlight at the end of &lt;body>... -->\n&lt;script src=\"node_modules/prismjs/prism.js\">&lt;/script>\n&lt;script src=\"node_modules/prismjs/components/prism-csharp.js\">&lt;/script>\n&lt;script src=\"node_modules/prismjs/components/prism-go.js\">&lt;/script>\n&lt;script src=\"node_modules/prismjs/components/prism-markdown.js\">&lt;/script>\n&lt;script src=\"trumbowyg/dist/plugins/highlight/trumbowyg.highlight.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Also on your website you must connect prismjs styles to lighting code worked. For example connect prism.css in head:\n            </p>\n            <pre><code class=\"html\">\n&lt;!-- Import prismjs style in &lt;head>... on your site -->\n&lt;link rel=\"stylesheet\" href=\"node_modules/prismjs/themes/prism.css\">\n            </code></pre>\n\n\n            <h4>Options</h4>\n            <dl>\n                <dt><strong><code>enableLineHighlight</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Add a field to highlight some lines if enabled. <br>\n                    You need to import the\n                    <a href=\"https://prismjs.com/plugins/line-highlight/\">Prism Line Highlight plugin</a> JS + CSS.\n                    <br>\n                    <strong>Default</strong>: <code>true</code>\n                </dd>\n\n                <dt><strong><code>languageNames</code></strong> <code class=\"type\">Object&lt;string, string></code></dt>\n                <dd>\n                    Pairs with language code as key and language name as value.\n                    <br>\n                    <strong>Default</strong>:\n                    <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/highlight/trumbowyg.highlight.js\">\n                        List of all languages available in Prism\n                    </a>\n                </dd>\n            </dl>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-history\">History</h3>\n\n            <p>\n                History plugin is an enhanced implementation of the undo and redo functionality.\n                It tracks changes of the editor and will add each change to a history stack.\n                If a word is typed in or text was pasted, it counts as a single stack entry.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-history\" class=\"button button-demo\">Try history plugin live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/history/trumbowyg.history.js\" class=\"button button-demo\">\n                    View history plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg history JS at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/history/trumbowyg.history.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definitions <code>historyUndo</code> and <code>historyRedo</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['historyUndo', 'historyRedo']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-indent\">Indent</h3>\n\n            <p>\n                This plugin allows you to indent or outdent your text.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-indent\" class=\"button button-demo\">Try indent live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/indent/trumbowyg.indent.js\" class=\"button button-demo\">\n                    View indent plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg indent at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/indent/trumbowyg.indent.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the news buttons definition <code>indent</code> or <code>outdent</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['indent', 'outdent']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-insertaudio\">Insert audio</h3>\n\n            <p>\n                Do the same as insert image, but for audio.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-insertaudio\" class=\"button button-demo\">Try insert audio live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/insertaudio/trumbowyg.insertaudio.js\" class=\"button button-demo\">\n                    View insertAudio plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg insertAudio at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/insertaudio/trumbowyg.insertaudio.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>insertAudio</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['insertAudio']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-lineheight\">Line height</h3>\n\n            <p>\n                This plugin allows user to custom line height.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-lineheight\" class=\"button button-demo\">Try line height live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/lineheight/trumbowyg.lineheight.js\" class=\"button button-demo\">\n                    View line height plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg lineheight at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/lineheight/trumbowyg.lineheight.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>lineheight</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['lineheight']\n    ]\n});\n            </code></pre>\n            <p>\n                You can also choose custom size list:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['lineheight']\n    ],\n    plugins: {\n        fontsize: {\n            sizeList: [\n                '12px',\n                '14px',\n                '16px'\n            ]\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-mathml\">MathML</h3>\n\n            <p>\n                This plugin allows user to use MathML.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-mathml\" class=\"button button-demo\">Try MathML live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/mathml/trumbowyg.mathml.js\" class=\"button button-demo\">\n                    View MathML plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg MathML style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/plugins/mathml/ui/trumbowyg.mathml.min.css\">\n            </code></pre>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg MathJax at the end of &lt;body>... -->\n&lt;script src=\"//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML\">&lt;/script>\n&lt;!-- Import Trumbowyg MathML plugin at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/mathml/trumbowyg.mathml.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>mathml</code>\n            </p>\n            <pre><code class=\"javascript\">\n// MathJax inline configuration\nMathJax.Hub.Config({\n    tex2jax: {\n        inlineMath: [\n            ['$', '$'],\n            ['\\\\(', '\\\\)']\n        ]\n    }\n});\n\n// Trumbowyg initialization with MathML button\n$('#editor')\n.trumbowyg({\n    btns: [\n        'mathml'\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-mention\">Mention</h3>\n\n            <p>\n                This plugin allows to mention an user from a source list.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-mention\" class=\"button button-demo\">Try mention live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/mention/trumbowyg.mention.js\" class=\"button button-demo\">\n                    View mention plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/mention/trumbowyg.mention.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>mention</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['mention']\n    ],\n    plugins: {\n        mention: {\n            source: [\n                {login: 'lucy'},\n                {login: 'jdoe'},\n                {login: 'mlisa'},\n                {login: 'jcesar'},\n            ]\n        }\n    }\n});\n            </code></pre>\n\n            <h4>Options</h4>\n            <dl>\n                <dt><strong><code>source</code></strong> <code class=\"type\">array&lt;object&gt;</code></dt>\n                <dd>\n                    List of mentionable users.\n                    Must contains <code>login</code> key if you do not override two other options.\n                    <br>\n                    <strong>Default</strong>: <code>[]</code>\n                </dd>\n                <dt><strong><code>formatDropdownItem</code></strong> <code class=\"type\">function</code></dt>\n                <dd>\n                    Custom format items in mention dropdown: <code>function (item) {}</code>. Must return a string.\n                    <br>\n                    <strong>Default output</strong>: <code>item.login</code>\n                </dd>\n                <dt><strong><code>formatResult</code></strong> <code class=\"type\">function</code></dt>\n                <dd>\n                    The string which will be inserted in editor: <code>function (item) {}</code>. Must return a string.\n                    <br>\n                    <strong>Default output</strong>: <code>'@' + item.login + ' '</code>\n                </dd>\n            </dl>\n\n            <p>\n                Example with options:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['mention']\n    ],\n    plugins: {\n        mention: {\n            source: [\n                {login: 'lucy', name: 'Lucy'},\n                {login: 'jdoe', name: 'John Doe'},\n                {login: 'mlisa', name: 'Mona Lisa'},\n                {login: 'jcesar', name: 'Julius Cesarius'},\n            ],\n            formatDropdownItem: function (item) {\n                return item.name + ' (' + item.login + ')';\n            },\n            formatResult: function (item) {\n                return '@\"' + item.name + '\" ';\n            }\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-noembed\">Noembed</h3>\n\n            <p>\n                Allows you to embed any content from a link using <a href=\"https://noembed.com/\">noembed.com</a> API.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-noembed\" class=\"button button-demo\">Try noembed live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/noembed/trumbowyg.noembed.js\" class=\"button button-demo\">\n                    View noembed plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/noembed/trumbowyg.noembed.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>noembed</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['noembed']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-pasteembed\">Paste embed</h3>\n\n            <p>\n                Paste embed plugin handles paste events. It looks for paste event, checks if it's a URL and uses noembed.com API to retrieve an iframe from that URL. If it can't retrieve an iframe, it will put an anchor tag around the URL. It doesn't do anything on text or HTML paste.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-pasteembed\" class=\"button button-demo\">Try paste embed live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/pasteembed/trumbowyg.pasteembed.js\" class=\"button button-demo\">\n                    View pasteembed plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/pasteembed/trumbowyg.pasteembed.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Paste embed now works on every new Trumbowyg instance.\n            </p>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-pasteimage\">Paste image</h3>\n\n            <p>\n                Paste image plugin handle paste events, check if you have image files in your clipboard, then paste them\n                into the editor as base64. It do nothing on text or HTML paste.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-pasteimage\" class=\"button button-demo\">Try paste image live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/pasteimage/trumbowyg.pasteimage.js\" class=\"button button-demo\">\n                    View paste image plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/pasteimage/trumbowyg.pasteimage.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Paste image works now on every new Trumbowyg instance.\n            </p>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-preformatted\">Preformatted</h3>\n\n            <p>\n                Wraps your code with <code>&lt;pre></code> tags.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-preformatted\" class=\"button button-demo\">Try preformatted live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/preformatted/trumbowyg.preformatted.js\" class=\"button button-demo\">\n                    View preformatted plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/preformatted/trumbowyg.preformatted.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>preformatted</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['preformatted']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-resizimg\">Resizimg</h3>\n\n            <p>\n                Allows you to resize images (preserving aspect ratio) by dragging their bottom-right corner.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-resizimg\" class=\"button button-demo\">Try resizimg live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/resizimg/trumbowyg.resizimg.js\" class=\"button button-demo\">\n                    View resizimg plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>Dependencies</h4>\n            <p>\n                This plugin depends on the\n                <a href=\"https://github.com/RickStrahl/jquery-resizable\" target=\"_blank\">jquery-resizable</a> plugin,\n                which must be loaded beforehand.\n            </p>\n            <p>\n                If in your project use the JQuery UI library with resizable interaction you need to include this\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/resizimg/resolveconflict-resizable.js\">script</a> to avoid issue before load jquery-resizable.\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import dependency for Resizimg (tested with version 0.35). For a production setup, follow install instructions here: https://github.com/RickStrahl/jquery-resizable -->\n&lt;script src=\"//rawcdn.githack.com/RickStrahl/jquery-resizable/0.35/dist/jquery-resizable.min.js\">&lt;/script>\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/resizimg/trumbowyg.resizimg.min.js\">&lt;/script>\n            </code></pre>\n\n            <h4>Options</h4>\n            <dl>\n                <dt><strong><code>minSize</code></strong> <code class=\"type\">number</code></dt>\n                <dd>\n                    Minimal size of image and also of draggable right-bottom corner.\n                    <br>\n                    <strong>Default</strong>: <code>32</code>\n                </dd>\n                <dt><strong><code>step</code></strong> <code class=\"type\">number</code></dt>\n                <dd>\n                    Increment when increasing / decreasing image height.\n                    <br>\n                    <strong>Default</strong>: <code>4</code>\n                </dd>\n            </dl>\n            <p>\n                Example with options:\n            </p>\n            <pre><code class=\"javascript\">\n$('#editor').trumbowyg({\n    plugins: {\n        resizimg: {\n            minSize: 64,\n            step: 16,\n        }\n    }\n});\n            </code></pre>\n\n            <p class=\"note\">\n                The resulting image size is currently absolute: CSS height in pixels (<code>style</code> attribute).\n            </p>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-ruby\">Ruby</h3>\n\n            <p>\n                Allows you to support <a href=\"https://www.w3.org/International/articles/ruby/\">ruby markup</a>.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-ruby\" class=\"button button-demo\">Try ruby live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/ruby/trumbowyg.ruby.js\" class=\"button button-demo\">\n                    View ruby plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg ruby style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/plugins/ruby/ui/trumbowyg.ruby.min.css\">\n            </code></pre>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg ruby at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/ruby/trumbowyg.ruby.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>ruby</code>\n            </p>\n\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['specialChars']\n    ]\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-specialchars\">Special Chars</h3>\n\n            <p>\n                Special Chars plugin allows you to insert some special characters in your editor.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-specialchars\" class=\"button button-demo\">Try special chars live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/specialchars/trumbowyg.specialchars.js\" class=\"button button-demo\">\n                    View specialChars plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg specialchars style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/plugins/specialchars/ui/trumbowyg.specialchars.min.css\">\n            </code></pre>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg specialchars at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/specialchars/trumbowyg.specialchars.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>specialchars</code>\n            </p>\n\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['specialChars']\n    ]\n});\n            </code></pre>\n\n            <h4>Options</h4>\n            <dl>\n                <dt><strong><code>symbolList</code></strong> <code class=\"type\">array&lt;string&gt;</code></dt>\n                <dd>\n                    List of special chars displayed in the dropdown. <br>\n                    To force next char to be on a new line in dropdown, add a <code>null</code> entry.\n                    <br>\n                    <strong>Default</strong>: <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/specialchars/trumbowyg.specialchars.js\">check in the code</a>.\n                </dd>\n            </dl>\n\n            <p>\n                Example with options:\n            </p>\n            <pre><code class=\"javascript\">\n$('#editor-custom-list')\n.trumbowyg({\n    btns: [\n        ['specialChars']\n    ],\n    plugins: {\n        specialchars: {\n            symbolList: [\n                '00A2', '00A5', '00A4', '2030',  null,\n                '00A9', '00AE',  '2122',  null,\n                '2023', '25B6', '2B29', '25C6', null,\n                '2211', '2243', '2264', '2265'\n            ]\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-speechrecognition\">Speech recogintion</h3>\n\n            <p>\n                Speech recognition plugin allows you to add text via speech.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-speechrecognition\" class=\"button button-demo\">Try speech recognition live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/speechrecognition/trumbowyg.speechrecognition.js\" class=\"button button-demo\">\n                    View speech recognition plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg speech recognition at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/speechrecognition/trumbowyg.speechrecognition.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>speechrecognition</code>.\n            </p>\n\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['speechrecognition']\n    ]\n});\n            </code></pre>\n\n            <h4>Options</h4>\n            <dl>\n                <dt><strong><code>lang</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    Language code which language should be detected.\n                    <br>\n                    <strong>Default</strong>: en_GB\n                </dd>\n            </dl>\n\n            <p>\n                Example with options:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor)\n.trumbowyg({\n    btns: [\n        ['speechrecognition']\n    ],\n    plugins: {\n        speechrecognition: {\n            lang: 'de-DE'\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-table\">Table</h3>\n\n            <p>\n                Table plugin allows users to create and manage tables.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-table\" class=\"button button-demo\">Try table live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/table/trumbowyg.table.js\" class=\"button button-demo\">\n                    View table plugin code on GitHub\n                </a>\n            </p>\n\n            <ul>\n                <li><a href=\"#plugin-table--how-to-use-it\">How to use it?</a></li>\n                <li><a href=\"#plugin-table--options\">Options</a></li>\n                <li><a href=\"#plugin-table--buttons\">Buttons</a></li>\n            </ul>\n\n            <h4 id=\"plugin-table--how-to-use-it\">How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg Table style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/plugins/table/ui/trumbowyg.table.min.css\">\n            </code></pre>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/table/trumbowyg.table.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>table</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['table', 'tableCellBackgroundColor', 'tableBorderColor']\n    ],\n    plugins: {\n        table: {\n            // Some table plugin options, see details below\n        }\n    }\n});\n            </code></pre>\n            <p>\n                To get a good UX, you need to have some CSS defined on your tables.\n                A good start can be something to guarantee that cell width and height\n                will not collapse, and allow to click inside. Also, ensure you have some borders\n                to distinguish cells. Here is a minimal example using CSS custom properties:\n            </p>\n            <pre><code class=\"css\">\n:root {\n    --tbw-cell-vertical-padding: 4px;\n    --tbw-cell-horizontal-padding: 8px;\n    --tbw-cell-line-height: 1.5em;\n}\n\ntable {\n    margin-bottom: var(--tbw-cell-line-height);\n}\n\nth,\ntd {\n    height: calc(var(--tbw-cell-vertical-padding) * 2 + var(--tbw-cell-line-height));\n    min-width: calc(var(--tbw-cell-horizontal-padding) * 2);\n    padding: var(--tbw-cell-vertical-padding) var(--tbw-cell-horizontal-padding);\n    border: 1px solid #e7eaec;\n}\n            </code></pre>\n\n            <h4 id=\"plugin-table--options\">Options</h4>\n            <dl>\n                <dt><strong><code>rows</code></strong> <code class=\"type\">number</code></dt>\n                <dd>\n                    The count of rows which should be used for table building in the table grid dropdown.\n                    <br>\n                    <strong>Default</strong>: <code>8</code>\n                </dd>\n                <dt><strong><code>columns</code></strong> <code class=\"type\">number</code></dt>\n                <dd>\n                    The count of columns which should be used for table building in the table grid dropdown.\n                    <br>\n                    <strong>Default</strong>: <code>8</code>\n                </dd>\n                <dt><strong><code>allowHorizontalResize</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Enable handles to adjust columns width.\n                    <br>\n                    <strong>Default</strong>: <code>true</code>\n                </dd>\n                <dt><strong><code>colorList</code></strong> <code class=\"type\">array&lt;string&gt;</code></dt>\n                <dd>\n                    List of colors available for both <code>tableCellBackgroundColor</code> and <code>tableBorderColor</code> dropdowns.\n                    <br>\n                    <strong>Default</strong>:\n                    <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/table/trumbowyg.table.js\">check the code</a>\n                    or\n                    <a href=\"../../demos/#plugins-table\">the demo</a>\n                </dd>\n                <dt><strong><code>backgroundColorList</code></strong> <code class=\"type\">array&lt;string&gt;</code></dt>\n                <dd>\n                    List of colors available used in the <code>tableCellBackgroundColor</code> dropdown instead of <code>colorList</code>'s one.\n                    <br>\n                    <strong>Default</strong>: fallbacks on <code>colorList</code>\n                </dd>\n                <dt><strong><code>allowCustomBackgroundColor</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Allow user to pick a color outside the list for <code>tableCellBackgroundColor</code>.\n                    <br>\n                    <strong>Default</strong>: <code>true</code>\n                </dd>\n                <dt><strong><code>displayBackgroundColorsAsList</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Switch from square to labelled list view for <code>tableCellBackgroundColor</code>. Default view is the square's one.\n                    <br>\n                    <strong>Default</strong>: <code>false</code>\n                </dd>\n                <dt><strong><code>borderColorList</code></strong> <code class=\"type\">array&lt;string&gt;</code></dt>\n                <dd>\n                    List of colors available used in the <code>tableBorderColor</code> dropdown instead of <code>colorList</code>'s one.\n                    <br>\n                    <strong>Default</strong>: fallbacks on <code>colorList</code>\n                </dd>\n                <dt><strong><code>allowCustomBorderColor</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Allow user to pick a color outside the list for <code>tableBorderColor</code>.\n                    <br>\n                    <strong>Default</strong>: <code>true</code>\n                </dd>\n                <dt><strong><code>displayBorderColorsAsList</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Switch from square to labelled list view for <code>tableBorderColor</code>. Default view is the square's one.\n                    <br>\n                    <strong>Default</strong>: <code>false</code>\n                </dd>\n                <dt><strong><code>dropdown</code></strong> <code class=\"type\">object</code></dt>\n                <dd>\n                    Define the <code>'table'</code> dropdown buttons when selection is inside a table.\n                    <ul>\n                        <li><code>title</code>: the dropdown section title translation key.</li>\n                        <li><code>buttons</code>: button list</li>\n                    </ul>\n                    You can rearrange them and remove those you do not want. <br>\n                    <strong>Default</strong>:\n                    <pre><code>\n[\n    {\n        title: 'tableRows',\n        buttons: [\n            'tableAddHeaderRow',\n            'tableAddRowAbove',\n            'tableAddRow',\n            'tableDeleteRow',\n        ],\n    },\n    {\n        title: 'tableColumns',\n        buttons: [\n            'tableAddColumnLeft',\n            'tableAddColumn',\n            'tableDeleteColumn',\n        ],\n    },\n    {\n        title: 'tableVerticalAlign',\n        buttons: [\n            'tableVerticalAlignTop',\n            'tableVerticalAlignMiddle',\n            'tableVerticalAlignBottom',\n        ],\n    },\n    {\n        title: 'tableOthers',\n        buttons: [\n            // Cell merge/split\n            'tableMergeCells',\n            'tableUnmergeCells',\n            'tableDestroy',\n        ]\n    }\n]\n                    </code></pre>\n                </dd>\n                <dt><strong><code>styler</code></strong> <code class=\"type\">string</code> <span class=\"deprecated-feature\">Removed in 2.27.0</span></dt>\n                <dd>\n                    The class which should be assigned to each table by default\n                    <br>\n                    <strong>Default</strong>: <code>'table'</code>\n                    <p>\n                        From version 2.27, use <a href=\"../#tag-classes\">core's <code>tagClasses</code> feature</a>:\n                    </p>\n                    <pre><code class=\"diff javascript\">\n$('.trumbowyg').trumbowyg({\n-    plugins: {\n-        table: {\n-            styler: 'table',\n-        },\n-    },\n+    tagClasses: {\n+        table: 'table',\n+    },\n});\n                    </code></pre>\n                </dd>\n            </dl>\n\n            <h4 id=\"plugin-table--buttons\">Buttons</h4>\n            <p>\n                Table plugin comes with <em>a lot of buttons</em>.\n                <br>\n                You can use most of them anywhere: in the table dropdown,\n                in the button pane or in your custom dropdown.\n                <br>\n                Exceptions are: <code>table</code>,\n                <code>tableCellBackgroundColor</code> and <code>tableBorderColor</code> which can\n                only be used directly in the button pane.\n            </p>\n            <dl>\n                <dt><strong><code>table</code></strong></dt>\n                <dd>\n                    The table button comes with two different dropdowns depending on current selection:\n                    <ul>\n                        <li>If the current cursor is inside a table, the dropdown shows table actions;</li>\n                        <li>Otherwise, renders a table grid where you can build the table.</li>\n                    </ul>\n                    See the <code>dropdown</code> option details above to see all default dropdown buttons.\n                </dd>\n                <dt><strong><code>tableAddHeaderRow</code></strong></dt>\n                <dd>\n                    Add a <code>&lt;thead&gt;</code> to the table if there is no one already.\n                    <br>\n                    Can be deleted using <code>tableRemoveRow</code>.\n                </dd>\n                <dt><strong><code>tableAddRowAbove</code></strong></dt>\n                <dd>\n                    Add a row above the selected row.\n                </dd>\n                <dt><strong><code>tableAddRow</code></strong></dt>\n                <dd>\n                    Add a row under the selected row.\n                </dd>\n                <dt><strong><code>tableDeleteRow</code></strong></dt>\n                <dd>\n                    Remove selected rows.\n                </dd>\n                <dt><strong><code>tableAddColumnLeft</code></strong></dt>\n                <dd>\n                    Add a column to the left of the selected cell.\n                </dd>\n                <dt><strong><code>tableAddColumn</code></strong></dt>\n                <dd>\n                    Add a column to the right of the selected cell.\n                </dd>\n                <dt><strong><code>tableDeleteColumn</code></strong></dt>\n                <dd>\n                    Remove the selected cells columns.\n                </dd>\n                <dt><strong><code>tableVerticalAlignTop</code></strong></dt>\n                <dd>\n                    Vertically align cell text to top.\n                </dd>\n                <dt><strong><code>tableVerticalAlignMiddle</code></strong></dt>\n                <dd>\n                    Vertically align cell text to middle.\n                </dd>\n                <dt><strong><code>tableVerticalAlignBottom</code></strong></dt>\n                <dd>\n                    Vertically align cell text to bottom.\n                </dd>\n                <dt><strong><code>tableMergeCells</code></strong></dt>\n                <dd>\n                    Merge selected cells, if possible.\n                </dd>\n                <dt><strong><code>tableUnmergeCells</code></strong></dt>\n                <dd>\n                    Unmerge selected cells.\n                </dd>\n                <dt><strong><code>tableDestroy</code></strong></dt>\n                <dd>\n                    Delete the selected table.\n                </dd>\n                <dt><strong><code>tableCellBackgroundColor</code></strong></dt>\n                <dd>\n                    Allow to choose selected cells background color.\n                </dd>\n                <dt><strong><code>tableBorderColor</code></strong></dt>\n                <dd>\n                    Allow to choose table border color.\n                </dd>\n            </dl>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-template\">Template</h3>\n\n            <p>\n                Manage a set of HTML templates to insert fast.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-template\" class=\"button button-demo\">Try template live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/template/trumbowyg.template.js\" class=\"button button-demo\">\n                    View template plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/template/trumbowyg.template.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>template</code> and can add your template code.\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['template']\n    ],\n    plugins: {\n        templates: [\n            {\n                name: 'Template 1',\n                html: '&lt;p>I am a template!&lt;/p>'\n            },\n            {\n                name: 'Template 2',\n                html: '&lt;p>I am a different template!&lt;/p>'\n            }\n        ]\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-tenor\">Tenor</h3>\n\n            <p>\n                User can search and pick gif to insert from Tenor\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-tenor\" class=\"button button-demo\">Try Tenor plugin live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/giphy/trumbowyg.tenor.js\" class=\"button button-demo\">\n                    View Tenor plugin code on GitHub\n                </a>\n            </p>\n\n            <h4>How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg Tenor style in &lt;head>... -->\n&lt;link rel=\"stylesheet\" href=\"trumbowyg/dist/plugins/giphy/ui/trumbowyg.tenor.min.css\">\n            </code></pre>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg Giphy JS at the end of &lt;body>... -->\n&lt;script src=\"trumbowyg/dist/plugins/giphy/trumbowyg.tenor.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then, you need to <a href=\"https://developers.google.com/tenor/guides/quickstart#setup\">create a Tenor App to get an API Key</a>.\n            </p>\n            <p>\n                Use the new button definition <code>tenor</code> and your newly created Tenor API Key:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['tenor']\n    ],\n    plugins: {\n        tenor: {\n            apiKey: 'yourVeryOwnApiKey'\n        }\n    }\n});\n            </code></pre>\n\n\n            <h4>Options</h4>\n            <dl>\n                <dt><strong><code>apiKey</code></strong> <code class=\"type\">string</code> <strong>(required)</strong></dt>\n                <dd>\n                    Tenor API Key of your application.\n                    <a href=\"https://developers.google.com/tenor/guides/quickstart#setup\">Create a Tenor App to get an API Key</a>.\n                </dd>\n                <dt><strong><code>contentFilter</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    Specify the content safety filter level.\n                    <br>\n                    The accepted values are <code>off</code>, <code>low</code>, <code>medium</code>, and <code>high</code>.\n                    <br>\n                    <strong>Default</strong>: <code>all</code>\n                </dd>\n                <dt><strong><code>locale</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    Specify the default language to interpret the search string (xx_YY).\n                    <br>\n                    xx is the language's <a href=\"https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes\">ISO 639-1</a> language code, while the optional _YY value is the two-letter <a href=\"https://en.wikipedia.org/wiki/ISO_3166-1#Codes\">3166-1</a> country code.\n                    <br>\n                    <strong>Default</strong>: <code>en_US</code>\n                </dd>\n                <dt><strong><code>throttleDelay</code></strong> <code class=\"type\">number</code> (in milliseconds)</dt>\n                <dd>\n                    It's the delay between each Tenor API requests while user is typing his query.\n                    <br>\n                    <strong>Default</strong>: <code>300</code>\n                </dd>\n                <dt><strong><code>noResultGifUrl</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    The image URL shown when there is no result.\n                    <br>\n                    <strong>Default</strong>: <a href=\"https://media1.tenor.com/m/KOZLvzU0o4kAAAAC/no-results.gif\" rel=\"noreferrer noopener\"><code>https://media1.tenor.com/m/KOZLvzU0o4kAAAAC/no-results.gif</code></a>\n                </dd>\n            </dl>\n\n            <p>\n                Example with options:\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['tenor']\n    ],\n    plugins: {\n        giphy: {\n            apiKey: 'yourVeryOwnApiKey',\n            locale: 'en_US',\n            contentFilter: \"off\",\n            throttleDelay: 500,\n            noResultGifUrl: 'https://media1.tenor.com/m/KOZLvzU0o4kAAAAC/no-results.gif'\n        }\n    }\n});\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"plugin-upload\">Upload</h3>\n\n            <p>\n                Add an upload front-end allowing users to select an image, upload it with progress bar and then insert\n                the uploaded image in the editor.\n            </p>\n\n            <p>\n                <a href=\"../../demos/#plugins-upload\" class=\"button button-demo\">Try upload live demo!</a>\n                <a href=\"https://github.com/Alex-D/Trumbowyg/tree/develop/plugins/upload/trumbowyg.upload.js\" class=\"button button-demo\">\n                    View upload plugin code on GitHub\n                </a>\n            </p>\n\n            <ul>\n                <li><a href=\"#plugin-upload--how-to-use-it\">How to use it?</a></li>\n                <li><a href=\"#plugin-upload--options\">Options</a></li>\n                <li><a href=\"#plugin-upload--server-side\">Server side</a></li>\n            </ul>\n\n            <h4 id=\"plugin-upload--how-to-use-it\">How to use it?</h4>\n            <pre><code class=\"html\">\n&lt;!-- Import Trumbowyg plugins... -->\n&lt;script src=\"trumbowyg/dist/plugins/upload/trumbowyg.upload.min.js\">&lt;/script>\n            </code></pre>\n            <p>\n                Then you can use the new button definition <code>upload</code>\n            </p>\n            <pre><code class=\"javascript\">\n$('#my-editor').trumbowyg({\n    btns: [\n        ['upload']\n    ],\n    plugins: {\n        upload: {\n            // Some upload plugin options, see details below\n        }\n    }\n});\n            </code></pre>\n\n            <h4 id=\"plugin-upload--options\">Options</h4>\n            <dl>\n                <dt><strong><code>serverPath</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    The URL to the server which catch the upload request\n                    <br>\n                    <strong>Default</strong>: <code>''</code>\n                </dd>\n                <dt><strong><code>fileFieldName</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    The POST property key associated to the upload file\n                    <br>\n                    <strong>Default</strong>: <code>'fileToUpload'</code>\n                </dd>\n                <dt><strong><code>data</code></strong> <code class=\"type\">array&lt;Object></code></dt>\n                <dd>\n                    Additional data for ajax. <a href=\"http://api.jquery.com/jquery.ajax/\">jQuery.ajax data option</a><br>\n                    Example: <code>[{name: 'myKey1', value: 'myValue1'}, {name: 'username', value: 'myUsername'}]</code>\n                    <br>\n                    <strong>Default</strong>: <code>[]</code>\n                </dd>\n                <dt><strong><code>headers</code></strong> <code class=\"type\">Object</code></dt>\n                <dd>\n                    Additional headers. Check <a href=\"http://api.jquery.com/jquery.ajax/\">jQuery.ajax headers option</a><br>\n                    Example: <code>{headerKey: 'headerValue', Authorization: 'Client-ID xxxxxxxxx'}</code>\n                    <br>\n                    <strong>Default</strong>: <code>{}</code>\n                </dd>\n                <dt><strong><code>xhrFields</code></strong> <code class=\"type\">Object</code></dt>\n                <dd>\n                    Additional xhrFields. Check <a href=\"http://api.jquery.com/jquery.ajax/\">jQuery.ajax xhrFields option</a>\n                    <br>\n                    <strong>Default</strong>: <code>{}</code>\n                </dd>\n                <dt><strong><code>urlPropertyName</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    How to get image URL in the JSON response. <br>\n                    Example: <code>'url'</code> for <code>{url: 'https://example.com/myimage.jpg', success: true}</code>\n                    <br>\n                    <strong>Default</strong>: <code>'file'</code>\n                </dd>\n                <dt><strong><code>statusPropertyName</code></strong> <code class=\"type\">string</code></dt>\n                <dd>\n                    How to get status from the json response. <br>\n                    Example: <code>'success'</code> for <code>{success: true, url: 'https://example.com/myimage.jpg'}</code>\n                    <br>\n                    <strong>Default</strong>: <code>'success'</code>\n                </dd>\n                <dt><strong><code>success</code></strong> <code class=\"type\">function</code></dt>\n                <dd>\n                    Success callback: <code>function (data, trumbowyg, $modal, values) {}</code>\n                    <br>\n                    <strong>Default</strong>: <code>null</code>\n                </dd>\n                <dt><strong><code>error</code></strong> <code class=\"type\">function</code></dt>\n                <dd>\n                    Error callback: <code>function () {}</code>\n                    <br>\n                    <strong>Default</strong>: <code>null</code>\n                </dd>\n                <dt><strong><code>imageWidthModalEdit</code></strong> <code class=\"type\">boolean</code></dt>\n                <dd>\n                    Add a field allowing user to set image width\n                    <br>\n                    <strong>Default</strong>: <code>false</code>\n                </dd>\n            </dl>\n\n            <h4 id=\"plugin-upload--server-side\">Server side</h4>\n            <p>\n                Server side receives a POST request with the image in the <code>fileFieldName</code> field and\n                <code>alt</code> which contains image description:\n            </p>\n            <pre><code>\nalt: 'Image description'\nfileToUpload: // The image file\n            </code></pre>\n            <p>\n                It must save this image, then return a JSON response like that:\n            </p>\n            <pre><code>\n{\n    success: true, // Must be false if upload fails\n    file: 'https://example.com/myimage.jpg'\n}\n            </code></pre>\n        </div>\n    </section>\n\n\n    <section id=\"create-your-own\" class=\"wrapper section\">\n        <h2 class=\"section-title\">Create your own</h2>\n\n        <div class=\"feature\">\n            <h3 id=\"introduction\">Introduction</h3>\n\n            <p>\n                A plugin can be a button, a paste handler or whatever you want. If you want to add a plugin <em>myplugin</em>\n                to the official Trumbowyg list, you should follow this tree:\n            </p>\n            <ul class=\"tree\">\n                <li>\n                    <strong>plugins</strong>\n                    <ul>\n                        <li>\n                            <strong>myplugin</strong>\n                            <ul>\n                                <li>\n                                    <strong>ui</strong>\n                                    <ul>\n                                        <li>\n                                            <strong>icons</strong>\n                                            <ul>\n                                                <li>myplugin.svg</li>\n                                            </ul>\n                                        </li>\n                                        <li>\n                                            <strong>sass</strong>\n                                            <ul>\n                                                <li>trumbowyg.myplugin.scss</li>\n                                            </ul>\n                                        </li>\n                                    </ul>\n                                </li>\n                                <li>\n                                    trumbowyg.myplugin.js\n                                </li>\n                            </ul>\n                        </li>\n                    </ul>\n                </li>\n            </ul>\n            <p>\n                As plugin can be something other than a button, icons and scss are optional depending on your feature.\n            </p>\n            <p>\n                In a plugin, you get access to all Trumbowyg core and you can extends all things as you wish.\n            </p>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"skeleton\">Skeleton</h3>\n\n            <p>\n                To create a new plugin, you should start your <code>trumbowyg.myplugin.js</code> with this code:\n            </p>\n            <pre><code class=\"javascript\">\n(function ($) {\n    'use strict';\n\n    // Plugin default options\n    var defaultOptions = {\n    };\n\n    // If the plugin is a button\n    function buildButtonDef (trumbowyg) {\n        return {\n            fn: function () {\n                // Plugin button logic\n            }\n        }\n    }\n\n    // If the plugin is a button\n    function buildButtonIcon() {\n        if ($(\"#trumbowyg-myplugin\").length > 0) {\n            return;\n        }\n\n        /*\n        When your button is created, an SVG will be inserted with an xref to a\n        symbol living at the fragment \"#trumbowyg-myplugin\". For Trumbowyg's\n        own plugins, this will come from a sprite sheet which is injected into\n        the document, built from the icon SVG in \"ui/icons\" in your plugin's\n        source tree. This is how you should organise things if you are\n        proposing your plugin to be included in the Trumbowyg main\n        distribution, or if you are rolling your own custom build of Trumbowyg\n        for your site.\n\n        But, nothing says it *has* to come from Trumbowyg's injected sprite\n        sheet; it only requires that this symbol exists in your document. To\n        allow stand-alone distribution of your plugin, we're going to insert a\n        custom SVG symbol into the document with the correct ID.\n        */\n        const iconWrap = $(document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\"));\n        iconWrap.addClass(\"trumbowyg-icons\");\n\n        // For demonstration purposes, we've taken the \"File\" icon from\n        // Remix Icon - https://remixicon.com/\n        iconWrap.html(`\n            &lt;symbol id=\"trumbowyg-myplugin\" viewBox=\"0 0 24 24\"&gt;\n                &lt;path d=\"M21 8v12.993A1 1 0 0 1 20.007 22H3.993A.993.993 0 0 1 3 21.008V2.992C3 2.455 3.449 2 4.002 2h10.995L21 8zm-2 1h-5V4H5v16h14V9zM8 7h3v2H8V7zm0 4h8v2H8v-2zm0 4h8v2H8v-2z\"/&gt;\n            &lt;/symbol&gt;\n        `).appendTo(document.body);\n    }\n\n\n    $.extend(true, $.trumbowyg, {\n        // Add some translations\n        langs: {\n            en: {\n                myplugin: 'My plugin'\n            }\n        },\n        // Register plugin in Trumbowyg\n        plugins: {\n            myplugin: {\n                // Code called by Trumbowyg core to register the plugin\n                init: function (trumbowyg) {\n                    // Fill current Trumbowyg instance with the plugin default options\n                    trumbowyg.o.plugins.myplugin = $.extend(true, {},\n                        defaultOptions,\n                        trumbowyg.o.plugins.myplugin || {}\n                    );\n\n                    // If the plugin is a paste handler, register it\n                    trumbowyg.pasteHandlers.push(function(pasteEvent) {\n                        // My plugin paste logic\n                    });\n\n                    // If the plugin is a button\n                    buildButtonIcon();\n                    trumbowyg.addBtnDef('myplugin', buildButtonDef(trumbowyg));\n                },\n                // Return a list of button names which are active on current element\n                tagHandler: function (element, trumbowyg) {\n                    return [];\n                },\n                destroy: function (trumbowyg) {\n                }\n            }\n        }\n    })\n})(jQuery);\n            </code></pre>\n        </div>\n\n        <div class=\"feature\">\n            <h3 id=\"interact-with-content\">Interact with content</h3>\n\n            <p>\n                To interact with editor and its content, you should use Trumbowyg core API.\n                You can also check existing plugins source code to see how it works!\n            </p>\n            <p>\n                <a href=\"../core/\">Go to the core API documentation</a>\n            </p>\n        </div>\n    </section>\n</main>\n\n\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"../../js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<script src=\"../../js/vendor/highlight.js\"></script>\n<script src=\"../../js/main.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/gulpfile.mjs",
    "content": "// jshint node:true\n'use strict';\n\nimport gulp from 'gulp';\nimport gulpAutoprefixer from 'gulp-autoprefixer';\nimport gulpLivereload from 'gulp-livereload';\nimport gulpCleanCss from 'gulp-clean-css';\nimport gulpSassPlugin from 'gulp-sass';\nimport * as sass from 'sass';\nimport {deleteAsync} from 'del';\n\nconst gulpSass = () => gulpSassPlugin(sass)();\n\nconst mainStyle = 'scss/main.scss';\n\n\nconst clean = function () {\n    return deleteAsync(['dist/*']);\n};\n\n\nconst styles = function () {\n    return gulp.src(mainStyle)\n        .pipe(gulpSass({\n            sass: 'sass',\n            includePaths: ['sass']\n        }))\n        .pipe(gulpAutoprefixer(['last 1 version', '> 1%', 'ff >= 20', 'ie >= 8', 'opera >= 12', 'Android >= 2.2'], {cascade: true}))\n        .pipe(gulpCleanCss())\n        .pipe(gulp.dest('css/'));\n};\n\n\nconst watch = function () {\n    gulp.watch(['scss/*.scss'], styles);\n\n    gulp.watch(['css/**', 'img/*', 'js/*'], function (file) {\n        gulpLivereload.changed(file);\n    });\n\n    gulpLivereload.listen();\n};\n\nconst build = gulp.series(styles);\n\nconst buildAndWatch = gulp.series(build, watch);\n\nexport default buildAndWatch;\nexport {\n    clean,\n    build,\n};\n"
  },
  {
    "path": "docs/humans.txt",
    "content": "# humanstxt.org/\n# The humans responsible & technology colophon\n\n# TEAM\n\n    Alex-D -- Main developer -- @AlexandreDemode\n\n# TECHNOLOGY COLOPHON\n\n    HTML5, CSS3\n    JavaScript, jQuery\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <title>Trumbowyg - A lightweight WYSIWYG editor by Alex-D / Alexandre Demode</title>\n    <meta name=\"description\" content=\"Trumbowyg is a very small jQuery plugin for creating a powerful WYSIWYG editor\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <link rel=\"icon\" type=\"image/png\" href=\"favicon.png\">\n\n    <meta name=\"google-site-verification\" content=\"JCnDOPMjp30qGb-ab2q0YnQ99Np9wop0E3wYXKwSoOw\">\n\n    <link rel=\"stylesheet\" href=\"css/main.css\">\n    <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400\" type=\"text/css\">\n    <link rel=\"stylesheet\" href=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/ui/trumbowyg.min.css\">\n</head>\n<body>\n\n<header class=\"header header-landing\">\n    <ul class=\"header-nav\">\n        <li>\n            <a href=\"https://github.com/Alex-D/Trumbowyg\" class=\"view-on-github\">\n                <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"438.549\" height=\"438.549\" viewBox=\"0 0 438.549 438.549\">\n                    <path d=\"M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8C295.736 15.166 259.057 5.365 219.27 5.365c-39.78 0-76.47 9.804-110.062 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.853 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.42-1.996 2.474-2.282 3.71-5.14 3.71-8.562 0-.57-.05-5.708-.144-15.417-.098-9.71-.144-18.18-.144-25.406l-6.567 1.136c-4.187.767-9.47 1.092-15.846 1-6.375-.09-12.992-.757-19.843-2-6.854-1.23-13.23-4.085-19.13-8.558-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.9-9.233-8.992-14.56-4.093-5.33-8.232-8.944-12.42-10.847l-1.998-1.43c-1.332-.952-2.568-2.1-3.71-3.43-1.143-1.33-1.998-2.663-2.57-3.997-.57-1.335-.097-2.43 1.428-3.29 1.525-.858 4.28-1.275 8.28-1.275l5.708.853c3.807.763 8.516 3.042 14.133 6.85 5.615 3.807 10.23 8.755 13.847 14.843 4.38 7.807 9.657 13.755 15.846 17.848 6.184 4.093 12.42 6.136 18.7 6.136 6.28 0 11.703-.476 16.273-1.423 4.565-.95 8.848-2.382 12.847-4.284 1.713-12.758 6.377-22.56 13.988-29.41-10.847-1.14-20.6-2.857-29.263-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.98-3.9-12.373-5.852-26.647-5.852-42.825 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.38-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.284 18.794 7.953 23.84 10.995 5.046 3.04 9.09 5.618 12.135 7.708 17.706-4.947 35.977-7.42 54.82-7.42s37.116 2.473 54.822 7.42l10.85-6.85c7.418-4.57 16.18-8.757 26.26-12.564 10.09-3.806 17.803-4.854 23.135-3.14 8.562 21.51 9.325 40.923 2.28 58.24 15.035 16.18 22.558 35.788 22.558 58.818 0 16.178-1.958 30.497-5.853 42.966-3.9 12.47-8.94 22.457-15.125 29.98-6.19 7.52-13.9 13.85-23.13 18.985-9.233 5.14-18.183 8.85-26.84 11.135-8.663 2.286-18.416 4.004-29.264 5.146 9.894 8.563 14.842 22.078 14.842 40.54v60.237c0 3.422 1.19 6.28 3.572 8.562 2.38 2.278 6.136 2.95 11.276 1.994 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.16 41.826-81.126 41.826-128.906-.01-39.77-9.818-76.454-29.414-110.05z\"></path>\n                </svg>\n                View project on GitHub &mdash; <span class=\"star-count\">2700</span> <span class=\"star\">★</span>\n            </a>\n        </li>\n        <li>\n            <a href=\"http://alex-d.fr\">\n                Made by Alex-D\n            </a>\n        </li>\n        <li>\n            <a href=\"#donate\">\n                Donate\n            </a>\n        </li>\n        <li>\n            <a href=\"./documentation/plugins/\">\n                Plugins\n            </a>\n        </li>\n        <li>\n            <a href=\"./documentation/\">\n                Documentation\n            </a>\n        </li>\n    </ul>\n\n    <div class=\"header-logo-container\">\n        <h1 class=\"header-logo-h1\">\n            <img src=\"./img/logo.svg\" alt=\"Trumbowyg\" class=\"header-logo\">\n            <span class=\"header-logo-animation\">\n                <svg class=\"header-logo-animation-strong\">\n                    <use xlink:href=\"#trumbowyg-strong\"></use>\n                </svg>\n                <svg class=\"header-logo-animation-p\">\n                    <use xlink:href=\"#trumbowyg-p\"></use>\n                </svg>\n                <svg class=\"header-logo-animation-link\">\n                    <use xlink:href=\"#trumbowyg-link\"></use>\n                </svg>\n                <svg class=\"header-logo-animation-blockquote\">\n                    <use xlink:href=\"#trumbowyg-blockquote\"></use>\n                </svg>\n                <svg class=\"header-logo-animation-view-html\">\n                    <use xlink:href=\"#trumbowyg-view-html\"></use>\n                </svg>\n            </span>\n        </h1>\n    </div>\n\n    <h2 class=\"header-subtitle\">A lightweight WYSIWYG editor</h2>\n    <p class=\"header-description\">\n        Light, translatable and customisable jQuery&nbsp;plugin <br>\n        Beautiful design, generates semantic code, comes with a&nbsp;powerful&nbsp;API\n    </p>\n\n    <div class=\"header-buttons\">\n        <a href=\"./documentation/\" class=\"button button-secondary\">\n            Get started\n        </a>\n        <a href=\"./demos/\" class=\"button button-ghost\">\n            See Demos\n        </a>\n    </div>\n</header>\n\n\n<main class=\"main\">\n    <section class=\"section wrapper\" id=\"demonstration\">\n        <textarea id=\"trumbowyg-demo\">\n<p>\n    Lorem ipsum dolor sit amet, consectetur adipiscing elit, <strong>some text bold</strong> sed do eiusmod tempor incididunt ut\n    labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut\n    aliquip ex ea commodo consequat.\n</p>\n\n<p>\n    Duis aute <a href=\"https://x.com/AlexandreDemode\" target=\"_blank\">some link</a> irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla\n    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt\n    mollit anim id est laborum.\n</p>\n        </textarea>\n\n        <div class=\"demo-switcher current-core\">\n            <button type=\"button\" class=\"button current\" data-config=\"core\">\n                Default\n            </button>\n            <button type=\"button\" class=\"button\" data-config=\"plugins\">\n                With plugins\n            </button>\n        </div>\n    </section>\n\n\n    <section class=\"section section-introduction\">\n        <div class=\"introduction-section\">\n            <div class=\"wrapper\">\n                <div class=\"introduction-section-col\">\n                    <h4 class=\"introduction-section-col-title\">\n                        <img src=\"./img/introduction-html.svg\" alt=\"\">\n                        HTML5 &amp; semantic\n                    </h4>\n                    <p class=\"introduction-section-col-description\">\n                        Editor and generated code are optimized for HTML5 support. Compatible with all recents\n                        browsers like IE9+, Chrome, Opera and Firefox.\n                    </p>\n                </div>\n                <div class=\"introduction-section-col\">\n                    <h4 class=\"introduction-section-col-title\">\n                        <img src=\"./img/introduction-lightweight.svg\" alt=\"\" class=\"illu-lightweight\">\n                        Fast & lightweight\n                    </h4>\n                    <p class=\"introduction-section-col-description\">\n                        All existing WYSIWYG editors are larger than 45kB. Trumbowyg is only 20kB which means faster\n                        page loading. No useless features, just the necessary ones to generate clean, semantic code.\n                    </p>\n                </div>\n                <div class=\"introduction-section-col\">\n                    <h4 class=\"introduction-section-col-title\">\n                        <img src=\"./img/introduction-customizable.svg\" alt=\"\">\n                        Customizable\n                    </h4>\n                    <p class=\"introduction-section-col-description\">\n                        Options and design are entirely configurable to suit your needs. However, the default design\n                        is compatible with Retina display and optimized for a great and simple user experience.\n                    </p>\n                </div>\n            </div>\n        </div>\n    </section>\n\n\n    <section class=\"section section-primary languages\" id=\"languages\">\n        <div class=\"wrapper\">\n            <h2 class=\"section-title\">45+ Languages</h2>\n\n            <p>\n                Read the documentation to <a href=\"./documentation/#localization\">apply a localization</a>\n            </p>\n            <p>\n                You can <a href=\"./documentation/#add-localization\">create your own localization file</a> and submit\n                it in a pull request :)\n            </p>\n\n            <div class=\"languages-columns\">\n                <div class=\"col-globe\">\n                    <img src=\"img/globe.svg\" alt=\"\" class=\"globe\">\n                </div>\n                <div class=\"col-list\">\n                    <ul>\n                        <li>\n                            <button class=\"continent-name\" type=\"button\">\n                                Africa\n                            </button>\n                            <ul>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/ar.min.js\">\n                                        <span class=\"lang-code\">ar</span>\n                                        <span class=\"lang-name\">Arabic</span>\n                                    </a>\n                                </li>\n                            </ul>\n                        </li>\n\n                        <li>\n                            <button class=\"continent-name\" type=\"button\">\n                                America\n                            </button>\n                            <ul>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/es_ar.min.js\">\n                                        <span class=\"lang-code\">es_ar</span>\n                                        <span class=\"lang-name\">Spanish (Argentina)</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/pt_br.min.js\">\n                                        <span class=\"lang-code\">pt_br</span>\n                                        <span class=\"lang-name\">Portuguese (Brazil)</span>\n                                    </a>\n                                </li>\n                            </ul>\n                        </li>\n\n                        <li>\n                            <button class=\"continent-name\" type=\"button\">\n                                Asia\n                            </button>\n                            <ul>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/bn.min.js\">\n                                        <span class=\"lang-code\">bn</span>\n                                        <span class=\"lang-name\">Bengla</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/fa.min.js\">\n                                        <span class=\"lang-code\">fa</span>\n                                        <span class=\"lang-name\">Persian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/he.min.js\">\n                                        <span class=\"lang-code\">he</span>\n                                        <span class=\"lang-name\">Hebrew</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/id.min.js\">\n                                        <span class=\"lang-code\">id</span>\n                                        <span class=\"lang-name\">Indonesian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/ja.min.js\">\n                                        <span class=\"lang-code\">ja</span>\n                                        <span class=\"lang-name\">Japanese</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/ko.min.js\">\n                                        <span class=\"lang-code\">ko</span>\n                                        <span class=\"lang-name\">Korean</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/mn.min.js\">\n                                        <span class=\"lang-code\">mn</span>\n                                        <span class=\"lang-name\">Mongolian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/my.min.js\">\n                                        <span class=\"lang-code\">my</span>\n                                        <span class=\"lang-name\">Malaysian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/ph.min.js\">\n                                        <span class=\"lang-code\">ph</span>\n                                        <span class=\"lang-name\">Filipino</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/ru.min.js\">\n                                        <span class=\"lang-code\">ru</span>\n                                        <span class=\"lang-name\">Russian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/th.min.js\">\n                                        <span class=\"lang-code\">th</span>\n                                        <span class=\"lang-name\">Thai</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/tr.min.js\">\n                                        <span class=\"lang-code\">tr</span>\n                                        <span class=\"lang-name\">Turkish</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/vi.min.js\">\n                                        <span class=\"lang-code\">vi</span>\n                                        <span class=\"lang-name\">Vietnamese</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/zh_cn.min.js\">\n                                        <span class=\"lang-code\">zh_cn</span>\n                                        <span class=\"lang-name\">Simplified Chinese</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/zh_tw.min.js\">\n                                        <span class=\"lang-code\">zh_tw</span>\n                                        <span class=\"lang-name\">Traditional Chinese</span>\n                                    </a>\n                                </li>\n                            </ul>\n                        </li>\n\n                        <li>\n                            <button class=\"continent-name\" type=\"button\">\n                                Europe\n                            </button>\n                            <ul>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/az.min.js\">\n                                        <span class=\"lang-code\">az</span>\n                                        <span class=\"lang-name\">Azerbaijani</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/bg.min.js\">\n                                        <span class=\"lang-code\">bg</span>\n                                        <span class=\"lang-name\">Bulgarian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/by.min.js\">\n                                        <span class=\"lang-code\">by</span>\n                                        <span class=\"lang-name\">Belarusian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/ca.min.js\">\n                                        <span class=\"lang-code\">ca</span>\n                                        <span class=\"lang-name\">Catalan</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/cs.min.js\">\n                                        <span class=\"lang-code\">cs</span>\n                                        <span class=\"lang-name\">Czech</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/da.min.js\">\n                                        <span class=\"lang-code\">da</span>\n                                        <span class=\"lang-name\">Danish</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/de.min.js\">\n                                        <span class=\"lang-code\">de</span>\n                                        <span class=\"lang-name\">German</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/el.min.js\">\n                                        <span class=\"lang-code\">el</span>\n                                        <span class=\"lang-name\">Greek</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/src/langs/en.js\">\n                                        <span class=\"lang-code\">en</span>\n                                        <span class=\"lang-name\">English</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/es.min.js\">\n                                        <span class=\"lang-code\">es</span>\n                                        <span class=\"lang-name\">Spanish</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/et.min.js\">\n                                        <span class=\"lang-code\">et</span>\n                                        <span class=\"lang-name\">Estonian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/fi.min.js\">\n                                        <span class=\"lang-code\">fi</span>\n                                        <span class=\"lang-name\">Finnish</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/fr.min.js\">\n                                        <span class=\"lang-code\">fr</span>\n                                        <span class=\"lang-name\">French</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/hr.min.js\">\n                                        <span class=\"lang-code\">hr</span>\n                                        <span class=\"lang-name\">Croatian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/hu.min.js\">\n                                        <span class=\"lang-code\">hu</span>\n                                        <span class=\"lang-name\">Hungarian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/it.min.js\">\n                                        <span class=\"lang-code\">it</span>\n                                        <span class=\"lang-name\">Italian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/lt.min.js\">\n                                        <span class=\"lang-code\">lt</span>\n                                        <span class=\"lang-name\">Lithuanian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/nl.min.js\">\n                                        <span class=\"lang-code\">nl</span>\n                                        <span class=\"lang-name\">Dutch</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/nb.min.js\">\n                                        <span class=\"lang-code\">nb</span>\n                                        <span class=\"lang-name\">Norwegian Bokmål</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/pl.min.js\">\n                                        <span class=\"lang-code\">pl</span>\n                                        <span class=\"lang-name\">Polish</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/pt.min.js\">\n                                        <span class=\"lang-code\">pt</span>\n                                        <span class=\"lang-name\">Portuguese</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/ro.min.js\">\n                                        <span class=\"lang-code\">ro</span>\n                                        <span class=\"lang-name\">Romanian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/rs.min.js\">\n                                        <span class=\"lang-code\">rs</span>\n                                        <span class=\"lang-name\">Serbian (Cyrlic)</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/rs_latin.min.js\">\n                                        <span class=\"lang-code\">rs_latin</span>\n                                        <span class=\"lang-name\">Serbian (Latin)</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/ru.min.js\">\n                                        <span class=\"lang-code\">ru</span>\n                                        <span class=\"lang-name\">Russian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/sk.min.js\">\n                                        <span class=\"lang-code\">sk</span>\n                                        <span class=\"lang-name\">Slovak</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/sl.min.js\">\n                                        <span class=\"lang-code\">sl</span>\n                                        <span class=\"lang-name\">Slovenian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/sq.min.js\">\n                                        <span class=\"lang-code\">sq</span>\n                                        <span class=\"lang-name\">Albanian</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/sv.min.js\">\n                                        <span class=\"lang-code\">sv</span>\n                                        <span class=\"lang-name\">Swedish</span>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"https://github.com/Alex-D/Trumbowyg/blob/v2.31.0/dist/langs/ua.min.js\">\n                                        <span class=\"lang-code\">ua</span>\n                                        <span class=\"lang-name\">Ukrainian</span>\n                                    </a>\n                                </li>\n                            </ul>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </div>\n    </section>\n\n\n    <div class=\"section section-secondary plugins-packages\">\n        <div class=\"wrapper\">\n            <div class=\"col-plugins\">\n                <h2 class=\"section-title\" id=\"plugins\">Plugins</h2>\n                <h3 class=\"section-subtitle\">Extends Trumbowyg</h3>\n\n                <p>\n                    You can create your own plugins for Trumbowyg and propose them via pull requests on the Github\n                    repository.\n                    <a href=\"./documentation/plugins/\">Plugins documentation</a>\n                </p>\n\n                <ul>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-allowtagsfrompaste\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-removeformat\"></use>\n                            </svg>\n                            Allow tags from paste\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-base64\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-base64\"></use>\n                            </svg>\n                            Base 64\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-cleanpaste\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-removeformat\"></use>\n                            </svg>\n                            Clean paste\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-colors\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-back-color\"></use>\n                            </svg>\n                            Colors\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-emoji\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-emoji\"></use>\n                            </svg>\n                            Emoji\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-fontfamily\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-bold\"></use>\n                            </svg>\n                            Font family\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-fontsize\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-fontsize\"></use>\n                            </svg>\n                            Font size\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-giphy\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-giphy\"></use>\n                            </svg>\n                            Giphy\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-highlight\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-highlight\"></use>\n                            </svg>\n                            Highlight\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-history\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-undo\"></use>\n                            </svg>\n                            History\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-indent\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-indent\"></use>\n                            </svg>\n                            Indent\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-insertaudio\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-insert-audio\"></use>\n                            </svg>\n                            Insert audio\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-lineheight\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-lineheight\"></use>\n                            </svg>\n                            Line height\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-mathml\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-mathml\"></use>\n                            </svg>\n                            MathML\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-mention\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-mention\"></use>\n                            </svg>\n                            Mention\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-noembed\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-noembed\"></use>\n                            </svg>\n                            No embed\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-pasteembed\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-noembed\"></use>\n                            </svg>\n                            Paste embed\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-pasteimage\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-insert-image\"></use>\n                            </svg>\n                            Paste image\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-preformatted\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-preformatted\"></use>\n                            </svg>\n                            Preformatted\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-resizimg\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-insert-image\"></use>\n                            </svg>\n                            Resizimg\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-ruby\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-ruby\"></use>\n                            </svg>\n                            Ruby\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-specialchars\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-special-chars\"></use>\n                            </svg>\n                            Special chars\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-speechrecognition\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-speechrecognition\"></use>\n                            </svg>\n                            Speech recognition\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-table\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-table\"></use>\n                            </svg>\n                            Table\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-template\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-justify-full\"></use>\n                            </svg>\n                            Template\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"./documentation/plugins/#plugin-upload\">\n                            <svg>\n                                <use xlink:href=\"#trumbowyg-upload\"></use>\n                            </svg>\n                            Upload\n                        </a>\n                    </li>\n                </ul>\n            </div>\n            <div class=\"col-packages\">\n                <h2 class=\"section-title\" id=\"packages\">Packages</h2>\n                <h3 class=\"section-subtitle\">Ready for use Web frameworks and CMS packages</h3>\n\n                <p>\n                    You can create your own package for Trumbowyg or use a ready for use. This is the full list of\n                    known packages for Trumbowyg.\n                </p>\n\n                <ul>\n                    <li>\n                        <a href=\"https://github.com/jutaz/angular-trumbowyg\">\n                            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 30 30\">\n                                <path fill=\"#FF974A\" d=\"M17.9 14.9l-2.9-6-.1-.1-2.6 6.2h5.6zM15 0L.8 5 3 23.4 15 30l12-6.6 2.2-18.5L15 0zm6 22l-2-4.5h-7.9l-1.8 4.4-3.2.1 8.8-19.4L24.1 22H21z\"></path>\n                            </svg>\n                            AngularJS\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"https://github.com/ankurk91/vue-trumbowyg\">\n                            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28.19 24.38\">\n                                <path fill=\"#ff974a\" d=\"M0 .06l14.09 24.32L28.18 0h-5.65l-8.44 14.66L5.65.03z\"></path>\n                                <path fill=\"#ffbe92\" d=\"M5.66.03l8.47 14.63L22.53 0h-5.19l-3.21 5.69L10.86.05 5.66.03z\"></path>\n                            </svg>\n                            Vue.js\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"https://github.com/RD17/react-trumbowyg\">\n                            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 37.7 33.5\">\n                                <g fill=\"#ff974a\">\n                                    <circle cx=\"18.8\" cy=\"16.7\" r=\"3.4\"></circle>\n                                    <path d=\"M37.5 15.8c-.2-.5-.5-1-.8-1.5-.3-.3-.6-.7-1-1-.6-.5-1.3-.9-2.1-1.3s-1.7-.8-2.6-1.1c-.4-.1-.8-.3-1.2-.4.1-.3.1-.6.2-.8.3-1.4.4-2.6.4-3.8 0-1.3-.2-2.4-.5-3.3-.2-.5-.4-.9-.7-1.2-.3-.4-.6-.7-1-.9-.3-.1-.5-.3-.8-.3-.3-.2-.6-.2-.9-.2-.5 0-1 .1-1.5.2-.8.2-1.6.6-2.5 1.1-.9.5-1.8 1.2-2.7 2l-.9.9-.6-.6c-1.3-1.1-2.5-2-3.7-2.6-.6-.3-1.2-.5-1.7-.7-.7-.2-1.2-.3-1.8-.3-.3 0-.6 0-.9.1-.3.1-.6.2-.8.4-.4.2-.7.5-1 .8-.2.3-.4.6-.5.9-.2.5-.4 1-.5 1.6-.1.6-.1 1.3-.1 1.9 0 1.1.1 2.2.4 3.5l.3 1.2c-.5.1-.9.3-1.4.4-1 .3-1.9.7-2.6 1.1-.6.3-1.1.6-1.6 1-.7.5-1.3 1.1-1.7 1.7-.2.3-.4.6-.5 1-.1.4-.2.8-.2 1.1 0 .3.1.6.1.9.2.5.5 1 .8 1.5.6.7 1.4 1.4 2.4 2 1 .6 2.2 1.2 3.5 1.6.3.1.7.2 1 .3-.1.5-.2.9-.3 1.3-.2 1.2-.3 2.3-.3 3.3 0 1.2.2 2.3.5 3.2.2.5.4.9.7 1.2.3.4.6.7 1 .9.3.2.6.3.9.3.3.1.6.1.9.1.5 0 1-.1 1.6-.2.8-.2 1.7-.6 2.6-1.1.9-.5 1.8-1.2 2.8-2 .3-.2.5-.5.8-.7.3.3.7.6 1 .9 1.2 1 2.3 1.8 3.4 2.3.6.3 1.1.5 1.6.6.5.1 1 .2 1.5.2.3 0 .6 0 .9-.1.3-.1.6-.2.8-.3.4-.2.7-.5 1-.9.2-.3.4-.6.5-.9.2-.5.4-1.1.5-1.7.1-.6.2-1.3.2-2 0-1.1-.1-2.2-.4-3.5-.1-.3-.1-.7-.2-1 .2-.1.5-.1.7-.2 1.1-.4 2-.8 2.9-1.2.6-.3 1.2-.7 1.7-1.1.8-.6 1.4-1.2 1.8-1.8.2-.3.4-.7.5-1 .1-.3.2-.7.2-1.1.1-.1 0-.4-.1-.7zM20.8 4.5C22 3.5 23 2.8 24 2.3c.5-.2.9-.4 1.4-.5.4-.1.8-.2 1.1-.2.2 0 .4 0 .5.1.2 0 .3.1.4.2.2.1.3.2.5.5l.3.6c.2.4.3.8.4 1.3.1.5.1 1.1.1 1.7 0 1-.1 2.2-.4 3.5-.1.2-.1.5-.2.7-.9-.2-1.8-.4-2.8-.5-.7-.1-1.5-.2-2.2-.3-.4-.6-.8-1.1-1.2-1.6-.7-.8-1.3-1.6-2-2.4.4-.4.7-.6.9-.9zm-8.6 8.4c-.4.6-.7 1.3-1.1 1.9-.1-.3-.2-.5-.3-.8-.3-.8-.6-1.7-.9-2.5.8-.2 1.6-.3 2.5-.5.3 0 .6-.1.9-.1-.4.7-.7 1.4-1.1 2zm-1.1 5.8c.3.6.7 1.3 1.1 1.9.4.7.8 1.3 1.2 1.9-.3 0-.5-.1-.8-.1-1-.1-1.9-.3-2.7-.5.2-.8.5-1.6.9-2.5.1-.2.2-.5.3-.7zm2.5 1.1c-.6-1-1.1-2-1.6-3 .5-1 1-2 1.6-3 .6-1 1.2-2 1.8-2.9 1.1-.1 2.3-.1 3.4-.1 1.2 0 2.3 0 3.4.1.6.9 1.2 1.9 1.8 2.9.6 1 1.1 2 1.6 3-.5 1-1 2-1.6 3-.6 1-1.2 2-1.8 2.9-1.1.1-2.3.1-3.4.1-1.2 0-2.3 0-3.4-.1-.6-.9-1.2-1.9-1.8-2.9zm11.9.8c.4-.7.7-1.3 1.1-2 .1.2.2.5.3.7.4.9.7 1.8 1 2.6-.9.2-1.9.4-2.9.5-.2 0-.4 0-.6.1.3-.6.7-1.3 1.1-1.9zm1.3-6.3c-.1.2-.1.4-.2.5-.3-.7-.7-1.3-1.1-2-.4-.6-.8-1.3-1.1-1.9.3 0 .6.1.8.1.9.1 1.8.3 2.6.5-.3 1-.6 1.9-1 2.8zm-8-7.8c.6.7 1.2 1.4 1.9 2.2.1.2.2.3.4.5-.7 0-1.5-.1-2.2-.1-.7 0-1.5 0-2.2.1.2-.2.3-.4.5-.7.5-.7 1.1-1.4 1.6-2zM9.3 3.1c.1-.3.3-.6.4-.8.1-.2.3-.3.5-.4.1-.1.3-.1.4-.2.2 0 .3-.1.6-.1s.7.1 1.2.2c.7.2 1.4.5 2.3 1 .8.5 1.7 1.1 2.6 1.9.2.2.4.3.6.5-.6.7-1.2 1.4-1.9 2.2-.6.6-1 1.2-1.5 1.9-.8.1-1.6.2-2.3.3-.9.1-1.8.3-2.7.5l-.3-1.2c-.2-1.2-.3-2.2-.3-3.2s.1-1.9.4-2.6zm-1 18.5l-.9-.3c-1-.3-1.8-.7-2.5-1.1-.6-.3-1-.6-1.5-.9-.6-.5-1.1-1-1.4-1.4-.1-.2-.3-.4-.3-.6-.1-.2-.1-.4-.1-.5 0-.1 0-.3.1-.4.1-.3.3-.6.5-.9l.8-.8c.5-.4 1-.8 1.7-1.1.7-.4 1.5-.7 2.4-1 .4-.1.8-.3 1.3-.4l.9 2.7.9 2.1c-.3.7-.6 1.5-.9 2.2-.4.6-.7 1.5-1 2.4zm8.8 7.3c-1.1 1-2.3 1.8-3.3 2.2-.5.2-1 .4-1.4.5-.4.1-.8.2-1.2.2-.2 0-.4 0-.6-.1-.2 0-.3-.1-.4-.2-.2-.1-.3-.2-.5-.4-.1-.2-.2-.3-.3-.6-.2-.3-.3-.8-.4-1.2-.1-.5-.1-1-.1-1.6 0-.9.1-1.9.3-3 .1-.4.2-.8.3-1.3.9.2 1.9.4 2.9.5.7.1 1.4.2 2.1.2.5.6.9 1.3 1.4 1.9.6.8 1.2 1.5 1.8 2.1-.2.4-.4.6-.6.8zm1.8-1.8c-.6-.6-1.1-1.3-1.7-2-.2-.2-.4-.5-.6-.7h2.2c.8 0 1.5 0 2.3-.1-.1.2-.3.4-.4.6-.6.8-1.2 1.5-1.8 2.2zm9.5 3.2c-.1.4-.3.6-.5.9-.2.2-.3.4-.5.5-.1.1-.3.1-.4.2-.2 0-.3.1-.5.1-.3 0-.7-.1-1.1-.2-.6-.2-1.3-.5-2.1-.9-.7-.4-1.5-1-2.4-1.7l-.9-.9c.6-.7 1.3-1.5 1.9-2.3.4-.5.8-1.1 1.2-1.7.7-.1 1.3-.1 1.9-.2 1.1-.1 2.2-.3 3.2-.6.1.3.1.6.2.9.2 1.2.3 2.2.3 3.2.1 1.1 0 2-.3 2.7zM36 17.2c-.1.3-.3.6-.6 1-.2.3-.5.5-.9.8-.5.4-1.2.8-1.9 1.2-.7.4-1.6.8-2.6 1.1-.2.1-.4.1-.6.2-.3-.9-.6-1.9-1-2.8-.3-.6-.6-1.3-.9-1.9.3-.6.5-1.2.8-1.8.4-1 .8-2 1.1-2.9.4.1.8.2 1.1.4.9.3 1.7.7 2.5 1 .5.3 1 .6 1.4.9.6.4 1.1.9 1.3 1.3l.3.6c.1.2.1.3.1.5 0 .1-.1.2-.1.4z\"></path>\n                                </g>\n                            </svg>\n                            React\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"https://bitbucket.org/fogstream/django-fs-trumbowyg/\">\n                            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 30 30\">\n                                <g fill=\"#FF974A\">\n                                    <path d=\"M3.5 10.3h1.6v7.6c-.8.2-1.5.2-2.1.2-2 0-3-.9-3-2.6 0-1.7 1.1-2.8 2.8-2.8.3 0 .5 0 .7.1v-2.5zm0 3.8c-.2-.1-.4-.1-.6-.1-.8 0-1.3.5-1.3 1.4 0 .9.5 1.3 1.3 1.3h.6v-2.6z\"></path>\n                                    <path d=\"M7.8 12.9v3.8c0 1.3-.1 1.9-.4 2.5-.3.5-.6.8-1.4 1.1l-1.5-.7c.7-.3 1.1-.6 1.3-1.1.2-.5.3-1 .3-2.4v-3.2h1.7zm-1.7-2.6h1.6V12H6.1v-1.7zM8.8 13.2c.7-.3 1.4-.5 2.2-.5.8 0 1.4.2 1.6.7.1.2.2.6.2 1.2V18c-.7.1-1.7.2-2.3.2-1.4 0-2-.5-2-1.5 0-1.1.8-1.7 2.8-1.8v-.4c0-.3-.1-.4-.6-.4-.6 0-1.3.2-1.9.5v-1.4zm2.5 2.6c-1.1.1-1.4.3-1.4.7 0 .3.2.5.6.5.2 0 .5 0 .8-.1v-1.1zM13.5 13.1c1-.3 1.8-.4 2.6-.4s1.4.2 1.8.6c.3.4.4.7.4 1.6v3.2h-1.6V15c0-.6-.2-.9-.8-.9-.2 0-.4 0-.8.1v3.9h-1.6v-5zM19 19c.6.3 1.1.4 1.8.4 1.1 0 1.5-.4 1.5-1.5-.3.2-.6.2-1.1.2-1.4 0-2.3-.9-2.3-2.4 0-1.9 1.3-2.9 3.7-2.9.7 0 1.3.1 2.1.2l-.6 1.2c-.4-.1 0 0-.4 0v2.9c0 1.4-.1 2.1-.5 2.6-.5.8-1.4 1.2-2.6 1.2-.6 0-1.2-.1-1.8-.3L19 19zm3.3-4.9c-.1 0-.1 0 0 0h-.2c-.3 0-.7.1-.9.2-.4.2-.6.6-.6 1.2 0 .8.4 1.3 1.1 1.3.2 0 .4 0 .6-.1v-.5-2.1zM27.3 12.7c1.6 0 2.6 1 2.6 2.7 0 1.7-1 2.8-2.7 2.8-1.6 0-2.6-1-2.6-2.7 0-1.7 1-2.8 2.7-2.8zm0 4.2c.6 0 1-.5 1-1.4 0-.9-.4-1.4-1-1.4s-1 .5-1 1.4c0 .9.3 1.4 1 1.4z\"></path>\n                                </g>\n                            </svg>\n                            Django\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"https://github.com/TikiTDO/trumbowyg_rails\">\n                            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 30 30\">\n                                <path fill=\"#FF974A\" d=\"M8.8 26.5c0-1.5-1.1-1.7-2.4-1.7H4.7V30H6v-1.4l1.2 1.2h2l-1.6-1.6s1.1 0 1.2-1.7zm-1.6.6H6v-.9h1.1v.9zm4.7-2.3h-.3c-.7 0-1.7.1-1.7 1.4v3.6h1.3V29h1.3v.9h1.3v-3.8c0-1.2-1.2-1.3-1.9-1.3zm.6 2.8h-1.2v-1.4h1.2v1.4zm2.7 2.2h1.4v-5h-1.4v5zm4.1-4.9H18v5h3.3v-1.3h-1.9v-3.7zm5 1.8h-.9v-.5h2.2v-1.3h-1.9c-1.2 0-1.8.5-1.8 1.7s1.1 1.5 1.8 1.5c.6 0 .9.1.9.3 0 .2 0 .4-.6.4h-2V30h1.7c1.4 0 2.1-.1 2.1-1.7 0-1.6-1-1.6-1.5-1.6zM19 1.3c-4.3.4-7.2 3.3-9 6.8-1.8 3.5-2.9 6-3.6 9.7-.7 3.7-.4 5.6-.4 5.6h11.3s-2.5-5.9-1.9-11.3c.6-5.4 4.8-7.9 7.1-8.1 2.3-.3 3.6 1.2 3.6 1.2l.5-.8S23.2.9 19 1.3zM5.9 17.6l-2.2-.2-.3 2.2 2.1.3.4-2.3zm1.8-6.7l-2-.8-.6 1.9 2 .7.6-1.8zM11 5.3l-1.5-1-1.1 1.4 1.5 1.1L11 5.3zm4.3-3.6l-1-1.2-1.4.7 1 1.3 1.4-.8zm4.6-.6L19.7 0l-1.8-.1.3 1.3 1.7-.1zm5.3 1.2l-1.4-1.1V2l1.2.7.2-.4zm-.5 2.6l-1.1-.3v.7l1.1.1v-.5zm-4.8.3l.6 1.1.8-.7-.2-.7-1.2.3zM19 7.8l-.9-1.3-.9.8 1.2 1.4.6-.9zm-3.1 3.5l1.4 1.3.3-1.4-1.2-1-.5 1.1zm-.1 4.4l1.8.8-.1-1.5-1.6-.9-.1 1.6zm3.2 5.6l-.8-1.7h-1.9l.4 1.6 2.3.1z\"></path>\n                            </svg>\n                            Ruby on Rails\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"https://github.com/Johnathan/nova-trumbowyg\">\n                            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"100 105 500 500\">\n                                <path fill=\"#FF974A\" d=\"M556.8 344.2c-2.9-3.2-42.3-52.6-49.3-61-7-8.4-10.3-6.9-14.6-6.2s-54.2 9-60 10c-5.8 1-9.4 3.3-5.9 8.3 3.2 4.4 36 51 43.2 61.2l-130.5 31.3-103.6-173.5c-4.1-6.1-5-8.3-14.4-7.8-9.4.4-81.4 6.4-86.5 6.8-5.1.4-10.8 2.7-5.6 14.8 5.1 12.1 86.9 188.3 89.2 193.4 2.3 5.1 8.2 13.4 22.1 10.1 14.2-3.4 63.5-16.3 90.4-23.3 14.2 25.8 43.3 78 48.6 85.5 7.2 10 12.1 8.3 23.1 5 8.6-2.6 134.4-47.8 140.1-50.2 5.7-2.3 9.2-4 5.3-9.7-2.8-4.2-36-48.6-53.4-71.9 11.9-3.2 54.2-14.4 58.8-15.7 5.2-1.3 5.9-3.9 3-7.1zm-237.2 48.5c-1.6.3-74.6 17.8-78.5 18.7-3.9.9-3.9.4-4.3-.9-.4-1.3-86.9-179.6-88.1-181.8-1.2-2.2-1.1-4 0-4s69-6.1 71.4-6.2 2.1.4 3 1.9c0 0 95.7 165.2 97.4 168.1 1.7 3 .7 3.9-.9 4.2zm206.1 38.6c1.2 1.8 2.3 3-1.3 4.3-3.7 1.3-123.7 41.8-126 42.8-2.3 1-4.2 1.3-7.2-3s-42-71.9-42-71.9l127.2-33.1c3.2-1 4.2-1.7 6.2 1.5s41.9 57.6 43.1 59.4zm8.1-90.3c-2.9.6-49.6 12.2-49.6 12.2L446 300.8c-1.1-1.5-2-3 .7-3.4 2.7-.4 46.1-8.2 48-8.6 2-.4 3.7-1 6.1 2.3 2.4 3.3 35.4 45.1 36.7 46.7 1.3 1.6-.8 2.6-3.7 3.2z\"></path>\n                            </svg>\n                            Laravel\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"https://github.com/alexdw/trumbowygBundle\">\n                            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"60 47 80 80\">\n                                <path fill=\"#FF974A\" d=\"M124.389 49.119c-5.697.195-10.67 3.34-14.373 7.68-4.1 4.765-6.824 10.411-8.791 16.18-3.514-2.882-6.223-6.611-11.864-8.233-4.359-1.253-8.936-.737-13.146 2.399-1.992 1.489-3.367 3.738-4.02 5.859-1.692 5.498 1.778 10.396 3.354 12.151l3.447 3.691c.709.725 2.422 2.613 1.584 5.319-.9 2.947-4.451 4.85-8.092 3.731-1.627-.499-3.963-1.71-3.439-3.413.215-.699.715-1.225.984-1.821.244-.521.363-.907.438-1.14.665-2.169-.245-4.994-2.57-5.713-2.171-.666-4.391-.138-5.252 2.655-.977 3.174.543 8.935 8.681 11.441 9.535 2.935 17.597-2.259 18.742-9.026.721-4.239-1.195-7.392-4.701-11.441l-2.859-3.163c-1.73-1.729-2.324-4.677-.533-6.942 1.512-1.912 3.664-2.726 7.191-1.768 5.15 1.396 7.443 4.969 11.271 7.851-1.578 5.187-2.613 10.392-3.547 15.059l-.574 3.481c-2.736 14.352-4.826 22.235-10.256 26.76-1.094.779-2.658 1.943-5.014 2.027-1.238.037-1.637-.814-1.654-1.186-.027-.865.703-1.264 1.188-1.652.727-.396 1.824-1.053 1.748-3.156-.078-2.484-2.137-4.639-5.111-4.541-2.229.075-5.625 2.171-5.497 6.011.131 3.967 3.827 6.938 9.401 6.75 2.979-.102 9.633-1.312 16.188-9.105 7.631-8.935 9.766-19.175 11.372-26.671l1.793-9.897c.992.119 2.059.2 3.217.228 9.504.201 14.256-4.72 14.328-8.302.049-2.167-1.42-4.302-3.479-4.251-1.471.041-3.32 1.022-3.762 3.057-.436 1.995 3.023 3.798.32 5.553-1.92 1.242-5.361 2.116-10.209 1.407l.881-4.872c1.799-9.238 4.018-20.6 12.436-20.878.615-.029 2.857.026 2.91 1.512.014.493-.109.623-.689 1.757-.592.884-.814 1.64-.785 2.504.08 2.356 1.873 3.908 4.471 3.818 3.473-.116 4.469-3.496 4.412-5.233-.146-4.085-4.449-6.665-10.14-6.477z\"></path>\n                            </svg>\n                            Symfony\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"https://github.com/artkost/yii2-trumbowyg\">\n                            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 30 30\">\n                                <path fill=\"#FF974A\" d=\"M24.8 0c-3.3.1-7.3 4.4-5.9 8.4 1.4 3.9 2.4 6.8 2.6 11.2 3.5-3.6 6.7-7.5 6.9-12.1.1-3.7-1.6-6.5-3.6-7.5zm-8.7 16.4c-.5.9-1.1 1.9-2 3-1.8 2.3-3.6 6.1-3 10.5 7.3-.8 9.6-6.5 9.8-9.6-1.3-2.2-3.8-3.5-4.8-3.9zM1.3 2.8c-.3 3.5 1.2 8.6 7 10.3 2.5.8 4.2 1.2 6 1.9 2.7 1 4.9 2.3 6.6 4.6-.3-3.9-1.9-8.3-4.3-11.8-3.5-5-9.6-7.4-15.3-5z\"></path>\n                            </svg>\n                            Yii 2 widget\n                        </a>\n                    </li>\n                </ul>\n            </div>\n        </div>\n    </div>\n\n\n    <section class=\"section wrapper\">\n        <h2 class=\"section-title\" id=\"donate\">Supporting Trumbowyg</h2>\n\n        <div class=\"donate-container\">\n            <div class=\"donate-description\">\n                <p>\n                    Trumbowyg is an MIT-licensed open source project and completely free to use.\n                </p>\n                <p>\n                    However, the amount of effort needed to maintain and develop new features for the project is not sustainable\n                    without proper financial backing.\n                    You can support its ongoing development by being a backer or a sponsor on\n                    <a href=\"https://www.patreon.com/alexandredemode\">Trumbowyg Patreon campaign</a>\n                    (recurring, with perks for different tiers), and get your company logo here.\n                </p>\n                <p>\n                    Also, you can make a <a href=\"https://www.paypal.me/demodealexandre/20eur\">one time donation via PayPal</a>.\n                </p>\n            </div>\n\n            <div class=\"donate-footer\">\n                <a href=\"https://www.patreon.com/alexandredemode\" class=\"button button-ghost\">Be a sponsor on Patreon</a>\n                <a href=\"https://www.paypal.me/demodealexandre/20eur\" class=\"button button-secondary\">Donate via PayPal</a>\n            </div>\n\n            <img src=\"img/beer.svg\" alt=\"\" class=\"donate-beer\">\n        </div>\n\n        <div class=\"sponsors-container\">\n            <p class=\"section-subtitle\">Sponsored by</p>\n\n            <a href=\"https://www.premirus.com/?ref=trumbowyg\">Premirus Corporation</a>\n        </div>\n    </section>\n</main>\n\n\n<footer class=\"footer\">\n    <div class=\"wrapper\">\n        <span class=\"footer-text\">\n            Made with <span class=\"hearts\">&hearts;</span> by Alex-D\n        </span>\n    </div>\n    <div class=\"wrapper\">\n        <a class=\"footer-link\" href=\"http://alex-d.fr/\" title=\"Discover the author's website\">\n            Website\n        </a>\n        <a class=\"footer-link\" href=\"https://github.com/Alex-D\" title=\"Alex-D's GitHub profile\">\n            GitHub\n        </a>\n        <a class=\"footer-link\" href=\"https://x.com/AlexandreDemode\" title=\"Alex-D's profile on X.com\">\n            X\n        </a>\n        <a class=\"footer-link\" href=\"https://www.facebook.com/Alex.D.fr\" title=\"Alex-D's Facebook page\">\n            Facebook\n        </a>\n        <a\n            class=\"footer-link\" href=\"https://soundcloud.com/alexandre-demode\"\n            title=\"Listen to Alex-D's compositions on SoundCloud\"\n        >\n            SoundCloud\n        </a>\n    </div>\n</footer>\n\n\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script>window.jQuery || document.write('<script src=\"js/vendor/jquery-3.3.1.min.js\"><\\/script>')</script>\n\n<script src=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/trumbowyg.min.js\"></script>\n<script src=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/plugins/base64/trumbowyg.base64.min.js\" defer></script>\n<script src=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/plugins/colors/trumbowyg.colors.min.js\" defer></script>\n<script src=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/plugins/giphy/trumbowyg.giphy.min.js\" defer></script>\n<script src=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/plugins/noembed/trumbowyg.noembed.min.js\" defer></script>\n<script src=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/plugins/pasteimage/trumbowyg.pasteimage.min.js\" defer></script>\n<script src=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/plugins/preformatted/trumbowyg.preformatted.min.js\" defer></script>\n<script src=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/plugins/upload/trumbowyg.upload.min.js\" defer></script>\n\n<script src=\"js/vendor/highlight.js\"></script>\n<script src=\"js/main.js\"></script>\n\n<link rel=\"stylesheet\" href=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/plugins/colors/ui/trumbowyg.colors.min.css\">\n<link rel=\"stylesheet\" href=\"//rawcdn.githack.com/Alex-D/Trumbowyg/v2.31.0/dist/plugins/giphy/ui/trumbowyg.giphy.min.css\">\n\n</body>\n</html>\n"
  },
  {
    "path": "docs/js/main.js",
    "content": "'use strict';\n\nif (window.location.href.indexOf('index.html') > 0) {\n    window.location = window.location.href.replace('index.html', '');\n}\n\nhljs.configure({\n    ignoreUnescapedHTML: true,\n});\n// Highlight.js mergeHtmlPlugin\nhljs.addPlugin((function () {\n    'use strict';\n\n    var originalStream;\n\n    /**\n     * @param {string} value\n     * @returns {string}\n     */\n    function escapeHTML(value) {\n        return value\n            .replace(/&/g, '&amp;')\n            .replace(/</g, '&lt;')\n            .replace(/>/g, '&gt;')\n            .replace(/\"/g, '&quot;')\n            .replace(/'/g, '&#x27;');\n    }\n\n    /* plugin itself */\n\n    /** @type {HLJSPlugin} */\n    const mergeHTMLPlugin = {\n        // preserve the original HTML token stream\n        \"before:highlightElement\": ({ el }) => {\n            originalStream = nodeStream(el);\n        },\n        // merge it afterwards with the highlighted token stream\n        \"after:highlightElement\": ({ el, result, text }) => {\n            if (!originalStream.length) return;\n\n            const resultNode = document.createElement('div');\n            resultNode.innerHTML = result.value;\n            result.value = mergeStreams(originalStream, nodeStream(resultNode), text);\n            el.innerHTML = result.value;\n        }\n    };\n\n    /* Stream merging support functions */\n\n    /**\n     * @typedef Event\n     * @property {'start'|'stop'} event\n     * @property {number} offset\n     * @property {Node} node\n     */\n\n    /**\n     * @param {Node} node\n     */\n    function tag(node) {\n        return node.nodeName.toLowerCase();\n    }\n\n    /**\n     * @param {Node} node\n     */\n    function nodeStream(node) {\n        /** @type Event[] */\n        const result = [];\n        (function _nodeStream(node, offset) {\n            for (let child = node.firstChild; child; child = child.nextSibling) {\n                if (child.nodeType === 3) {\n                    offset += child.nodeValue.length;\n                } else if (child.nodeType === 1) {\n                    result.push({\n                        event: 'start',\n                        offset: offset,\n                        node: child\n                    });\n                    offset = _nodeStream(child, offset);\n                    // Prevent void elements from having an end tag that would actually\n                    // double them in the output. There are more void elements in HTML\n                    // but we list only those realistically expected in code display.\n                    if (!tag(child).match(/br|hr|img|input/)) {\n                        result.push({\n                            event: 'stop',\n                            offset: offset,\n                            node: child\n                        });\n                    }\n                }\n            }\n            return offset;\n        })(node, 0);\n        return result;\n    }\n\n    /**\n     * @param {any} original - the original stream\n     * @param {any} highlighted - stream of the highlighted source\n     * @param {string} value - the original source itself\n     */\n    function mergeStreams(original, highlighted, value) {\n        let processed = 0;\n        let result = '';\n        const nodeStack = [];\n\n        function selectStream() {\n            if (!original.length || !highlighted.length) {\n                return original.length ? original : highlighted;\n            }\n            if (original[0].offset !== highlighted[0].offset) {\n                return (original[0].offset < highlighted[0].offset) ? original : highlighted;\n            }\n\n            return highlighted[0].event === 'start' ? original : highlighted;\n        }\n\n        /**\n         * @param {Node} node\n         */\n        function open(node) {\n            function attributeString(attr) {\n                return ' ' + attr.nodeName + '=\"' + escapeHTML(attr.value) + '\"';\n            }\n            result += '<' + tag(node) + [].map.call(node.attributes, attributeString).join('') + '>';\n        }\n\n        /**\n         * @param {Node} node\n         */\n        function close(node) {\n            result += '</' + tag(node) + '>';\n        }\n\n        /**\n         * @param {Event} event\n         */\n        function render(event) {\n            (event.event === 'start' ? open : close)(event.node);\n        }\n\n        while (original.length || highlighted.length) {\n            let stream = selectStream();\n            result += escapeHTML(value.substring(processed, stream[0].offset));\n            processed = stream[0].offset;\n            if (stream === original) {\n                /*\n                On any opening or closing tag of the original markup we first close\n                the entire highlighted node stack, then render the original tag along\n                with all the following original tags at the same offset and then\n                reopen all the tags on the highlighted stack.\n                */\n                nodeStack.reverse().forEach(close);\n                do {\n                    render(stream.splice(0, 1)[0]);\n                    stream = selectStream();\n                } while (stream === original && stream.length && stream[0].offset === processed);\n                nodeStack.reverse().forEach(open);\n            } else {\n                if (stream[0].event === 'start') {\n                    nodeStack.push(stream[0].node);\n                } else {\n                    nodeStack.pop();\n                }\n                render(stream.splice(0, 1)[0]);\n            }\n        }\n        return result + escapeHTML(value.substr(processed));\n    }\n\n    return mergeHTMLPlugin;\n\n}()));\nArray.from(document.querySelectorAll('pre code')).forEach(function (codeElement) {\n    const hasDiff = codeElement.classList.contains('diff');\n    if (hasDiff) {\n        hljs.highlightElement(codeElement);\n        codeElement.classList.remove('diff', 'language-diff');\n    }\n    hljs.highlightElement(codeElement);\n    if (hasDiff) {\n        codeElement.classList.add('language-diff');\n    }\n});\n\n(function ($) {\n    if ($.trumbowyg) {\n        var configurations = {\n            core: {},\n            plugins: {\n                btnsDef: {\n                    // Customizable dropdowns\n                    align: {\n                        dropdown: ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n                        ico: 'justifyLeft'\n                    }\n                },\n                btns: [\n                    ['viewHTML'],\n                    ['undo', 'redo'],\n                    ['formatting'],\n                    ['strong', 'em', 'del', 'underline'],\n                    ['foreColor', 'backColor'],\n                    ['link'],\n                    ['insertImage', 'upload', 'base64', 'noembed', 'giphy'],\n                    ['align'],\n                    ['preformatted'],\n                    ['horizontalRule'],\n                    ['fullscreen']\n                ],\n                plugins: {\n                    giphy: {\n                        apiKey: 'dNhCbN6hrhpBMxXhIswM34wIR2UBpCns'\n                    },\n                    // Add imgur parameters to upload plugin\n                    upload: {\n                        serverPath: 'https://api.imgur.com/3/image',\n                        fileFieldName: 'image',\n                        headers: {\n                            'Authorization': 'Client-ID 9e57cb1c4791cea'\n                        },\n                        urlPropertyName: 'data.link'\n                    }\n                }\n            }\n        };\n\n        // Demo switch\n        var $demoTextarea = $('#trumbowyg-demo');\n        $demoTextarea.trumbowyg(configurations.core);\n        $('.demo-switcher .button').on('click', function () {\n            var $current = $('.demo-switcher .current');\n            $(this).parent().removeClass('current-' + $current.data('config'));\n            $current.removeClass('current');\n            $(this).addClass('current');\n            $(this).parent().addClass('current-' + $(this).data('config'));\n            $demoTextarea.trumbowyg('destroy');\n            $demoTextarea.trumbowyg(configurations[$(this).data('config')]);\n        });\n\n        // Lang accordion\n        $('#lang-list-view-full').on('click', function () {\n            $('#lang-list-light').slideUp(100);\n            $('#lang-list-full').slideDown(350);\n        });\n    }\n\n    // Languages continent switch\n    var $continentNames = $('.continent-name');\n    $continentNames.each(function () {\n        $(this).parent().attr('data-height', $(this).parent().height());\n    });\n    $continentNames.click(function () {\n        var $oldOpen = $('#languages').find('.col-list ul li[style]');\n        $oldOpen.removeAttr('style');\n        $(this).parent().css({\n            height: $(this).parent().attr('data-height') + 'px'\n        });\n    });\n    $continentNames.last().parent().css({\n        height: $continentNames.last().parent().attr('data-height') + 'px'\n    });\n\n    // Add anchors\n    $('.feature h3[id], .feature h4[id]').each(function () {\n        $(this).after($('<a/>', {\n            html: '<svg><use xlink:href=\"#trumbowyg-link\"></use></svg>',\n            'class': 'title-link',\n            href: '#' + $(this).attr('id'),\n            title: 'Permalink to ' + $(this).text()\n        }));\n    });\n\n    // Show star count\n    function setStarsCount(stars) {\n        $('.star-count').text(stars);\n    }\n\n    var date = new Date();\n    var starsKey = 'stars_' + date.getMonth() + '_' + date.getYear();\n    var stars = localStorage.getItem(starsKey);\n    if (!stars) {\n        $.ajax('https://api.github.com/repos/Alex-D/Trumbowyg', {\n            success: function (data) {\n                var stars = data.stargazers_count; // jshint ignore:line\n                localStorage.clear();\n                localStorage.setItem(starsKey, stars);\n                setStarsCount(stars);\n            }\n        });\n    } else {\n        setStarsCount(stars);\n    }\n\n    // Switch iframe src for demos\n    if ($('.main-demos').length > 0) {\n        $('.documentation-summary a').each(function() {\n            var demoHash = $(this).attr('href').replace('.html', '').replace(/[\\/.]/g, '-').replace(/^-*/g, '');\n            $(this).attr('data-hash', demoHash);\n            $(this).click(function() {\n                $('.main-demos iframe').attr('src', $(this).attr('href'));\n                window.location.hash = demoHash;\n                return false;\n            });\n        });\n        if (window.location.hash.length > 1) {\n            var demoHref = $('[data-hash=\"' + window.location.hash.replace('#', '') + '\"]').attr('href');\n            $('.main-demos iframe').attr('src', demoHref);\n        }\n    }\n})(jQuery);\n\n/* Google Analytics */\n// jshint ignore:start\n(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\nm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');\n\nga('set', 'anonymizeIp', true);\nga('create', 'UA-35470243-1', 'auto');\nga('send', 'pageview');\n"
  },
  {
    "path": "docs/js/vendor/highlight.js",
    "content": "/*!\n  Highlight.js v11.7.0 (git: 82688fad18)\n  (c) 2006-2022 undefined and other contributors\n  License: BSD-3-Clause\n */\nvar hljs=function(){\"use strict\";var e={exports:{}};function t(e){\n    return e instanceof Map?e.clear=e.delete=e.set=()=>{\n        throw Error(\"map is read-only\")}:e instanceof Set&&(e.add=e.clear=e.delete=()=>{\n        throw Error(\"set is read-only\")\n    }),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((n=>{var i=e[n]\n    ;\"object\"!=typeof i||Object.isFrozen(i)||t(i)})),e}\n    e.exports=t,e.exports.default=t;class n{constructor(e){\n        void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}\n        ignoreMatch(){this.isMatchIgnored=!0}}function i(e){\n        return e.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\").replace(/'/g,\"&#x27;\")\n    }function r(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t]\n    ;return t.forEach((e=>{for(const t in e)n[t]=e[t]})),n}\n    const s=e=>!!e.scope||e.sublanguage&&e.language;class o{constructor(e,t){\n        this.buffer=\"\",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){\n        this.buffer+=i(e)}openNode(e){if(!s(e))return;let t=\"\"\n    ;t=e.sublanguage?\"language-\"+e.language:((e,{prefix:t})=>{if(e.includes(\".\")){\n        const n=e.split(\".\")\n        ;return[`${t}${n.shift()}`,...n.map(((e,t)=>`${e}${\"_\".repeat(t+1)}`))].join(\" \")\n    }return`${t}${e}`})(e.scope,{prefix:this.classPrefix}),this.span(t)}\n        closeNode(e){s(e)&&(this.buffer+=\"</span>\")}value(){return this.buffer}span(e){\n            this.buffer+=`<span class=\"${e}\">`}}const a=(e={})=>{const t={children:[]}\n    ;return Object.assign(t,e),t};class c{constructor(){\n        this.rootNode=a(),this.stack=[this.rootNode]}get top(){\n        return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){\n        this.top.children.push(e)}openNode(e){const t=a({scope:e})\n    ;this.add(t),this.stack.push(t)}closeNode(){\n        if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){\n        for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}\n        walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){\n            return\"string\"==typeof t?e.addText(t):t.children&&(e.openNode(t),\n                t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){\n            \"string\"!=typeof e&&e.children&&(e.children.every((e=>\"string\"==typeof e))?e.children=[e.children.join(\"\")]:e.children.forEach((e=>{\n                c._collapse(e)})))}}class l extends c{constructor(e){super(),this.options=e}\n        addKeyword(e,t){\"\"!==e&&(this.openNode(t),this.addText(e),this.closeNode())}\n        addText(e){\"\"!==e&&this.add(e)}addSublanguage(e,t){const n=e.root\n        ;n.sublanguage=!0,n.language=t,this.add(n)}toHTML(){\n            return new o(this,this.options).value()}finalize(){return!0}}function g(e){\n        return e?\"string\"==typeof e?e:e.source:null}function d(e){return p(\"(?=\",e,\")\")}\n    function u(e){return p(\"(?:\",e,\")*\")}function h(e){return p(\"(?:\",e,\")?\")}\n    function p(...e){return e.map((e=>g(e))).join(\"\")}function f(...e){const t=(e=>{\n        const t=e[e.length-1]\n        ;return\"object\"==typeof t&&t.constructor===Object?(e.splice(e.length-1,1),t):{}\n    })(e);return\"(\"+(t.capture?\"\":\"?:\")+e.map((e=>g(e))).join(\"|\")+\")\"}\n    function b(e){return RegExp(e.toString()+\"|\").exec(\"\").length-1}\n    const m=/\\[(?:[^\\\\\\]]|\\\\.)*\\]|\\(\\??|\\\\([1-9][0-9]*)|\\\\./\n    ;function E(e,{joinWith:t}){let n=0;return e.map((e=>{n+=1;const t=n\n    ;let i=g(e),r=\"\";for(;i.length>0;){const e=m.exec(i);if(!e){r+=i;break}\n        r+=i.substring(0,e.index),\n            i=i.substring(e.index+e[0].length),\"\\\\\"===e[0][0]&&e[1]?r+=\"\\\\\"+(Number(e[1])+t):(r+=e[0],\n        \"(\"===e[0]&&n++)}return r})).map((e=>`(${e})`)).join(t)}\n    const x=\"[a-zA-Z]\\\\w*\",w=\"[a-zA-Z_]\\\\w*\",y=\"\\\\b\\\\d+(\\\\.\\\\d+)?\",_=\"(-?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)\",O=\"\\\\b(0b[01]+)\",v={\n        begin:\"\\\\\\\\[\\\\s\\\\S]\",relevance:0},N={scope:\"string\",begin:\"'\",end:\"'\",\n        illegal:\"\\\\n\",contains:[v]},k={scope:\"string\",begin:'\"',end:'\"',illegal:\"\\\\n\",\n        contains:[v]},M=(e,t,n={})=>{const i=r({scope:\"comment\",begin:e,end:t,\n        contains:[]},n);i.contains.push({scope:\"doctag\",\n        begin:\"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)\",\n        end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0})\n    ;const s=f(\"I\",\"a\",\"is\",\"so\",\"us\",\"to\",\"at\",\"if\",\"in\",\"it\",\"on\",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/)\n    ;return i.contains.push({begin:p(/[ ]+/,\"(\",s,/[.]?[:]?([.][ ]|[ ])/,\"){3}\")}),i\n    },S=M(\"//\",\"$\"),R=M(\"/\\\\*\",\"\\\\*/\"),j=M(\"#\",\"$\");var A=Object.freeze({\n        __proto__:null,MATCH_NOTHING_RE:/\\b\\B/,IDENT_RE:x,UNDERSCORE_IDENT_RE:w,\n        NUMBER_RE:y,C_NUMBER_RE:_,BINARY_NUMBER_RE:O,\n        RE_STARTERS_RE:\"!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~\",\n        SHEBANG:(e={})=>{const t=/^#![ ]*\\//\n        ;return e.binary&&(e.begin=p(t,/.*\\b/,e.binary,/\\b.*/)),r({scope:\"meta\",begin:t,\n            end:/$/,relevance:0,\"on:begin\":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)},\n        BACKSLASH_ESCAPE:v,APOS_STRING_MODE:N,QUOTE_STRING_MODE:k,PHRASAL_WORDS_MODE:{\n            begin:/\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b/\n        },COMMENT:M,C_LINE_COMMENT_MODE:S,C_BLOCK_COMMENT_MODE:R,HASH_COMMENT_MODE:j,\n        NUMBER_MODE:{scope:\"number\",begin:y,relevance:0},C_NUMBER_MODE:{scope:\"number\",\n            begin:_,relevance:0},BINARY_NUMBER_MODE:{scope:\"number\",begin:O,relevance:0},\n        REGEXP_MODE:{begin:/(?=\\/[^/\\n]*\\/)/,contains:[{scope:\"regexp\",begin:/\\//,\n                end:/\\/[gimuy]*/,illegal:/\\n/,contains:[v,{begin:/\\[/,end:/\\]/,relevance:0,\n                    contains:[v]}]}]},TITLE_MODE:{scope:\"title\",begin:x,relevance:0},\n        UNDERSCORE_TITLE_MODE:{scope:\"title\",begin:w,relevance:0},METHOD_GUARD:{\n            begin:\"\\\\.\\\\s*[a-zA-Z_]\\\\w*\",relevance:0},END_SAME_AS_BEGIN:e=>Object.assign(e,{\n            \"on:begin\":(e,t)=>{t.data._beginMatch=e[1]},\"on:end\":(e,t)=>{\n                t.data._beginMatch!==e[1]&&t.ignoreMatch()}})});function I(e,t){\n        \".\"===e.input[e.index-1]&&t.ignoreMatch()}function T(e,t){\n        void 0!==e.className&&(e.scope=e.className,delete e.className)}function L(e,t){\n        t&&e.beginKeywords&&(e.begin=\"\\\\b(\"+e.beginKeywords.split(\" \").join(\"|\")+\")(?!\\\\.)(?=\\\\b|\\\\s)\",\n            e.__beforeBegin=I,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,\n        void 0===e.relevance&&(e.relevance=0))}function B(e,t){\n        Array.isArray(e.illegal)&&(e.illegal=f(...e.illegal))}function D(e,t){\n        if(e.match){\n            if(e.begin||e.end)throw Error(\"begin & end are not supported with match\")\n                ;e.begin=e.match,delete e.match}}function H(e,t){\n        void 0===e.relevance&&(e.relevance=1)}const P=(e,t)=>{if(!e.beforeMatch)return\n            ;if(e.starts)throw Error(\"beforeMatch cannot be used with starts\")\n            ;const n=Object.assign({},e);Object.keys(e).forEach((t=>{delete e[t]\n        })),e.keywords=n.keywords,e.begin=p(n.beforeMatch,d(n.begin)),e.starts={\n            relevance:0,contains:[Object.assign(n,{endsParent:!0})]\n        },e.relevance=0,delete n.beforeMatch\n        },C=[\"of\",\"and\",\"for\",\"in\",\"not\",\"or\",\"if\",\"then\",\"parent\",\"list\",\"value\"]\n    ;function $(e,t,n=\"keyword\"){const i=Object.create(null)\n    ;return\"string\"==typeof e?r(n,e.split(\" \")):Array.isArray(e)?r(n,e):Object.keys(e).forEach((n=>{\n        Object.assign(i,$(e[n],t,n))})),i;function r(e,n){\n        t&&(n=n.map((e=>e.toLowerCase()))),n.forEach((t=>{const n=t.split(\"|\")\n        ;i[n[0]]=[e,U(n[0],n[1])]}))}}function U(e,t){\n        return t?Number(t):(e=>C.includes(e.toLowerCase()))(e)?0:1}const z={},K=e=>{\n        console.error(e)},W=(e,...t)=>{console.log(\"WARN: \"+e,...t)},X=(e,t)=>{\n        z[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),z[`${e}/${t}`]=!0)\n    },G=Error();function Z(e,t,{key:n}){let i=0;const r=e[n],s={},o={}\n    ;for(let e=1;e<=t.length;e++)o[e+i]=r[e],s[e+i]=!0,i+=b(t[e-1])\n    ;e[n]=o,e[n]._emit=s,e[n]._multi=!0}function F(e){(e=>{\n        e.scope&&\"object\"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope,\n            delete e.scope)})(e),\"string\"==typeof e.beginScope&&(e.beginScope={\n        _wrap:e.beginScope}),\"string\"==typeof e.endScope&&(e.endScope={_wrap:e.endScope\n    }),(e=>{if(Array.isArray(e.begin)){\n        if(e.skip||e.excludeBegin||e.returnBegin)throw K(\"skip, excludeBegin, returnBegin not compatible with beginScope: {}\"),\n            G\n            ;if(\"object\"!=typeof e.beginScope||null===e.beginScope)throw K(\"beginScope must be object\"),\n            G;Z(e,e.begin,{key:\"beginScope\"}),e.begin=E(e.begin,{joinWith:\"\"})}})(e),(e=>{\n        if(Array.isArray(e.end)){\n            if(e.skip||e.excludeEnd||e.returnEnd)throw K(\"skip, excludeEnd, returnEnd not compatible with endScope: {}\"),\n                G\n                ;if(\"object\"!=typeof e.endScope||null===e.endScope)throw K(\"endScope must be object\"),\n                G;Z(e,e.end,{key:\"endScope\"}),e.end=E(e.end,{joinWith:\"\"})}})(e)}function V(e){\n        function t(t,n){\n            return RegExp(g(t),\"m\"+(e.case_insensitive?\"i\":\"\")+(e.unicodeRegex?\"u\":\"\")+(n?\"g\":\"\"))\n        }class n{constructor(){\n            this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}\n            addRule(e,t){\n                t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]),\n                    this.matchAt+=b(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null)\n            ;const e=this.regexes.map((e=>e[1]));this.matcherRe=t(E(e,{joinWith:\"|\"\n            }),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex\n            ;const t=this.matcherRe.exec(e);if(!t)return null\n                ;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),i=this.matchIndexes[n]\n            ;return t.splice(0,n),Object.assign(t,i)}}class i{constructor(){\n            this.rules=[],this.multiRegexes=[],\n                this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){\n            if(this.multiRegexes[e])return this.multiRegexes[e];const t=new n\n            ;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))),\n                t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){\n            return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){\n            this.rules.push([e,t]),\"begin\"===t.type&&this.count++}exec(e){\n            const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex\n            ;let n=t.exec(e)\n            ;if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{\n                const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)}\n            return n&&(this.regexIndex+=n.position+1,\n            this.regexIndex===this.count&&this.considerAll()),n}}\n        if(e.compilerExtensions||(e.compilerExtensions=[]),\n        e.contains&&e.contains.includes(\"self\"))throw Error(\"ERR: contains `self` is not supported at the top-level of a language.  See documentation.\")\n            ;return e.classNameAliases=r(e.classNameAliases||{}),function n(s,o){const a=s\n        ;if(s.isCompiled)return a\n            ;[T,D,F,P].forEach((e=>e(s,o))),e.compilerExtensions.forEach((e=>e(s,o))),\n            s.__beforeBegin=null,[L,B,H].forEach((e=>e(s,o))),s.isCompiled=!0;let c=null\n        ;return\"object\"==typeof s.keywords&&s.keywords.$pattern&&(s.keywords=Object.assign({},s.keywords),\n            c=s.keywords.$pattern,\n            delete s.keywords.$pattern),c=c||/\\w+/,s.keywords&&(s.keywords=$(s.keywords,e.case_insensitive)),\n            a.keywordPatternRe=t(c,!0),\n        o&&(s.begin||(s.begin=/\\B|\\b/),a.beginRe=t(a.begin),s.end||s.endsWithParent||(s.end=/\\B|\\b/),\n        s.end&&(a.endRe=t(a.end)),\n            a.terminatorEnd=g(a.end)||\"\",s.endsWithParent&&o.terminatorEnd&&(a.terminatorEnd+=(s.end?\"|\":\"\")+o.terminatorEnd)),\n        s.illegal&&(a.illegalRe=t(s.illegal)),\n        s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((t=>r(e,{\n            variants:null},t)))),e.cachedVariants?e.cachedVariants:q(e)?r(e,{\n            starts:e.starts?r(e.starts):null\n        }):Object.isFrozen(e)?r(e):e))(\"self\"===e?s:e)))),s.contains.forEach((e=>{n(e,a)\n        })),s.starts&&n(s.starts,o),a.matcher=(e=>{const t=new i\n        ;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:\"begin\"\n        }))),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:\"end\"\n        }),e.illegal&&t.addRule(e.illegal,{type:\"illegal\"}),t})(a),a}(e)}function q(e){\n        return!!e&&(e.endsWithParent||q(e.starts))}class J extends Error{\n        constructor(e,t){super(e),this.name=\"HTMLInjectionError\",this.html=t}}\n    const Y=i,Q=r,ee=Symbol(\"nomatch\");var te=(t=>{\n        const i=Object.create(null),r=Object.create(null),s=[];let o=!0\n        ;const a=\"Could not find the language '{}', did you forget to load/include a language module?\",c={\n            disableAutodetect:!0,name:\"Plain text\",contains:[]};let g={\n            ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,\n            languageDetectRe:/\\blang(?:uage)?-([\\w-]+)\\b/i,classPrefix:\"hljs-\",\n            cssSelector:\"pre code\",languages:null,__emitter:l};function b(e){\n            return g.noHighlightRe.test(e)}function m(e,t,n){let i=\"\",r=\"\"\n        ;\"object\"==typeof t?(i=e,\n            n=t.ignoreIllegals,r=t.language):(X(\"10.7.0\",\"highlight(lang, code, ...args) has been deprecated.\"),\n            X(\"10.7.0\",\"Please use highlight(code, options) instead.\\nhttps://github.com/highlightjs/highlight.js/issues/2277\"),\n            r=e,i=t),void 0===n&&(n=!0);const s={code:i,language:r};k(\"before:highlight\",s)\n        ;const o=s.result?s.result:E(s.language,s.code,n)\n        ;return o.code=s.code,k(\"after:highlight\",o),o}function E(e,t,r,s){\n            const c=Object.create(null);function l(){if(!N.keywords)return void M.addText(S)\n                ;let e=0;N.keywordPatternRe.lastIndex=0;let t=N.keywordPatternRe.exec(S),n=\"\"\n            ;for(;t;){n+=S.substring(e,t.index)\n            ;const r=y.case_insensitive?t[0].toLowerCase():t[0],s=(i=r,N.keywords[i]);if(s){\n                const[e,i]=s\n                ;if(M.addText(n),n=\"\",c[r]=(c[r]||0)+1,c[r]<=7&&(R+=i),e.startsWith(\"_\"))n+=t[0];else{\n                    const n=y.classNameAliases[e]||e;M.addKeyword(t[0],n)}}else n+=t[0]\n            ;e=N.keywordPatternRe.lastIndex,t=N.keywordPatternRe.exec(S)}var i\n            ;n+=S.substring(e),M.addText(n)}function d(){null!=N.subLanguage?(()=>{\n                if(\"\"===S)return;let e=null;if(\"string\"==typeof N.subLanguage){\n                    if(!i[N.subLanguage])return void M.addText(S)\n                        ;e=E(N.subLanguage,S,!0,k[N.subLanguage]),k[N.subLanguage]=e._top\n                }else e=x(S,N.subLanguage.length?N.subLanguage:null)\n                ;N.relevance>0&&(R+=e.relevance),M.addSublanguage(e._emitter,e.language)\n            })():l(),S=\"\"}function u(e,t){let n=1;const i=t.length-1;for(;n<=i;){\n                if(!e._emit[n]){n++;continue}const i=y.classNameAliases[e[n]]||e[n],r=t[n]\n                ;i?M.addKeyword(r,i):(S=r,l(),S=\"\"),n++}}function h(e,t){\n                return e.scope&&\"string\"==typeof e.scope&&M.openNode(y.classNameAliases[e.scope]||e.scope),\n                e.beginScope&&(e.beginScope._wrap?(M.addKeyword(S,y.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap),\n                    S=\"\"):e.beginScope._multi&&(u(e.beginScope,t),S=\"\")),N=Object.create(e,{parent:{\n                        value:N}}),N}function p(e,t,i){let r=((e,t)=>{const n=e&&e.exec(t)\n            ;return n&&0===n.index})(e.endRe,i);if(r){if(e[\"on:end\"]){const i=new n(e)\n            ;e[\"on:end\"](t,i),i.isMatchIgnored&&(r=!1)}if(r){\n                for(;e.endsParent&&e.parent;)e=e.parent;return e}}\n                if(e.endsWithParent)return p(e.parent,t,i)}function f(e){\n                return 0===N.matcher.regexIndex?(S+=e[0],1):(I=!0,0)}function b(e){\n                const n=e[0],i=t.substring(e.index),r=p(N,e,i);if(!r)return ee;const s=N\n                ;N.endScope&&N.endScope._wrap?(d(),\n                    M.addKeyword(n,N.endScope._wrap)):N.endScope&&N.endScope._multi?(d(),\n                    u(N.endScope,e)):s.skip?S+=n:(s.returnEnd||s.excludeEnd||(S+=n),\n                    d(),s.excludeEnd&&(S=n));do{\n                    N.scope&&M.closeNode(),N.skip||N.subLanguage||(R+=N.relevance),N=N.parent\n                }while(N!==r.parent);return r.starts&&h(r.starts,e),s.returnEnd?0:n.length}\n            let m={};function w(i,s){const a=s&&s[0];if(S+=i,null==a)return d(),0\n                ;if(\"begin\"===m.type&&\"end\"===s.type&&m.index===s.index&&\"\"===a){\n                if(S+=t.slice(s.index,s.index+1),!o){const t=Error(`0 width match regex (${e})`)\n                ;throw t.languageName=e,t.badRule=m.rule,t}return 1}\n                if(m=s,\"begin\"===s.type)return(e=>{\n                    const t=e[0],i=e.rule,r=new n(i),s=[i.__beforeBegin,i[\"on:begin\"]]\n                    ;for(const n of s)if(n&&(n(e,r),r.isMatchIgnored))return f(t)\n                        ;return i.skip?S+=t:(i.excludeBegin&&(S+=t),\n                        d(),i.returnBegin||i.excludeBegin||(S=t)),h(i,e),i.returnBegin?0:t.length})(s)\n                    ;if(\"illegal\"===s.type&&!r){\n                    const e=Error('Illegal lexeme \"'+a+'\" for mode \"'+(N.scope||\"<unnamed>\")+'\"')\n                    ;throw e.mode=N,e}if(\"end\"===s.type){const e=b(s);if(e!==ee)return e}\n                if(\"illegal\"===s.type&&\"\"===a)return 1\n                    ;if(A>1e5&&A>3*s.index)throw Error(\"potential infinite loop, way more iterations than matches\")\n                    ;return S+=a,a.length}const y=O(e)\n            ;if(!y)throw K(a.replace(\"{}\",e)),Error('Unknown language: \"'+e+'\"')\n                ;const _=V(y);let v=\"\",N=s||_;const k={},M=new g.__emitter(g);(()=>{const e=[]\n            ;for(let t=N;t!==y;t=t.parent)t.scope&&e.unshift(t.scope)\n            ;e.forEach((e=>M.openNode(e)))})();let S=\"\",R=0,j=0,A=0,I=!1;try{\n                for(N.matcher.considerAll();;){\n                    A++,I?I=!1:N.matcher.considerAll(),N.matcher.lastIndex=j\n                    ;const e=N.matcher.exec(t);if(!e)break;const n=w(t.substring(j,e.index),e)\n                    ;j=e.index+n}\n                return w(t.substring(j)),M.closeAllNodes(),M.finalize(),v=M.toHTML(),{\n                    language:e,value:v,relevance:R,illegal:!1,_emitter:M,_top:N}}catch(n){\n                if(n.message&&n.message.includes(\"Illegal\"))return{language:e,value:Y(t),\n                    illegal:!0,relevance:0,_illegalBy:{message:n.message,index:j,\n                        context:t.slice(j-100,j+100),mode:n.mode,resultSoFar:v},_emitter:M};if(o)return{\n                    language:e,value:Y(t),illegal:!1,relevance:0,errorRaised:n,_emitter:M,_top:N}\n                    ;throw n}}function x(e,t){t=t||g.languages||Object.keys(i);const n=(e=>{\n            const t={value:Y(e),illegal:!1,relevance:0,_top:c,_emitter:new g.__emitter(g)}\n            ;return t._emitter.addText(e),t})(e),r=t.filter(O).filter(N).map((t=>E(t,e,!1)))\n        ;r.unshift(n);const s=r.sort(((e,t)=>{\n            if(e.relevance!==t.relevance)return t.relevance-e.relevance\n                ;if(e.language&&t.language){if(O(e.language).supersetOf===t.language)return 1\n                ;if(O(t.language).supersetOf===e.language)return-1}return 0})),[o,a]=s,l=o\n        ;return l.secondBest=a,l}function w(e){let t=null;const n=(e=>{\n            let t=e.className+\" \";t+=e.parentNode?e.parentNode.className:\"\"\n            ;const n=g.languageDetectRe.exec(t);if(n){const t=O(n[1])\n            ;return t||(W(a.replace(\"{}\",n[1])),\n                W(\"Falling back to no-highlight mode for this block.\",e)),t?n[1]:\"no-highlight\"}\n            return t.split(/\\s+/).find((e=>b(e)||O(e)))})(e);if(b(n))return\n            ;if(k(\"before:highlightElement\",{el:e,language:n\n        }),e.children.length>0&&(g.ignoreUnescapedHTML||(console.warn(\"One of your code blocks includes unescaped HTML. This is a potentially serious security risk.\"),\n            console.warn(\"https://github.com/highlightjs/highlight.js/wiki/security\"),\n            console.warn(\"The element with unescaped HTML:\"),\n            console.warn(e)),g.throwUnescapedHTML))throw new J(\"One of your code blocks includes unescaped HTML.\",e.innerHTML)\n            ;t=e;const i=t.textContent,s=n?m(i,{language:n,ignoreIllegals:!0}):x(i)\n        ;e.innerHTML=s.value,((e,t,n)=>{const i=t&&r[t]||n\n        ;e.classList.add(\"hljs\"),e.classList.add(\"language-\"+i)\n        })(e,n,s.language),e.result={language:s.language,re:s.relevance,\n            relevance:s.relevance},s.secondBest&&(e.secondBest={\n            language:s.secondBest.language,relevance:s.secondBest.relevance\n        }),k(\"after:highlightElement\",{el:e,result:s,text:i})}let y=!1;function _(){\n            \"loading\"!==document.readyState?document.querySelectorAll(g.cssSelector).forEach(w):y=!0\n        }function O(e){return e=(e||\"\").toLowerCase(),i[e]||i[r[e]]}\n        function v(e,{languageName:t}){\"string\"==typeof e&&(e=[e]),e.forEach((e=>{\n            r[e.toLowerCase()]=t}))}function N(e){const t=O(e)\n        ;return t&&!t.disableAutodetect}function k(e,t){const n=e;s.forEach((e=>{\n            e[n]&&e[n](t)}))}\n        \"undefined\"!=typeof window&&window.addEventListener&&window.addEventListener(\"DOMContentLoaded\",(()=>{\n            y&&_()}),!1),Object.assign(t,{highlight:m,highlightAuto:x,highlightAll:_,\n            highlightElement:w,\n            highlightBlock:e=>(X(\"10.7.0\",\"highlightBlock will be removed entirely in v12.0\"),\n                X(\"10.7.0\",\"Please use highlightElement now.\"),w(e)),configure:e=>{g=Q(g,e)},\n            initHighlighting:()=>{\n                _(),X(\"10.6.0\",\"initHighlighting() deprecated.  Use highlightAll() now.\")},\n            initHighlightingOnLoad:()=>{\n                _(),X(\"10.6.0\",\"initHighlightingOnLoad() deprecated.  Use highlightAll() now.\")\n            },registerLanguage:(e,n)=>{let r=null;try{r=n(t)}catch(t){\n                if(K(\"Language definition for '{}' could not be registered.\".replace(\"{}\",e)),\n                    !o)throw t;K(t),r=c}\n                r.name||(r.name=e),i[e]=r,r.rawDefinition=n.bind(null,t),r.aliases&&v(r.aliases,{\n                    languageName:e})},unregisterLanguage:e=>{delete i[e]\n            ;for(const t of Object.keys(r))r[t]===e&&delete r[t]},\n            listLanguages:()=>Object.keys(i),getLanguage:O,registerAliases:v,\n            autoDetection:N,inherit:Q,addPlugin:e=>{(e=>{\n                e[\"before:highlightBlock\"]&&!e[\"before:highlightElement\"]&&(e[\"before:highlightElement\"]=t=>{\n                    e[\"before:highlightBlock\"](Object.assign({block:t.el},t))\n                }),e[\"after:highlightBlock\"]&&!e[\"after:highlightElement\"]&&(e[\"after:highlightElement\"]=t=>{\n                    e[\"after:highlightBlock\"](Object.assign({block:t.el},t))})})(e),s.push(e)}\n        }),t.debugMode=()=>{o=!1},t.safeMode=()=>{o=!0\n        },t.versionString=\"11.7.0\",t.regex={concat:p,lookahead:d,either:f,optional:h,\n            anyNumberOfTimes:u};for(const t in A)\"object\"==typeof A[t]&&e.exports(A[t])\n        ;return Object.assign(t,A),t})({});return te}()\n;\"object\"==typeof exports&&\"undefined\"!=typeof module&&(module.exports=hljs);/*! `scss` grammar compiled for Highlight.js 11.7.0 */\n(()=>{var e=(()=>{\"use strict\"\n;const e=[\"a\",\"abbr\",\"address\",\"article\",\"aside\",\"audio\",\"b\",\"blockquote\",\"body\",\"button\",\"canvas\",\"caption\",\"cite\",\"code\",\"dd\",\"del\",\"details\",\"dfn\",\"div\",\"dl\",\"dt\",\"em\",\"fieldset\",\"figcaption\",\"figure\",\"footer\",\"form\",\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\",\"header\",\"hgroup\",\"html\",\"i\",\"iframe\",\"img\",\"input\",\"ins\",\"kbd\",\"label\",\"legend\",\"li\",\"main\",\"mark\",\"menu\",\"nav\",\"object\",\"ol\",\"p\",\"q\",\"quote\",\"samp\",\"section\",\"span\",\"strong\",\"summary\",\"sup\",\"table\",\"tbody\",\"td\",\"textarea\",\"tfoot\",\"th\",\"thead\",\"time\",\"tr\",\"ul\",\"var\",\"video\"],r=[\"any-hover\",\"any-pointer\",\"aspect-ratio\",\"color\",\"color-gamut\",\"color-index\",\"device-aspect-ratio\",\"device-height\",\"device-width\",\"display-mode\",\"forced-colors\",\"grid\",\"height\",\"hover\",\"inverted-colors\",\"monochrome\",\"orientation\",\"overflow-block\",\"overflow-inline\",\"pointer\",\"prefers-color-scheme\",\"prefers-contrast\",\"prefers-reduced-motion\",\"prefers-reduced-transparency\",\"resolution\",\"scan\",\"scripting\",\"update\",\"width\",\"min-width\",\"max-width\",\"min-height\",\"max-height\"],i=[\"active\",\"any-link\",\"blank\",\"checked\",\"current\",\"default\",\"defined\",\"dir\",\"disabled\",\"drop\",\"empty\",\"enabled\",\"first\",\"first-child\",\"first-of-type\",\"fullscreen\",\"future\",\"focus\",\"focus-visible\",\"focus-within\",\"has\",\"host\",\"host-context\",\"hover\",\"indeterminate\",\"in-range\",\"invalid\",\"is\",\"lang\",\"last-child\",\"last-of-type\",\"left\",\"link\",\"local-link\",\"not\",\"nth-child\",\"nth-col\",\"nth-last-child\",\"nth-last-col\",\"nth-last-of-type\",\"nth-of-type\",\"only-child\",\"only-of-type\",\"optional\",\"out-of-range\",\"past\",\"placeholder-shown\",\"read-only\",\"read-write\",\"required\",\"right\",\"root\",\"scope\",\"target\",\"target-within\",\"user-invalid\",\"valid\",\"visited\",\"where\"],t=[\"after\",\"backdrop\",\"before\",\"cue\",\"cue-region\",\"first-letter\",\"first-line\",\"grammar-error\",\"marker\",\"part\",\"placeholder\",\"selection\",\"slotted\",\"spelling-error\"],o=[\"align-content\",\"align-items\",\"align-self\",\"all\",\"animation\",\"animation-delay\",\"animation-direction\",\"animation-duration\",\"animation-fill-mode\",\"animation-iteration-count\",\"animation-name\",\"animation-play-state\",\"animation-timing-function\",\"backface-visibility\",\"background\",\"background-attachment\",\"background-blend-mode\",\"background-clip\",\"background-color\",\"background-image\",\"background-origin\",\"background-position\",\"background-repeat\",\"background-size\",\"block-size\",\"border\",\"border-block\",\"border-block-color\",\"border-block-end\",\"border-block-end-color\",\"border-block-end-style\",\"border-block-end-width\",\"border-block-start\",\"border-block-start-color\",\"border-block-start-style\",\"border-block-start-width\",\"border-block-style\",\"border-block-width\",\"border-bottom\",\"border-bottom-color\",\"border-bottom-left-radius\",\"border-bottom-right-radius\",\"border-bottom-style\",\"border-bottom-width\",\"border-collapse\",\"border-color\",\"border-image\",\"border-image-outset\",\"border-image-repeat\",\"border-image-slice\",\"border-image-source\",\"border-image-width\",\"border-inline\",\"border-inline-color\",\"border-inline-end\",\"border-inline-end-color\",\"border-inline-end-style\",\"border-inline-end-width\",\"border-inline-start\",\"border-inline-start-color\",\"border-inline-start-style\",\"border-inline-start-width\",\"border-inline-style\",\"border-inline-width\",\"border-left\",\"border-left-color\",\"border-left-style\",\"border-left-width\",\"border-radius\",\"border-right\",\"border-right-color\",\"border-right-style\",\"border-right-width\",\"border-spacing\",\"border-style\",\"border-top\",\"border-top-color\",\"border-top-left-radius\",\"border-top-right-radius\",\"border-top-style\",\"border-top-width\",\"border-width\",\"bottom\",\"box-decoration-break\",\"box-shadow\",\"box-sizing\",\"break-after\",\"break-before\",\"break-inside\",\"caption-side\",\"caret-color\",\"clear\",\"clip\",\"clip-path\",\"clip-rule\",\"color\",\"column-count\",\"column-fill\",\"column-gap\",\"column-rule\",\"column-rule-color\",\"column-rule-style\",\"column-rule-width\",\"column-span\",\"column-width\",\"columns\",\"contain\",\"content\",\"content-visibility\",\"counter-increment\",\"counter-reset\",\"cue\",\"cue-after\",\"cue-before\",\"cursor\",\"direction\",\"display\",\"empty-cells\",\"filter\",\"flex\",\"flex-basis\",\"flex-direction\",\"flex-flow\",\"flex-grow\",\"flex-shrink\",\"flex-wrap\",\"float\",\"flow\",\"font\",\"font-display\",\"font-family\",\"font-feature-settings\",\"font-kerning\",\"font-language-override\",\"font-size\",\"font-size-adjust\",\"font-smoothing\",\"font-stretch\",\"font-style\",\"font-synthesis\",\"font-variant\",\"font-variant-caps\",\"font-variant-east-asian\",\"font-variant-ligatures\",\"font-variant-numeric\",\"font-variant-position\",\"font-variation-settings\",\"font-weight\",\"gap\",\"glyph-orientation-vertical\",\"grid\",\"grid-area\",\"grid-auto-columns\",\"grid-auto-flow\",\"grid-auto-rows\",\"grid-column\",\"grid-column-end\",\"grid-column-start\",\"grid-gap\",\"grid-row\",\"grid-row-end\",\"grid-row-start\",\"grid-template\",\"grid-template-areas\",\"grid-template-columns\",\"grid-template-rows\",\"hanging-punctuation\",\"height\",\"hyphens\",\"icon\",\"image-orientation\",\"image-rendering\",\"image-resolution\",\"ime-mode\",\"inline-size\",\"isolation\",\"justify-content\",\"left\",\"letter-spacing\",\"line-break\",\"line-height\",\"list-style\",\"list-style-image\",\"list-style-position\",\"list-style-type\",\"margin\",\"margin-block\",\"margin-block-end\",\"margin-block-start\",\"margin-bottom\",\"margin-inline\",\"margin-inline-end\",\"margin-inline-start\",\"margin-left\",\"margin-right\",\"margin-top\",\"marks\",\"mask\",\"mask-border\",\"mask-border-mode\",\"mask-border-outset\",\"mask-border-repeat\",\"mask-border-slice\",\"mask-border-source\",\"mask-border-width\",\"mask-clip\",\"mask-composite\",\"mask-image\",\"mask-mode\",\"mask-origin\",\"mask-position\",\"mask-repeat\",\"mask-size\",\"mask-type\",\"max-block-size\",\"max-height\",\"max-inline-size\",\"max-width\",\"min-block-size\",\"min-height\",\"min-inline-size\",\"min-width\",\"mix-blend-mode\",\"nav-down\",\"nav-index\",\"nav-left\",\"nav-right\",\"nav-up\",\"none\",\"normal\",\"object-fit\",\"object-position\",\"opacity\",\"order\",\"orphans\",\"outline\",\"outline-color\",\"outline-offset\",\"outline-style\",\"outline-width\",\"overflow\",\"overflow-wrap\",\"overflow-x\",\"overflow-y\",\"padding\",\"padding-block\",\"padding-block-end\",\"padding-block-start\",\"padding-bottom\",\"padding-inline\",\"padding-inline-end\",\"padding-inline-start\",\"padding-left\",\"padding-right\",\"padding-top\",\"page-break-after\",\"page-break-before\",\"page-break-inside\",\"pause\",\"pause-after\",\"pause-before\",\"perspective\",\"perspective-origin\",\"pointer-events\",\"position\",\"quotes\",\"resize\",\"rest\",\"rest-after\",\"rest-before\",\"right\",\"row-gap\",\"scroll-margin\",\"scroll-margin-block\",\"scroll-margin-block-end\",\"scroll-margin-block-start\",\"scroll-margin-bottom\",\"scroll-margin-inline\",\"scroll-margin-inline-end\",\"scroll-margin-inline-start\",\"scroll-margin-left\",\"scroll-margin-right\",\"scroll-margin-top\",\"scroll-padding\",\"scroll-padding-block\",\"scroll-padding-block-end\",\"scroll-padding-block-start\",\"scroll-padding-bottom\",\"scroll-padding-inline\",\"scroll-padding-inline-end\",\"scroll-padding-inline-start\",\"scroll-padding-left\",\"scroll-padding-right\",\"scroll-padding-top\",\"scroll-snap-align\",\"scroll-snap-stop\",\"scroll-snap-type\",\"scrollbar-color\",\"scrollbar-gutter\",\"scrollbar-width\",\"shape-image-threshold\",\"shape-margin\",\"shape-outside\",\"speak\",\"speak-as\",\"src\",\"tab-size\",\"table-layout\",\"text-align\",\"text-align-all\",\"text-align-last\",\"text-combine-upright\",\"text-decoration\",\"text-decoration-color\",\"text-decoration-line\",\"text-decoration-style\",\"text-emphasis\",\"text-emphasis-color\",\"text-emphasis-position\",\"text-emphasis-style\",\"text-indent\",\"text-justify\",\"text-orientation\",\"text-overflow\",\"text-rendering\",\"text-shadow\",\"text-transform\",\"text-underline-position\",\"top\",\"transform\",\"transform-box\",\"transform-origin\",\"transform-style\",\"transition\",\"transition-delay\",\"transition-duration\",\"transition-property\",\"transition-timing-function\",\"unicode-bidi\",\"vertical-align\",\"visibility\",\"voice-balance\",\"voice-duration\",\"voice-family\",\"voice-pitch\",\"voice-range\",\"voice-rate\",\"voice-stress\",\"voice-volume\",\"white-space\",\"widows\",\"width\",\"will-change\",\"word-break\",\"word-spacing\",\"word-wrap\",\"writing-mode\",\"z-index\"].reverse()\n;return n=>{const a=(e=>({IMPORTANT:{scope:\"meta\",begin:\"!important\"},\n    BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:\"number\",\n        begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\\b/},FUNCTION_DISPATCH:{\n        className:\"built_in\",begin:/[\\w-]+(?=\\()/},ATTRIBUTE_SELECTOR_MODE:{\n        scope:\"selector-attr\",begin:/\\[/,end:/\\]/,illegal:\"$\",\n        contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{\n        scope:\"number\",\n        begin:e.NUMBER_RE+\"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?\",\n        relevance:0},CSS_VARIABLE:{className:\"attr\",begin:/--[A-Za-z][A-Za-z0-9_-]*/}\n}))(n),l=t,s=i,d=\"@[a-z-]+\",c={className:\"variable\",\n    begin:\"(\\\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\\\b\",relevance:0};return{name:\"SCSS\",\n    case_insensitive:!0,illegal:\"[=/|']\",\n    contains:[n.C_LINE_COMMENT_MODE,n.C_BLOCK_COMMENT_MODE,a.CSS_NUMBER_MODE,{\n        className:\"selector-id\",begin:\"#[A-Za-z0-9_-]+\",relevance:0},{\n        className:\"selector-class\",begin:\"\\\\.[A-Za-z0-9_-]+\",relevance:0\n    },a.ATTRIBUTE_SELECTOR_MODE,{className:\"selector-tag\",\n        begin:\"\\\\b(\"+e.join(\"|\")+\")\\\\b\",relevance:0},{className:\"selector-pseudo\",\n        begin:\":(\"+s.join(\"|\")+\")\"},{className:\"selector-pseudo\",\n        begin:\":(:)?(\"+l.join(\"|\")+\")\"},c,{begin:/\\(/,end:/\\)/,\n        contains:[a.CSS_NUMBER_MODE]},a.CSS_VARIABLE,{className:\"attribute\",\n        begin:\"\\\\b(\"+o.join(\"|\")+\")\\\\b\"},{\n        begin:\"\\\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\\\b\"\n    },{begin:/:/,end:/[;}{]/,relevance:0,\n        contains:[a.BLOCK_COMMENT,c,a.HEXCOLOR,a.CSS_NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,a.IMPORTANT,a.FUNCTION_DISPATCH]\n    },{begin:\"@(page|font-face)\",keywords:{$pattern:d,keyword:\"@page @font-face\"}},{\n        begin:\"@\",end:\"[{;]\",returnBegin:!0,keywords:{$pattern:/[a-z-]+/,\n            keyword:\"and or not only\",attribute:r.join(\" \")},contains:[{begin:d,\n            className:\"keyword\"},{begin:/[a-z-]+(?=:)/,className:\"attribute\"\n        },c,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,a.HEXCOLOR,a.CSS_NUMBER_MODE]\n    },a.FUNCTION_DISPATCH]}}})();hljs.registerLanguage(\"scss\",e)})();/*! `javascript` grammar compiled for Highlight.js 11.7.0 */\n(()=>{var e=(()=>{\"use strict\"\n    ;const e=\"[A-Za-z$_][0-9A-Za-z$_]*\",n=[\"as\",\"in\",\"of\",\"if\",\"for\",\"while\",\"finally\",\"var\",\"new\",\"function\",\"do\",\"return\",\"void\",\"else\",\"break\",\"catch\",\"instanceof\",\"with\",\"throw\",\"case\",\"default\",\"try\",\"switch\",\"continue\",\"typeof\",\"delete\",\"let\",\"yield\",\"const\",\"class\",\"debugger\",\"async\",\"await\",\"static\",\"import\",\"from\",\"export\",\"extends\"],a=[\"true\",\"false\",\"null\",\"undefined\",\"NaN\",\"Infinity\"],t=[\"Object\",\"Function\",\"Boolean\",\"Symbol\",\"Math\",\"Date\",\"Number\",\"BigInt\",\"String\",\"RegExp\",\"Array\",\"Float32Array\",\"Float64Array\",\"Int8Array\",\"Uint8Array\",\"Uint8ClampedArray\",\"Int16Array\",\"Int32Array\",\"Uint16Array\",\"Uint32Array\",\"BigInt64Array\",\"BigUint64Array\",\"Set\",\"Map\",\"WeakSet\",\"WeakMap\",\"ArrayBuffer\",\"SharedArrayBuffer\",\"Atomics\",\"DataView\",\"JSON\",\"Promise\",\"Generator\",\"GeneratorFunction\",\"AsyncFunction\",\"Reflect\",\"Proxy\",\"Intl\",\"WebAssembly\"],s=[\"Error\",\"EvalError\",\"InternalError\",\"RangeError\",\"ReferenceError\",\"SyntaxError\",\"TypeError\",\"URIError\"],r=[\"setInterval\",\"setTimeout\",\"clearInterval\",\"clearTimeout\",\"require\",\"exports\",\"eval\",\"isFinite\",\"isNaN\",\"parseFloat\",\"parseInt\",\"decodeURI\",\"decodeURIComponent\",\"encodeURI\",\"encodeURIComponent\",\"escape\",\"unescape\"],c=[\"arguments\",\"this\",\"super\",\"console\",\"window\",\"document\",\"localStorage\",\"module\",\"global\"],i=[].concat(r,t,s)\n    ;return o=>{const l=o.regex,b=e,d={begin:/<[A-Za-z0-9\\\\._:-]+/,\n            end:/\\/[A-Za-z0-9\\\\._:-]+>|\\/>/,isTrulyOpeningTag:(e,n)=>{\n                const a=e[0].length+e.index,t=e.input[a]\n                ;if(\"<\"===t||\",\"===t)return void n.ignoreMatch();let s\n                ;\">\"===t&&(((e,{after:n})=>{const a=\"</\"+e[0].slice(1)\n                ;return-1!==e.input.indexOf(a,n)})(e,{after:a})||n.ignoreMatch())\n                ;const r=e.input.substring(a)\n                ;((s=r.match(/^\\s*=/))||(s=r.match(/^\\s+extends\\s+/))&&0===s.index)&&n.ignoreMatch()\n            }},g={$pattern:e,keyword:n,literal:a,built_in:i,\"variable.language\":c\n        },u=\"\\\\.([0-9](_?[0-9])*)\",m=\"0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*\",E={\n            className:\"number\",variants:[{\n                begin:`(\\\\b(${m})((${u})|\\\\.)?|(${u}))[eE][+-]?([0-9](_?[0-9])*)\\\\b`},{\n                begin:`\\\\b(${m})\\\\b((${u})\\\\b|\\\\.)?|(${u})\\\\b`},{\n                begin:\"\\\\b(0|[1-9](_?[0-9])*)n\\\\b\"},{\n                begin:\"\\\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\\\b\"},{\n                begin:\"\\\\b0[bB][0-1](_?[0-1])*n?\\\\b\"},{begin:\"\\\\b0[oO][0-7](_?[0-7])*n?\\\\b\"},{\n                begin:\"\\\\b0[0-7]+n?\\\\b\"}],relevance:0},A={className:\"subst\",begin:\"\\\\$\\\\{\",\n            end:\"\\\\}\",keywords:g,contains:[]},y={begin:\"html`\",end:\"\",starts:{end:\"`\",\n                returnEnd:!1,contains:[o.BACKSLASH_ESCAPE,A],subLanguage:\"xml\"}},N={\n            begin:\"css`\",end:\"\",starts:{end:\"`\",returnEnd:!1,\n                contains:[o.BACKSLASH_ESCAPE,A],subLanguage:\"css\"}},_={className:\"string\",\n            begin:\"`\",end:\"`\",contains:[o.BACKSLASH_ESCAPE,A]},h={className:\"comment\",\n            variants:[o.COMMENT(/\\/\\*\\*(?!\\/)/,\"\\\\*/\",{relevance:0,contains:[{\n                    begin:\"(?=@[A-Za-z]+)\",relevance:0,contains:[{className:\"doctag\",\n                        begin:\"@[A-Za-z]+\"},{className:\"type\",begin:\"\\\\{\",end:\"\\\\}\",excludeEnd:!0,\n                        excludeBegin:!0,relevance:0},{className:\"variable\",begin:b+\"(?=\\\\s*(-)|$)\",\n                        endsParent:!0,relevance:0},{begin:/(?=[^\\n])\\s/,relevance:0}]}]\n            }),o.C_BLOCK_COMMENT_MODE,o.C_LINE_COMMENT_MODE]\n        },f=[o.APOS_STRING_MODE,o.QUOTE_STRING_MODE,y,N,_,{match:/\\$\\d+/},E]\n    ;A.contains=f.concat({begin:/\\{/,end:/\\}/,keywords:g,contains:[\"self\"].concat(f)\n    });const v=[].concat(h,A.contains),p=v.concat([{begin:/\\(/,end:/\\)/,keywords:g,\n        contains:[\"self\"].concat(v)}]),S={className:\"params\",begin:/\\(/,end:/\\)/,\n        excludeBegin:!0,excludeEnd:!0,keywords:g,contains:p},w={variants:[{\n            match:[/class/,/\\s+/,b,/\\s+/,/extends/,/\\s+/,l.concat(b,\"(\",l.concat(/\\./,b),\")*\")],\n            scope:{1:\"keyword\",3:\"title.class\",5:\"keyword\",7:\"title.class.inherited\"}},{\n            match:[/class/,/\\s+/,b],scope:{1:\"keyword\",3:\"title.class\"}}]},R={relevance:0,\n        match:l.either(/\\bJSON/,/\\b[A-Z][a-z]+([A-Z][a-z]*|\\d)*/,/\\b[A-Z]{2,}([A-Z][a-z]+|\\d)+([A-Z][a-z]*)*/,/\\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\\d)*([A-Z][a-z]*)*/),\n        className:\"title.class\",keywords:{_:[...t,...s]}},O={variants:[{\n            match:[/function/,/\\s+/,b,/(?=\\s*\\()/]},{match:[/function/,/\\s*(?=\\()/]}],\n        className:{1:\"keyword\",3:\"title.function\"},label:\"func.def\",contains:[S],\n        illegal:/%/},k={\n        match:l.concat(/\\b/,(I=[...r,\"super\",\"import\"],l.concat(\"(?!\",I.join(\"|\"),\")\")),b,l.lookahead(/\\(/)),\n        className:\"title.function\",relevance:0};var I;const x={\n            begin:l.concat(/\\./,l.lookahead(l.concat(b,/(?![0-9A-Za-z$_(])/))),end:b,\n            excludeBegin:!0,keywords:\"prototype\",className:\"property\",relevance:0},T={\n            match:[/get|set/,/\\s+/,b,/(?=\\()/],className:{1:\"keyword\",3:\"title.function\"},\n            contains:[{begin:/\\(\\)/},S]\n        },C=\"(\\\\([^()]*(\\\\([^()]*(\\\\([^()]*\\\\)[^()]*)*\\\\)[^()]*)*\\\\)|\"+o.UNDERSCORE_IDENT_RE+\")\\\\s*=>\",M={\n            match:[/const|var|let/,/\\s+/,b,/\\s*/,/=\\s*/,/(async\\s*)?/,l.lookahead(C)],\n            keywords:\"async\",className:{1:\"keyword\",3:\"title.function\"},contains:[S]}\n    ;return{name:\"Javascript\",aliases:[\"js\",\"jsx\",\"mjs\",\"cjs\"],keywords:g,exports:{\n            PARAMS_CONTAINS:p,CLASS_REFERENCE:R},illegal:/#(?![$_A-z])/,\n        contains:[o.SHEBANG({label:\"shebang\",binary:\"node\",relevance:5}),{\n            label:\"use_strict\",className:\"meta\",relevance:10,\n            begin:/^\\s*['\"]use (strict|asm)['\"]/\n        },o.APOS_STRING_MODE,o.QUOTE_STRING_MODE,y,N,_,h,{match:/\\$\\d+/},E,R,{\n            className:\"attr\",begin:b+l.lookahead(\":\"),relevance:0},M,{\n            begin:\"(\"+o.RE_STARTERS_RE+\"|\\\\b(case|return|throw)\\\\b)\\\\s*\",\n            keywords:\"return throw case\",relevance:0,contains:[h,o.REGEXP_MODE,{\n                className:\"function\",begin:C,returnBegin:!0,end:\"\\\\s*=>\",contains:[{\n                    className:\"params\",variants:[{begin:o.UNDERSCORE_IDENT_RE,relevance:0},{\n                        className:null,begin:/\\(\\s*\\)/,skip:!0},{begin:/\\(/,end:/\\)/,excludeBegin:!0,\n                        excludeEnd:!0,keywords:g,contains:p}]}]},{begin:/,/,relevance:0},{match:/\\s+/,\n                relevance:0},{variants:[{begin:\"<>\",end:\"</>\"},{\n                    match:/<[A-Za-z0-9\\\\._:-]+\\s*\\/>/},{begin:d.begin,\n                    \"on:begin\":d.isTrulyOpeningTag,end:d.end}],subLanguage:\"xml\",contains:[{\n                    begin:d.begin,end:d.end,skip:!0,contains:[\"self\"]}]}]},O,{\n            beginKeywords:\"while if switch catch for\"},{\n            begin:\"\\\\b(?!function)\"+o.UNDERSCORE_IDENT_RE+\"\\\\([^()]*(\\\\([^()]*(\\\\([^()]*\\\\)[^()]*)*\\\\)[^()]*)*\\\\)\\\\s*\\\\{\",\n            returnBegin:!0,label:\"func.def\",contains:[S,o.inherit(o.TITLE_MODE,{begin:b,\n                className:\"title.function\"})]},{match:/\\.\\.\\./,relevance:0},x,{match:\"\\\\$\"+b,\n            relevance:0},{match:[/\\bconstructor(?=\\s*\\()/],className:{1:\"title.function\"},\n            contains:[S]},k,{relevance:0,match:/\\b[A-Z][A-Z_0-9]+\\b/,\n            className:\"variable.constant\"},w,T,{match:/\\$[(.]/}]}}})()\n;hljs.registerLanguage(\"javascript\",e)})();/*! `typescript` grammar compiled for Highlight.js 11.7.0 */\n(()=>{var e=(()=>{\"use strict\"\n    ;const e=\"[A-Za-z$_][0-9A-Za-z$_]*\",n=[\"as\",\"in\",\"of\",\"if\",\"for\",\"while\",\"finally\",\"var\",\"new\",\"function\",\"do\",\"return\",\"void\",\"else\",\"break\",\"catch\",\"instanceof\",\"with\",\"throw\",\"case\",\"default\",\"try\",\"switch\",\"continue\",\"typeof\",\"delete\",\"let\",\"yield\",\"const\",\"class\",\"debugger\",\"async\",\"await\",\"static\",\"import\",\"from\",\"export\",\"extends\"],a=[\"true\",\"false\",\"null\",\"undefined\",\"NaN\",\"Infinity\"],t=[\"Object\",\"Function\",\"Boolean\",\"Symbol\",\"Math\",\"Date\",\"Number\",\"BigInt\",\"String\",\"RegExp\",\"Array\",\"Float32Array\",\"Float64Array\",\"Int8Array\",\"Uint8Array\",\"Uint8ClampedArray\",\"Int16Array\",\"Int32Array\",\"Uint16Array\",\"Uint32Array\",\"BigInt64Array\",\"BigUint64Array\",\"Set\",\"Map\",\"WeakSet\",\"WeakMap\",\"ArrayBuffer\",\"SharedArrayBuffer\",\"Atomics\",\"DataView\",\"JSON\",\"Promise\",\"Generator\",\"GeneratorFunction\",\"AsyncFunction\",\"Reflect\",\"Proxy\",\"Intl\",\"WebAssembly\"],s=[\"Error\",\"EvalError\",\"InternalError\",\"RangeError\",\"ReferenceError\",\"SyntaxError\",\"TypeError\",\"URIError\"],c=[\"setInterval\",\"setTimeout\",\"clearInterval\",\"clearTimeout\",\"require\",\"exports\",\"eval\",\"isFinite\",\"isNaN\",\"parseFloat\",\"parseInt\",\"decodeURI\",\"decodeURIComponent\",\"encodeURI\",\"encodeURIComponent\",\"escape\",\"unescape\"],r=[\"arguments\",\"this\",\"super\",\"console\",\"window\",\"document\",\"localStorage\",\"module\",\"global\"],i=[].concat(c,t,s)\n    ;function o(o){const l=o.regex,d=e,b={begin:/<[A-Za-z0-9\\\\._:-]+/,\n            end:/\\/[A-Za-z0-9\\\\._:-]+>|\\/>/,isTrulyOpeningTag:(e,n)=>{\n                const a=e[0].length+e.index,t=e.input[a]\n                ;if(\"<\"===t||\",\"===t)return void n.ignoreMatch();let s\n                ;\">\"===t&&(((e,{after:n})=>{const a=\"</\"+e[0].slice(1)\n                ;return-1!==e.input.indexOf(a,n)})(e,{after:a})||n.ignoreMatch())\n                ;const c=e.input.substring(a)\n                ;((s=c.match(/^\\s*=/))||(s=c.match(/^\\s+extends\\s+/))&&0===s.index)&&n.ignoreMatch()\n            }},g={$pattern:e,keyword:n,literal:a,built_in:i,\"variable.language\":r\n        },u=\"\\\\.([0-9](_?[0-9])*)\",m=\"0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*\",E={\n            className:\"number\",variants:[{\n                begin:`(\\\\b(${m})((${u})|\\\\.)?|(${u}))[eE][+-]?([0-9](_?[0-9])*)\\\\b`},{\n                begin:`\\\\b(${m})\\\\b((${u})\\\\b|\\\\.)?|(${u})\\\\b`},{\n                begin:\"\\\\b(0|[1-9](_?[0-9])*)n\\\\b\"},{\n                begin:\"\\\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\\\b\"},{\n                begin:\"\\\\b0[bB][0-1](_?[0-1])*n?\\\\b\"},{begin:\"\\\\b0[oO][0-7](_?[0-7])*n?\\\\b\"},{\n                begin:\"\\\\b0[0-7]+n?\\\\b\"}],relevance:0},y={className:\"subst\",begin:\"\\\\$\\\\{\",\n            end:\"\\\\}\",keywords:g,contains:[]},A={begin:\"html`\",end:\"\",starts:{end:\"`\",\n                returnEnd:!1,contains:[o.BACKSLASH_ESCAPE,y],subLanguage:\"xml\"}},p={\n            begin:\"css`\",end:\"\",starts:{end:\"`\",returnEnd:!1,\n                contains:[o.BACKSLASH_ESCAPE,y],subLanguage:\"css\"}},_={className:\"string\",\n            begin:\"`\",end:\"`\",contains:[o.BACKSLASH_ESCAPE,y]},N={className:\"comment\",\n            variants:[o.COMMENT(/\\/\\*\\*(?!\\/)/,\"\\\\*/\",{relevance:0,contains:[{\n                    begin:\"(?=@[A-Za-z]+)\",relevance:0,contains:[{className:\"doctag\",\n                        begin:\"@[A-Za-z]+\"},{className:\"type\",begin:\"\\\\{\",end:\"\\\\}\",excludeEnd:!0,\n                        excludeBegin:!0,relevance:0},{className:\"variable\",begin:d+\"(?=\\\\s*(-)|$)\",\n                        endsParent:!0,relevance:0},{begin:/(?=[^\\n])\\s/,relevance:0}]}]\n            }),o.C_BLOCK_COMMENT_MODE,o.C_LINE_COMMENT_MODE]\n        },f=[o.APOS_STRING_MODE,o.QUOTE_STRING_MODE,A,p,_,{match:/\\$\\d+/},E]\n    ;y.contains=f.concat({begin:/\\{/,end:/\\}/,keywords:g,contains:[\"self\"].concat(f)\n    });const h=[].concat(N,y.contains),v=h.concat([{begin:/\\(/,end:/\\)/,keywords:g,\n        contains:[\"self\"].concat(h)}]),S={className:\"params\",begin:/\\(/,end:/\\)/,\n        excludeBegin:!0,excludeEnd:!0,keywords:g,contains:v},w={variants:[{\n            match:[/class/,/\\s+/,d,/\\s+/,/extends/,/\\s+/,l.concat(d,\"(\",l.concat(/\\./,d),\")*\")],\n            scope:{1:\"keyword\",3:\"title.class\",5:\"keyword\",7:\"title.class.inherited\"}},{\n            match:[/class/,/\\s+/,d],scope:{1:\"keyword\",3:\"title.class\"}}]},R={relevance:0,\n        match:l.either(/\\bJSON/,/\\b[A-Z][a-z]+([A-Z][a-z]*|\\d)*/,/\\b[A-Z]{2,}([A-Z][a-z]+|\\d)+([A-Z][a-z]*)*/,/\\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\\d)*([A-Z][a-z]*)*/),\n        className:\"title.class\",keywords:{_:[...t,...s]}},x={variants:[{\n            match:[/function/,/\\s+/,d,/(?=\\s*\\()/]},{match:[/function/,/\\s*(?=\\()/]}],\n        className:{1:\"keyword\",3:\"title.function\"},label:\"func.def\",contains:[S],\n        illegal:/%/},k={\n        match:l.concat(/\\b/,(O=[...c,\"super\",\"import\"],l.concat(\"(?!\",O.join(\"|\"),\")\")),d,l.lookahead(/\\(/)),\n        className:\"title.function\",relevance:0};var O;const I={\n            begin:l.concat(/\\./,l.lookahead(l.concat(d,/(?![0-9A-Za-z$_(])/))),end:d,\n            excludeBegin:!0,keywords:\"prototype\",className:\"property\",relevance:0},C={\n            match:[/get|set/,/\\s+/,d,/(?=\\()/],className:{1:\"keyword\",3:\"title.function\"},\n            contains:[{begin:/\\(\\)/},S]\n        },T=\"(\\\\([^()]*(\\\\([^()]*(\\\\([^()]*\\\\)[^()]*)*\\\\)[^()]*)*\\\\)|\"+o.UNDERSCORE_IDENT_RE+\")\\\\s*=>\",M={\n            match:[/const|var|let/,/\\s+/,d,/\\s*/,/=\\s*/,/(async\\s*)?/,l.lookahead(T)],\n            keywords:\"async\",className:{1:\"keyword\",3:\"title.function\"},contains:[S]}\n    ;return{name:\"Javascript\",aliases:[\"js\",\"jsx\",\"mjs\",\"cjs\"],keywords:g,exports:{\n            PARAMS_CONTAINS:v,CLASS_REFERENCE:R},illegal:/#(?![$_A-z])/,\n        contains:[o.SHEBANG({label:\"shebang\",binary:\"node\",relevance:5}),{\n            label:\"use_strict\",className:\"meta\",relevance:10,\n            begin:/^\\s*['\"]use (strict|asm)['\"]/\n        },o.APOS_STRING_MODE,o.QUOTE_STRING_MODE,A,p,_,N,{match:/\\$\\d+/},E,R,{\n            className:\"attr\",begin:d+l.lookahead(\":\"),relevance:0},M,{\n            begin:\"(\"+o.RE_STARTERS_RE+\"|\\\\b(case|return|throw)\\\\b)\\\\s*\",\n            keywords:\"return throw case\",relevance:0,contains:[N,o.REGEXP_MODE,{\n                className:\"function\",begin:T,returnBegin:!0,end:\"\\\\s*=>\",contains:[{\n                    className:\"params\",variants:[{begin:o.UNDERSCORE_IDENT_RE,relevance:0},{\n                        className:null,begin:/\\(\\s*\\)/,skip:!0},{begin:/\\(/,end:/\\)/,excludeBegin:!0,\n                        excludeEnd:!0,keywords:g,contains:v}]}]},{begin:/,/,relevance:0},{match:/\\s+/,\n                relevance:0},{variants:[{begin:\"<>\",end:\"</>\"},{\n                    match:/<[A-Za-z0-9\\\\._:-]+\\s*\\/>/},{begin:b.begin,\n                    \"on:begin\":b.isTrulyOpeningTag,end:b.end}],subLanguage:\"xml\",contains:[{\n                    begin:b.begin,end:b.end,skip:!0,contains:[\"self\"]}]}]},x,{\n            beginKeywords:\"while if switch catch for\"},{\n            begin:\"\\\\b(?!function)\"+o.UNDERSCORE_IDENT_RE+\"\\\\([^()]*(\\\\([^()]*(\\\\([^()]*\\\\)[^()]*)*\\\\)[^()]*)*\\\\)\\\\s*\\\\{\",\n            returnBegin:!0,label:\"func.def\",contains:[S,o.inherit(o.TITLE_MODE,{begin:d,\n                className:\"title.function\"})]},{match:/\\.\\.\\./,relevance:0},I,{match:\"\\\\$\"+d,\n            relevance:0},{match:[/\\bconstructor(?=\\s*\\()/],className:{1:\"title.function\"},\n            contains:[S]},k,{relevance:0,match:/\\b[A-Z][A-Z_0-9]+\\b/,\n            className:\"variable.constant\"},w,C,{match:/\\$[(.]/}]}}return t=>{\n        const s=o(t),c=[\"any\",\"void\",\"number\",\"boolean\",\"string\",\"object\",\"never\",\"symbol\",\"bigint\",\"unknown\"],l={\n            beginKeywords:\"namespace\",end:/\\{/,excludeEnd:!0,\n            contains:[s.exports.CLASS_REFERENCE]},d={beginKeywords:\"interface\",end:/\\{/,\n            excludeEnd:!0,keywords:{keyword:\"interface extends\",built_in:c},\n            contains:[s.exports.CLASS_REFERENCE]},b={$pattern:e,\n            keyword:n.concat([\"type\",\"namespace\",\"interface\",\"public\",\"private\",\"protected\",\"implements\",\"declare\",\"abstract\",\"readonly\",\"enum\",\"override\"]),\n            literal:a,built_in:i.concat(c),\"variable.language\":r},g={className:\"meta\",\n            begin:\"@[A-Za-z$_][0-9A-Za-z$_]*\"},u=(e,n,a)=>{\n            const t=e.contains.findIndex((e=>e.label===n))\n            ;if(-1===t)throw Error(\"can not find mode to replace\");e.contains.splice(t,1,a)}\n        ;return Object.assign(s.keywords,b),\n            s.exports.PARAMS_CONTAINS.push(g),s.contains=s.contains.concat([g,l,d]),\n            u(s,\"shebang\",t.SHEBANG()),u(s,\"use_strict\",{className:\"meta\",relevance:10,\n            begin:/^\\s*['\"]use strict['\"]/\n        }),s.contains.find((e=>\"func.def\"===e.label)).relevance=0,Object.assign(s,{\n            name:\"TypeScript\",aliases:[\"ts\",\"tsx\"]}),s}})()\n;hljs.registerLanguage(\"typescript\",e)})();/*! `css` grammar compiled for Highlight.js 11.7.0 */\n(()=>{var e=(()=>{\"use strict\"\n    ;const e=[\"a\",\"abbr\",\"address\",\"article\",\"aside\",\"audio\",\"b\",\"blockquote\",\"body\",\"button\",\"canvas\",\"caption\",\"cite\",\"code\",\"dd\",\"del\",\"details\",\"dfn\",\"div\",\"dl\",\"dt\",\"em\",\"fieldset\",\"figcaption\",\"figure\",\"footer\",\"form\",\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\",\"header\",\"hgroup\",\"html\",\"i\",\"iframe\",\"img\",\"input\",\"ins\",\"kbd\",\"label\",\"legend\",\"li\",\"main\",\"mark\",\"menu\",\"nav\",\"object\",\"ol\",\"p\",\"q\",\"quote\",\"samp\",\"section\",\"span\",\"strong\",\"summary\",\"sup\",\"table\",\"tbody\",\"td\",\"textarea\",\"tfoot\",\"th\",\"thead\",\"time\",\"tr\",\"ul\",\"var\",\"video\"],i=[\"any-hover\",\"any-pointer\",\"aspect-ratio\",\"color\",\"color-gamut\",\"color-index\",\"device-aspect-ratio\",\"device-height\",\"device-width\",\"display-mode\",\"forced-colors\",\"grid\",\"height\",\"hover\",\"inverted-colors\",\"monochrome\",\"orientation\",\"overflow-block\",\"overflow-inline\",\"pointer\",\"prefers-color-scheme\",\"prefers-contrast\",\"prefers-reduced-motion\",\"prefers-reduced-transparency\",\"resolution\",\"scan\",\"scripting\",\"update\",\"width\",\"min-width\",\"max-width\",\"min-height\",\"max-height\"],r=[\"active\",\"any-link\",\"blank\",\"checked\",\"current\",\"default\",\"defined\",\"dir\",\"disabled\",\"drop\",\"empty\",\"enabled\",\"first\",\"first-child\",\"first-of-type\",\"fullscreen\",\"future\",\"focus\",\"focus-visible\",\"focus-within\",\"has\",\"host\",\"host-context\",\"hover\",\"indeterminate\",\"in-range\",\"invalid\",\"is\",\"lang\",\"last-child\",\"last-of-type\",\"left\",\"link\",\"local-link\",\"not\",\"nth-child\",\"nth-col\",\"nth-last-child\",\"nth-last-col\",\"nth-last-of-type\",\"nth-of-type\",\"only-child\",\"only-of-type\",\"optional\",\"out-of-range\",\"past\",\"placeholder-shown\",\"read-only\",\"read-write\",\"required\",\"right\",\"root\",\"scope\",\"target\",\"target-within\",\"user-invalid\",\"valid\",\"visited\",\"where\"],t=[\"after\",\"backdrop\",\"before\",\"cue\",\"cue-region\",\"first-letter\",\"first-line\",\"grammar-error\",\"marker\",\"part\",\"placeholder\",\"selection\",\"slotted\",\"spelling-error\"],o=[\"align-content\",\"align-items\",\"align-self\",\"all\",\"animation\",\"animation-delay\",\"animation-direction\",\"animation-duration\",\"animation-fill-mode\",\"animation-iteration-count\",\"animation-name\",\"animation-play-state\",\"animation-timing-function\",\"backface-visibility\",\"background\",\"background-attachment\",\"background-blend-mode\",\"background-clip\",\"background-color\",\"background-image\",\"background-origin\",\"background-position\",\"background-repeat\",\"background-size\",\"block-size\",\"border\",\"border-block\",\"border-block-color\",\"border-block-end\",\"border-block-end-color\",\"border-block-end-style\",\"border-block-end-width\",\"border-block-start\",\"border-block-start-color\",\"border-block-start-style\",\"border-block-start-width\",\"border-block-style\",\"border-block-width\",\"border-bottom\",\"border-bottom-color\",\"border-bottom-left-radius\",\"border-bottom-right-radius\",\"border-bottom-style\",\"border-bottom-width\",\"border-collapse\",\"border-color\",\"border-image\",\"border-image-outset\",\"border-image-repeat\",\"border-image-slice\",\"border-image-source\",\"border-image-width\",\"border-inline\",\"border-inline-color\",\"border-inline-end\",\"border-inline-end-color\",\"border-inline-end-style\",\"border-inline-end-width\",\"border-inline-start\",\"border-inline-start-color\",\"border-inline-start-style\",\"border-inline-start-width\",\"border-inline-style\",\"border-inline-width\",\"border-left\",\"border-left-color\",\"border-left-style\",\"border-left-width\",\"border-radius\",\"border-right\",\"border-right-color\",\"border-right-style\",\"border-right-width\",\"border-spacing\",\"border-style\",\"border-top\",\"border-top-color\",\"border-top-left-radius\",\"border-top-right-radius\",\"border-top-style\",\"border-top-width\",\"border-width\",\"bottom\",\"box-decoration-break\",\"box-shadow\",\"box-sizing\",\"break-after\",\"break-before\",\"break-inside\",\"caption-side\",\"caret-color\",\"clear\",\"clip\",\"clip-path\",\"clip-rule\",\"color\",\"column-count\",\"column-fill\",\"column-gap\",\"column-rule\",\"column-rule-color\",\"column-rule-style\",\"column-rule-width\",\"column-span\",\"column-width\",\"columns\",\"contain\",\"content\",\"content-visibility\",\"counter-increment\",\"counter-reset\",\"cue\",\"cue-after\",\"cue-before\",\"cursor\",\"direction\",\"display\",\"empty-cells\",\"filter\",\"flex\",\"flex-basis\",\"flex-direction\",\"flex-flow\",\"flex-grow\",\"flex-shrink\",\"flex-wrap\",\"float\",\"flow\",\"font\",\"font-display\",\"font-family\",\"font-feature-settings\",\"font-kerning\",\"font-language-override\",\"font-size\",\"font-size-adjust\",\"font-smoothing\",\"font-stretch\",\"font-style\",\"font-synthesis\",\"font-variant\",\"font-variant-caps\",\"font-variant-east-asian\",\"font-variant-ligatures\",\"font-variant-numeric\",\"font-variant-position\",\"font-variation-settings\",\"font-weight\",\"gap\",\"glyph-orientation-vertical\",\"grid\",\"grid-area\",\"grid-auto-columns\",\"grid-auto-flow\",\"grid-auto-rows\",\"grid-column\",\"grid-column-end\",\"grid-column-start\",\"grid-gap\",\"grid-row\",\"grid-row-end\",\"grid-row-start\",\"grid-template\",\"grid-template-areas\",\"grid-template-columns\",\"grid-template-rows\",\"hanging-punctuation\",\"height\",\"hyphens\",\"icon\",\"image-orientation\",\"image-rendering\",\"image-resolution\",\"ime-mode\",\"inline-size\",\"isolation\",\"justify-content\",\"left\",\"letter-spacing\",\"line-break\",\"line-height\",\"list-style\",\"list-style-image\",\"list-style-position\",\"list-style-type\",\"margin\",\"margin-block\",\"margin-block-end\",\"margin-block-start\",\"margin-bottom\",\"margin-inline\",\"margin-inline-end\",\"margin-inline-start\",\"margin-left\",\"margin-right\",\"margin-top\",\"marks\",\"mask\",\"mask-border\",\"mask-border-mode\",\"mask-border-outset\",\"mask-border-repeat\",\"mask-border-slice\",\"mask-border-source\",\"mask-border-width\",\"mask-clip\",\"mask-composite\",\"mask-image\",\"mask-mode\",\"mask-origin\",\"mask-position\",\"mask-repeat\",\"mask-size\",\"mask-type\",\"max-block-size\",\"max-height\",\"max-inline-size\",\"max-width\",\"min-block-size\",\"min-height\",\"min-inline-size\",\"min-width\",\"mix-blend-mode\",\"nav-down\",\"nav-index\",\"nav-left\",\"nav-right\",\"nav-up\",\"none\",\"normal\",\"object-fit\",\"object-position\",\"opacity\",\"order\",\"orphans\",\"outline\",\"outline-color\",\"outline-offset\",\"outline-style\",\"outline-width\",\"overflow\",\"overflow-wrap\",\"overflow-x\",\"overflow-y\",\"padding\",\"padding-block\",\"padding-block-end\",\"padding-block-start\",\"padding-bottom\",\"padding-inline\",\"padding-inline-end\",\"padding-inline-start\",\"padding-left\",\"padding-right\",\"padding-top\",\"page-break-after\",\"page-break-before\",\"page-break-inside\",\"pause\",\"pause-after\",\"pause-before\",\"perspective\",\"perspective-origin\",\"pointer-events\",\"position\",\"quotes\",\"resize\",\"rest\",\"rest-after\",\"rest-before\",\"right\",\"row-gap\",\"scroll-margin\",\"scroll-margin-block\",\"scroll-margin-block-end\",\"scroll-margin-block-start\",\"scroll-margin-bottom\",\"scroll-margin-inline\",\"scroll-margin-inline-end\",\"scroll-margin-inline-start\",\"scroll-margin-left\",\"scroll-margin-right\",\"scroll-margin-top\",\"scroll-padding\",\"scroll-padding-block\",\"scroll-padding-block-end\",\"scroll-padding-block-start\",\"scroll-padding-bottom\",\"scroll-padding-inline\",\"scroll-padding-inline-end\",\"scroll-padding-inline-start\",\"scroll-padding-left\",\"scroll-padding-right\",\"scroll-padding-top\",\"scroll-snap-align\",\"scroll-snap-stop\",\"scroll-snap-type\",\"scrollbar-color\",\"scrollbar-gutter\",\"scrollbar-width\",\"shape-image-threshold\",\"shape-margin\",\"shape-outside\",\"speak\",\"speak-as\",\"src\",\"tab-size\",\"table-layout\",\"text-align\",\"text-align-all\",\"text-align-last\",\"text-combine-upright\",\"text-decoration\",\"text-decoration-color\",\"text-decoration-line\",\"text-decoration-style\",\"text-emphasis\",\"text-emphasis-color\",\"text-emphasis-position\",\"text-emphasis-style\",\"text-indent\",\"text-justify\",\"text-orientation\",\"text-overflow\",\"text-rendering\",\"text-shadow\",\"text-transform\",\"text-underline-position\",\"top\",\"transform\",\"transform-box\",\"transform-origin\",\"transform-style\",\"transition\",\"transition-delay\",\"transition-duration\",\"transition-property\",\"transition-timing-function\",\"unicode-bidi\",\"vertical-align\",\"visibility\",\"voice-balance\",\"voice-duration\",\"voice-family\",\"voice-pitch\",\"voice-range\",\"voice-rate\",\"voice-stress\",\"voice-volume\",\"white-space\",\"widows\",\"width\",\"will-change\",\"word-break\",\"word-spacing\",\"word-wrap\",\"writing-mode\",\"z-index\"].reverse()\n    ;return n=>{const a=n.regex,l=(e=>({IMPORTANT:{scope:\"meta\",begin:\"!important\"},\n        BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:\"number\",\n            begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\\b/},FUNCTION_DISPATCH:{\n            className:\"built_in\",begin:/[\\w-]+(?=\\()/},ATTRIBUTE_SELECTOR_MODE:{\n            scope:\"selector-attr\",begin:/\\[/,end:/\\]/,illegal:\"$\",\n            contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{\n            scope:\"number\",\n            begin:e.NUMBER_RE+\"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?\",\n            relevance:0},CSS_VARIABLE:{className:\"attr\",begin:/--[A-Za-z][A-Za-z0-9_-]*/}\n    }))(n),s=[n.APOS_STRING_MODE,n.QUOTE_STRING_MODE];return{name:\"CSS\",\n        case_insensitive:!0,illegal:/[=|'\\$]/,keywords:{keyframePosition:\"from to\"},\n        classNameAliases:{keyframePosition:\"selector-tag\"},contains:[l.BLOCK_COMMENT,{\n            begin:/-(webkit|moz|ms|o)-(?=[a-z])/},l.CSS_NUMBER_MODE,{\n            className:\"selector-id\",begin:/#[A-Za-z0-9_-]+/,relevance:0},{\n            className:\"selector-class\",begin:\"\\\\.[a-zA-Z-][a-zA-Z0-9_-]*\",relevance:0\n        },l.ATTRIBUTE_SELECTOR_MODE,{className:\"selector-pseudo\",variants:[{\n                begin:\":(\"+r.join(\"|\")+\")\"},{begin:\":(:)?(\"+t.join(\"|\")+\")\"}]},l.CSS_VARIABLE,{\n            className:\"attribute\",begin:\"\\\\b(\"+o.join(\"|\")+\")\\\\b\"},{begin:/:/,end:/[;}{]/,\n            contains:[l.BLOCK_COMMENT,l.HEXCOLOR,l.IMPORTANT,l.CSS_NUMBER_MODE,...s,{\n                begin:/(url|data-uri)\\(/,end:/\\)/,relevance:0,keywords:{built_in:\"url data-uri\"\n                },contains:[...s,{className:\"string\",begin:/[^)]/,endsWithParent:!0,\n                    excludeEnd:!0}]},l.FUNCTION_DISPATCH]},{begin:a.lookahead(/@/),end:\"[{;]\",\n            relevance:0,illegal:/:/,contains:[{className:\"keyword\",begin:/@-?\\w[\\w]*(-\\w+)*/\n            },{begin:/\\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{\n                    $pattern:/[a-z-]+/,keyword:\"and or not only\",attribute:i.join(\" \")},contains:[{\n                    begin:/[a-z-]+(?=:)/,className:\"attribute\"},...s,l.CSS_NUMBER_MODE]}]},{\n            className:\"selector-tag\",begin:\"\\\\b(\"+e.join(\"|\")+\")\\\\b\"}]}}})()\n;hljs.registerLanguage(\"css\",e)})();/*! `json` grammar compiled for Highlight.js 11.7.0 */\n(()=>{var e=(()=>{\"use strict\";return e=>{const a=[\"true\",\"false\",\"null\"],n={\n    scope:\"literal\",beginKeywords:a.join(\" \")};return{name:\"JSON\",keywords:{\n        literal:a},contains:[{className:\"attr\",begin:/\"(\\\\.|[^\\\\\"\\r\\n])*\"(?=\\s*:)/,\n        relevance:1.01},{match:/[{}[\\],:]/,className:\"punctuation\",relevance:0\n    },e.QUOTE_STRING_MODE,n,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],\n    illegal:\"\\\\S\"}}})();hljs.registerLanguage(\"json\",e)})();/*! `diff` grammar compiled for Highlight.js 11.7.0 */\n(()=>{var e=(()=>{\"use strict\";return e=>{const a=e.regex;return{name:\"Diff\",\n    aliases:[\"patch\"],contains:[{className:\"meta\",relevance:10,\n        match:a.either(/^@@ +-\\d+,\\d+ +\\+\\d+,\\d+ +@@/,/^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$/,/^--- +\\d+,\\d+ +----$/)\n    },{className:\"comment\",variants:[{\n            begin:a.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\\*{3} /,/^\\+{3}/,/^diff --git/),\n            end:/$/},{match:/^\\*{15}$/}]},{className:\"addition\",begin:/^\\+/,end:/$/},{\n        className:\"deletion\",begin:/^-/,end:/$/},{className:\"addition\",begin:/^!/,\n        end:/$/}]}}})();hljs.registerLanguage(\"diff\",e)})();/*! `xml` grammar compiled for Highlight.js 11.7.0 */\n(()=>{var e=(()=>{\"use strict\";return e=>{\n    const a=e.regex,n=a.concat(/[\\p{L}_]/u,a.optional(/[\\p{L}0-9_.-]*:/u),/[\\p{L}0-9_.-]*/u),s={\n        className:\"symbol\",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},t={begin:/\\s/,\n        contains:[{className:\"keyword\",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\\n/}]\n    },i=e.inherit(t,{begin:/\\(/,end:/\\)/}),c=e.inherit(e.APOS_STRING_MODE,{\n        className:\"string\"}),l=e.inherit(e.QUOTE_STRING_MODE,{className:\"string\"}),r={\n        endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:\"attr\",\n            begin:/[\\p{L}0-9._:-]+/u,relevance:0},{begin:/=\\s*/,relevance:0,contains:[{\n                className:\"string\",endsParent:!0,variants:[{begin:/\"/,end:/\"/,contains:[s]},{\n                    begin:/'/,end:/'/,contains:[s]},{begin:/[^\\s\"'=<>`]+/}]}]}]};return{\n        name:\"HTML, XML\",\n        aliases:[\"html\",\"xhtml\",\"rss\",\"atom\",\"xjb\",\"xsd\",\"xsl\",\"plist\",\"wsf\",\"svg\"],\n        case_insensitive:!0,unicodeRegex:!0,contains:[{className:\"meta\",begin:/<![a-z]/,\n            end:/>/,relevance:10,contains:[t,l,c,i,{begin:/\\[/,end:/\\]/,contains:[{\n                    className:\"meta\",begin:/<![a-z]/,end:/>/,contains:[t,i,l,c]}]}]\n        },e.COMMENT(/<!--/,/-->/,{relevance:10}),{begin:/<!\\[CDATA\\[/,end:/\\]\\]>/,\n            relevance:10},s,{className:\"meta\",end:/\\?>/,variants:[{begin:/<\\?xml/,\n                relevance:10,contains:[l]},{begin:/<\\?[a-z][a-z0-9]+/}]},{className:\"tag\",\n            begin:/<style(?=\\s|>)/,end:/>/,keywords:{name:\"style\"},contains:[r],starts:{\n                end:/<\\/style>/,returnEnd:!0,subLanguage:[\"css\",\"xml\"]}},{className:\"tag\",\n            begin:/<script(?=\\s|>)/,end:/>/,keywords:{name:\"script\"},contains:[r],starts:{\n                end:/<\\/script>/,returnEnd:!0,subLanguage:[\"javascript\",\"handlebars\",\"xml\"]}},{\n            className:\"tag\",begin:/<>|<\\/>/},{className:\"tag\",\n            begin:a.concat(/</,a.lookahead(a.concat(n,a.either(/\\/>/,/>/,/\\s/)))),\n            end:/\\/?>/,contains:[{className:\"name\",begin:n,relevance:0,starts:r}]},{\n            className:\"tag\",begin:a.concat(/<\\//,a.lookahead(a.concat(n,/>/))),contains:[{\n                className:\"name\",begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}\n})();hljs.registerLanguage(\"xml\",e)})();"
  },
  {
    "path": "docs/package.json",
    "content": "{\n  \"name\": \"trumbowyg-github-page\",\n  \"private\": true,\n  \"author\": {\n    \"name\": \"Alexandre Demode (Alex-D)\",\n    \"email\": \"contact@alex-d.fr\",\n    \"url\": \"https://alex-d.fr\"\n  },\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"dev\": \"gulp\",\n    \"clean\": \"gulp clean\",\n    \"build\": \"gulp build\"\n  },\n  \"volta\": {\n    \"node\": \"22.13.1\"\n  }\n}\n"
  },
  {
    "path": "docs/robots.txt",
    "content": "# robotstxt.org/\n\nUser-agent: *\n"
  },
  {
    "path": "docs/scss/_base.scss",
    "content": "@use \"variables\";\n\n/*! HTML5 Boilerplate v4.3.0 | MIT License | http://h5bp.com/ */\n\nhtml,\nbutton,\ninput,\nselect,\ntextarea {\n    color: #222;\n}\n\nhtml {\n    font-size: 1em;\n    line-height: 1.4;\n}\n\nhtml,\nbody {\n    background: #fff;\n}\n\n::-moz-selection {\n    background: #b3d4fc;\n    text-shadow: none;\n}\n\n::selection {\n    background: #b3d4fc;\n    text-shadow: none;\n}\n\nhr {\n    display: block;\n    height: 1px;\n    border: 0;\n    border-top: 1px solid #ccc;\n    margin: 1em 0;\n    padding: 0;\n}\n\naudio,\ncanvas,\nimg,\nvideo {\n    vertical-align: middle;\n}\n\nfieldset {\n    border: 0;\n    margin: 0;\n    padding: 0;\n}\n\ntextarea {\n    resize: vertical;\n}\n\n\nhtml {\n    box-sizing: border-box;\n}\n\n*,\n*:before,\n*:after {\n    box-sizing: inherit;\n}\n\nbody,\nbutton,\ninput,\nselect,\ntextarea {\n    font-family: variables.$font;\n    font-size: 18px;\n    font-weight: 300;\n}\n\n.wrapper {\n    max-width: 1200px;\n    margin: 0 auto;\n    clear: both;\n\n    p:last-child {\n        margin-bottom: 0;\n    }\n\n    h4 {\n        font-size: 30px;\n    }\n\n    code.console {\n        background: variables.$text-color;\n        color: #fff;\n        font-size: 16px;\n        padding: 3px 7px;\n    }\n\n    .note {\n        display: table;\n        color: #666;\n        background: rgba(0, 0, 0, 0.02);\n        padding: 8px 12px;\n        border-left: 3px solid variables.$primary-color-light;\n        border-radius: 8px;\n        font-size: 15px;\n        margin-block-start: 0.5em;\n        margin-block-end: 0.5em;\n\n        > :first-child {\n            margin-top: 6px;\n        }\n\n        > :last-child {\n            margin-bottom: 6px;\n        }\n\n        code {\n            margin-left: 2px;\n            margin-right: 2px;\n        }\n    }\n}\n\n.section {\n    a {\n        text-decoration: none;\n        color: variables.$primary-color;\n\n        &:hover,\n        &:focus {\n            text-decoration: underline;\n        }\n    }\n}\n\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n    font-weight: 300;\n    margin: 0;\n    padding: 0;\n}\n\nhr.clearfix {\n    display: block;\n    border: none;\n    background: none;\n    margin: 0;\n    padding: 0;\n    height: 0;\n    clear: both;\n}\n\ncode,\nkbd,\npre,\nsamp {\n    font-family: \"JetBrains Mono\", monospace;\n    font-size: 15px;\n    line-height: 1.5;\n}\n\n\n:root {\n    --tbw-cell-vertical-padding: 4px;\n    --tbw-cell-horizontal-padding: 8px;\n    --tbw-cell-line-height: 1.5em;\n}\n\ntable {\n    margin-bottom: var(--tbw-cell-line-height);\n}\n\nth,\ntd {\n    height: calc(var(--tbw-cell-vertical-padding) * 2 + var(--tbw-cell-line-height));\n    min-width: calc(var(--tbw-cell-horizontal-padding) * 2);\n    padding: var(--tbw-cell-vertical-padding) var(--tbw-cell-horizontal-padding);\n    border: 1px solid #e7eaec;\n}\n\nthead {\n    background: #FFFFFF;\n}\n"
  },
  {
    "path": "docs/scss/_buttons.scss",
    "content": "@use \"variables\";\n\n.button {\n    display: inline-block;\n    position: relative;\n    width: 250px;\n    border: 2px solid transparent;\n    margin: 0 auto;\n    padding: 23px 30px;\n    color: #fff;\n    font-weight: 400;\n    font-size: 16px;\n    line-height: 1.2;\n    text-decoration: none;\n    border-radius: 50px;\n    text-align: center;\n    transition: color variables.$transition-duration, background-color variables.$transition-duration;\n\n    &-primary {\n        background: variables.$primary-color;\n    }\n\n    &-secondary {\n        background: variables.$secondary-color;\n    }\n\n    &-ghost {\n        border-color: rgba(255, 255, 255, 0.4);\n    }\n\n    &:not(:last-child) {\n        margin-right: 20px;\n    }\n}\n\n.button:hover,\n.button:focus {\n    background: #fff;\n    color: variables.$primary-color;\n    outline: none;\n}\n"
  },
  {
    "path": "docs/scss/_documentation.scss",
    "content": "@use \"variables\";\n\n$added-color: #5ecb0e;\n$deprecated-color: #ff9a4d;\n\n$sidebar-width: 22%;\n$beer-height: 70px;\n\n.documentation-body {\n    background: variables.$grey;\n    display: flex;\n\n    .main {\n        padding: 0 60px;\n        height: 100vh;\n        width: 100% - $sidebar-width;\n        overflow: auto;\n    }\n\n    .main-demos {\n        padding: 0;\n        overflow: hidden;\n\n        iframe {\n            width: 100%;\n            height: 100vh;\n            background: variables.$grey;\n        }\n    }\n\n    .main-demo-inner {\n        width: 100%;\n    }\n\n    .section-title {\n        padding: 50px 0 0;\n    }\n\n    h3 {\n        display: inline-block;\n        font-weight: bold;\n        font-size: 26px;\n    }\n\n    h4 {\n        padding: 20px 0 0;\n    }\n\n    p,\n    dd,\n    ul {\n        & > code,\n        *:not(pre) > code {\n            color: #616870;\n            background: #dfe5eb;\n            padding: 0 5px;\n            border-radius: 4px;\n        }\n\n        a code {\n            color: inherit;\n        }\n    }\n\n    code.type {\n        padding: 0 3px;\n        color: variables.$primary-color-dark;\n\n        &::before {\n            content: \"<\";\n        }\n\n        &::after {\n            content: \">\";\n        }\n    }\n\n    .button.button-demo {\n        border-color: rgba(variables.$secondary-color, 0.6);\n        color: variables.$secondary-color;\n        width: auto;\n        padding: 10px 30px;\n\n        &:hover,\n        &:focus {\n            text-decoration: none;\n            border-color: variables.$secondary-color;\n            background: variables.$secondary-color;\n            color: variables.$white;\n        }\n    }\n\n    ::-webkit-scrollbar {\n        width: 17px;\n    }\n\n    ::-webkit-scrollbar-track {\n        background: variables.$grey;\n    }\n\n    ::-webkit-scrollbar-thumb {\n        background: #cfd7de;\n        border: 2px solid variables.$grey;\n\n        &:hover {\n            background: #616870;\n        }\n    }\n}\n\n.header-documentation {\n    margin-top: 50px;\n\n    .documentation-logo-link {\n        display: block;\n        margin: 0 auto;\n        width: 80%;\n        max-width: 350px;\n\n        .documentation-logo {\n            width: 100%;\n        }\n    }\n\n    .documentation-title {\n        text-align: center;\n        font-family: variables.$panton;\n        font-weight: 100;\n        line-height: 1;\n\n        @media (max-width: 1290px) {\n            font-size: 2.5vw;\n        }\n    }\n\n    .documentation-menu {\n        text-align: center;\n        margin-top: 40px;\n        background: variables.$secondary-color;\n\n        a {\n            display: inline-block;\n            padding: 20px 5px;\n\n            &:hover,\n            &:focus {\n                text-decoration: underline;\n            }\n        }\n\n        @media (max-width: 1550px) {\n            padding: 5px 7%;\n\n            a {\n                width: 48%;\n                padding: 10px 0;\n            }\n\n            .documentation-menu-dot {\n                display: none;\n            }\n        }\n    }\n}\n\n.sidebar {\n    position: relative;\n    top: 0;\n    left: 0;\n    height: 100vh;\n    color: variables.$white;\n    background: variables.$primary-color linear-gradient(to bottom left, variables.$primary-color, variables.$primary-color-light);\n    width: $sidebar-width;\n\n    ::-webkit-scrollbar-track {\n        background: transparent;\n    }\n\n    ::-webkit-scrollbar-thumb {\n        background: variables.$primary-color-light;\n        border: 1px solid variables.$primary-color-light;\n        border-right: none;\n\n        &:hover {\n            background: variables.$white;\n        }\n    }\n\n    &::after {\n        content: \"\";\n        display: block;\n        position: absolute;\n        left: 0;\n        bottom: $beer-height;\n        width: calc(100% - 17px);\n        height: 100px;\n        background: linear-gradient(to bottom, rgba(variables.$primary-color-light, 0), variables.$primary-color-light);\n        pointer-events: none;\n    }\n\n    .sidebar-inner {\n        overflow: auto;\n        overflow-y: scroll;\n        overflow-x: hidden;\n        height: calc(100vh - #{$beer-height});\n    }\n\n    ul,\n    li {\n        padding: 0;\n        margin: 0;\n        list-style: none;\n    }\n\n    a {\n        text-decoration: none;\n        color: variables.$white;\n        transition: color variables.$transition-duration, text-indent variables.$transition-duration;\n    }\n\n    .documentation-summary {\n        position: relative;\n        font-size: 18px;\n        margin-bottom: 100px;\n\n        > ul {\n            max-width: 340px;\n            margin: 0 auto;\n            padding: 0 30px;\n\n            a,\n            .documentation-summary-title {\n                display: block;\n                height: 30px;\n                line-height: 30px;\n                text-overflow: ellipsis;\n                width: 100%;\n                white-space: nowrap;\n                overflow: hidden;\n            }\n\n            > li {\n                margin-top: 30px;\n\n                &:first-child {\n                    margin-top: 50px;\n                }\n\n                > a,\n                .documentation-summary-title {\n                    font-weight: 600;\n                    text-transform: uppercase;\n                    margin-bottom: 5px;\n                }\n\n                > a {\n                    &:hover,\n                    &:focus {\n                        color: variables.$primary-color-dark;\n                    }\n                }\n\n                ul li a {\n                    &:hover,\n                    &:focus {\n                        color: variables.$primary-color-dark;\n                        text-indent: 10px;\n                    }\n                }\n            }\n        }\n    }\n\n    .documentation-sidebar-beer {\n        position: fixed;\n        width: $sidebar-width;\n        bottom: 0;\n        left: 0;\n        background: variables.$white;\n        height: $beer-height;\n\n        a {\n            position: relative;\n            display: block;\n            height: $beer-height;\n            width: 100%;\n            text-align: left;\n            padding: 10px 17px 0 0;\n            background: none;\n            border: none;\n            border-top: 1px solid #e9eef3;\n            color: #9ca4ac;\n\n            &:focus {\n                outline: none;\n            }\n\n            .beer-icon {\n                display: none;\n            }\n\n            @media (min-width: 1700px) {\n                .beer-icon {\n                    position: absolute;\n                    display: block;\n                    width: calc((100% - 236px) / 2);\n                    height: 50px;\n                    margin: 0 auto;\n                }\n            }\n\n            .beer-label {\n                position: relative;\n                display: block;\n                max-width: 236px;\n                margin: 0 auto;\n            }\n\n            @media (max-width: 1290px) {\n                .beer-label {\n                    font-size: 14px;\n                    margin: 0;\n                    padding: 7px 0 0 15px;\n                    width: 200px;\n                }\n            }\n        }\n    }\n}\n\n.added-feature,\n.deprecated-feature {\n    display: inline-block;\n    padding: 3px 13px;\n    margin: 0;\n    color: variables.$white;\n    font-size: 14px;\n    border-radius: 50px;\n    transform: translateX(10px) translateY(-4px);\n}\n\n.added-feature {\n    background: $added-color;\n}\n\n.deprecated-feature {\n    background: $deprecated-color;\n}\n\n.deprecated-info {\n    padding: 7px 15px;\n    border-radius: 4px;\n    background: #f2dfc1;\n    border: 1px solid $deprecated-color;\n\n    a {\n        color: $deprecated-color;\n    }\n}\n\n.version-tag {\n    display: inline-block;\n    padding: 2px 6px;\n    background: $added-color;\n    color: #FFF;\n    font-size: 12px;\n    font-style: normal;\n    border-radius: 20px;\n}\n\n.note .version-tag {\n    transform: translateY(-1px);\n}\n\n.feature {\n    position: relative;\n    padding-bottom: 60px;\n\n    &::after {\n        content: \" \";\n        display: block;\n        position: absolute;\n        bottom: 0;\n        left: 50%;\n        width: 40%;\n        height: 0;\n        border-bottom: 1px solid variables.$primary-color-light;\n        transform: translateX(-50%);\n    }\n\n    h3,\n    h4 {\n        display: inline-block;\n        position: relative;\n    }\n\n    h3 {\n        padding-top: 50px;\n        margin-left: -15px;\n        padding-left: 15px;\n    }\n\n    h4 {\n        font-size: 20px;\n        font-weight: bold;\n    }\n\n    h3 + h4,\n    h3 + a + h4 {\n        display: block;\n    }\n\n    .title-link {\n        display: block;\n        position: absolute;\n        left: -45px;\n        height: 30px;\n        width: 30px;\n        opacity: 0;\n        text-align: center;\n        text-decoration: none;\n        background: variables.$primary-color;\n        border-radius: 50%;\n        transform: translateY(-36px);\n        transition: opacity variables.$transition-duration, background variables.$transition-duration, color variables.$transition-duration;\n\n        &:hover,\n        &:focus {\n            background: variables.$white;\n            text-decoration: none;\n\n            svg {\n                fill: variables.$primary-color;\n            }\n        }\n\n        svg {\n            fill: variables.$white;\n            width: 70%;\n            height: 100%;\n        }\n    }\n\n    h4 + .title-link {\n        transform: translateY(-30px);\n    }\n\n    &:hover {\n        .title-link {\n            opacity: 1;\n        }\n    }\n\n    .trumbowyg-box,\n    .trumbowyg-editor {\n        margin: 24px auto;\n    }\n}\n\n.sample-data {\n    background: variables.$white;\n    padding: 25px;\n\n    h4 {\n        padding: 0;\n    }\n\n    input {\n        width: 100%;\n        border: none;\n        padding: 5px 7px;\n        color: #616870;\n        background: #dfe5eb;\n\n        &:not(:last-child) {\n            margin-bottom: 10px;\n        }\n    }\n}\n\ndl {\n    dt {\n        display: inline-block;\n        color: #1b2126;\n        background: #dfe5eb;\n        padding: 0 4px 0 6px;\n        border-radius: 4px;\n    }\n\n    dd {\n        padding: 5px 0 15px;\n        margin-left: 15px;\n\n        ul {\n            margin: 0.5em 0;\n        }\n    }\n}\n\n.tree {\n    list-style: none;\n    background: white;\n    padding: 1em 1.5em;\n    border-radius: 8px;\n    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.02);\n\n    ul {\n        position: relative;\n        list-style: none;\n        margin: 0;\n        padding-left: 8px;\n        overflow: hidden;\n    }\n\n    li {\n        padding-top: 8px;\n    }\n\n    & > li {\n        padding-top: 0;\n    }\n\n    ul li {\n        position: relative;\n        padding-left: 16px;\n\n        &::before,\n        &::after {\n            content: '';\n            display: block;\n            position: absolute;\n            background: variables.$primary-color;\n        }\n\n        &::before {\n            top: 20px;\n            left: 0;\n            width: 12px;\n            height: 1px;\n        }\n\n        &::after {\n            left: 0;\n            bottom: calc(100% - 20px);\n            width: 1px;\n            height: 500px;\n        }\n    }\n}\n"
  },
  {
    "path": "docs/scss/_donate.scss",
    "content": "@use \"variables\";\n\n.donate-container {\n    position: relative;\n    max-width: 800px;\n    margin: 0 auto;\n\n    .donate-description {\n        width: 100%;\n        padding: 30px 50px 50px;\n        background: variables.$grey;\n        border-top-left-radius: variables.$radius;\n        border-top-right-radius: variables.$radius;\n    }\n\n    .donate-footer {\n        text-align: center;\n        padding: 50px 0;\n        background: variables.$primary-color linear-gradient(to bottom left, variables.$primary-color, variables.$primary-color-light);\n        border-bottom-left-radius: variables.$radius;\n        border-bottom-right-radius: variables.$radius;\n    }\n\n    .donate-beer {\n        position: absolute;\n        left: -190px;\n        bottom: -30px;\n        width: 250px;\n    }\n\n    .button {\n        color: variables.$white;\n        text-decoration: none;\n\n        &:hover,\n        &:focus {\n            text-decoration: none;\n            background: variables.$white;\n            color: variables.$primary-color;\n        }\n    }\n}\n\n.sponsors-container {\n    margin: 150px 0 0;\n    text-align: center;\n\n    a {\n        padding: 0 20px;\n    }\n}\n"
  },
  {
    "path": "docs/scss/_font.scss",
    "content": "// Panton Light\n@font-face {\n    font-family: 'Panton';\n    src: url('../fonts/panton.woff2') format('woff2');\n    font-weight: 300;\n    font-style: normal;\n    font-display: swap;\n}\n\n// Open Sans\n@font-face {\n    font-family: 'Open Sans';\n    src: url('../fonts/open-sans-light.woff2') format('woff2');\n    font-weight: 300;\n    font-style: normal;\n    font-display: swap;\n}\n\n@font-face {\n    font-family: 'Open Sans';\n    src: url('../fonts/open-sans-regular.woff2') format('woff2');\n    font-weight: normal;\n    font-style: normal;\n    font-display: swap;\n}\n\n@font-face {\n    font-family: 'Open Sans';\n    src: url('../fonts/open-sans-semibold.woff2') format('woff2');\n    font-weight: 600;\n    font-style: normal;\n    font-display: swap;\n}\n\n// JetBrains Mono\n@font-face {\n    font-family: 'JetBrains Mono';\n    src: url('../fonts/jetbrains-mono-regular.woff2') format('woff2');\n    font-weight: normal;\n    font-style: normal;\n    font-display: swap;\n}\n"
  },
  {
    "path": "docs/scss/_footer.scss",
    "content": "@use \"variables\";\n\n.footer {\n    margin-top: 40px;\n    text-align: center;\n    color: variables.$white;\n    background: linear-gradient(to bottom left, variables.$primary-color, variables.$primary-color-light);\n    clear: both;\n\n    .footer-text,\n    .footer-link {\n        display: inline-block;\n        padding: 40px;\n    }\n\n    .footer-text {\n        padding-bottom: 0;\n\n        .hearts {\n            font-size: 18px;\n            color: variables.$primary-color-dark;\n        }\n    }\n\n    .footer-link {\n        text-decoration: none;\n        color: variables.$white;\n        transition: color 0.15s;\n\n        &:hover,\n        &:focus {\n            color: variables.$primary-color-dark;\n        }\n    }\n}\n"
  },
  {
    "path": "docs/scss/_get-started.scss",
    "content": "@use \"variables\";\n\n.installation-first-step {\n    height: 400px;\n    color: variables.$text-color;\n    text-align: center;\n    padding-top: 10px;\n    margin: 20px 0 50px;\n    border: 1px solid rgba(0, 0, 0, 0.15);\n    border-radius: 8px;\n\n    code {\n        display: block;\n    }\n\n    .installation-download,\n    .installation-package-managers {\n        width: 48%;\n        float: left;\n    }\n\n    .installation-col-title {\n        font-size: 22px;\n        padding: 30px 0;\n        color: variables.$text-color;\n    }\n\n    .button {\n        display: block;\n        color: variables.$text-color;\n        border-color: rgba(0, 0, 0, 0.07);\n        background-color: transparent;\n        box-shadow: 0 0 50px rgba(0, 0, 0, 0.03);\n        transition: background-color 150ms, box-shadow 150ms, color 150ms;\n\n        &:hover {\n            text-decoration: none;\n            color: variables.$white;\n            border-color: transparent;\n            background-color: variables.$primary-color;\n            box-shadow: 0 0 50px rgba(variables.$primary-color, 0.4);\n        }\n    }\n\n    .installation-or {\n        position: relative;\n        font-weight: bold;\n        text-transform: uppercase;\n        width: 4%;\n        float: left;\n        font-size: 18px;\n        margin: 140px 0 20px;\n        border-radius: 50px;\n        z-index: 0;\n    }\n\n    .installation-or::before {\n        content: \"\";\n        display: block;\n        position: absolute;\n        top: 50%;\n        left: 50%;\n        z-index: -1;\n        width: 100%;\n        padding-top: 100%;\n        min-width: 45px;\n        min-height: 45px;\n        background: variables.$white;\n        border-radius: 100%;\n        transform: translate(-50%, -50%);\n    }\n\n    .installation-package-managers {\n        font-size: 18px;\n\n        code {\n            padding-top: 5px;\n            line-height: 1.6;\n\n            & + code {\n                padding-top: 0;\n            }\n        }\n    }\n\n    .installation-cdn {\n        clear: both;\n        width: 100%;\n\n        code {\n\n        }\n    }\n}\n"
  },
  {
    "path": "docs/scss/_header.scss",
    "content": "@use \"variables\";\n\n.header-landing {\n    position: relative;\n    background: variables.$primary-color linear-gradient(to bottom left, variables.$primary-color, variables.$primary-color-light);\n    text-align: center;\n    color: variables.$white;\n    padding-bottom: 200px;\n}\n\n.header-nav {\n    float: right;\n    width: 100%;\n    margin: 0;\n    padding: 25px 40px 0;\n    font-weight: 400;\n\n    li {\n        list-style: none;\n        float: right;\n        margin-right: 30px;\n\n        &:first-child {\n            float: left;\n        }\n\n        &:nth-child(2) {\n            margin-right: 0;\n        }\n\n        a {\n            display: block;\n            text-decoration: none;\n            color: variables.$primary-color-dark;\n            font-size: 16px;\n            padding: 10px 0;\n            transition: color variables.$transition-duration;\n\n            &:hover {\n                color: variables.$white;\n            }\n\n            &.view-on-github {\n                transform: translateY(-11px);\n\n                svg {\n                    width: 25px;\n                    height: 25px;\n                    fill: currentColor;\n                    margin-right: 10px;\n                    vertical-align: baseline;\n                    transform: translateY(5px);\n                }\n\n                .star {\n                    font-size: 18px;\n                }\n            }\n        }\n    }\n}\n\n.header-logo-container {\n    margin: 0 auto;\n    padding-top: calc(80px + 4%);\n    text-align: center;\n\n    .header-logo-h1 {\n        position: relative;\n        margin: 0 auto;\n        width: 1000px;\n        max-width: 100%;\n    }\n\n    .header-logo {\n        margin-right: -3%;\n        width: 1000px;\n        max-width: 80%;\n    }\n}\n\n.header-subtitle {\n    font-size: 28px;\n    padding: 0 20px;\n}\n\n.header-description {\n    font-size: 18px;\n    line-height: 1.6;\n    padding: 0 20px;\n    font-weight: 300;\n}\n\n.header-buttons {\n    margin: 50px 0;\n}\n\n.header-install {\n    font-size: 18px;\n    line-height: 1.6;\n    font-weight: 300;\n}\n\n#demonstration {\n    padding-bottom: 0;\n    margin-bottom: 80px;\n\n    .trumbowyg-editor {\n        //height: 300px !important;\n    }\n\n    .trumbowyg-editor,\n    .trumbowyg-textarea {\n        padding: 25px;\n    }\n}\n\n#demonstration .trumbowyg:not(.trumbowyg-fullscreen),\n#trumbowyg-demo:not(.trumbowyg-textarea) {\n    margin: -150px auto 0;\n    width: 100%;\n    height: 340px;\n    max-width: 900px;\n    background: variables.$white;\n    box-shadow: 0 0 27px rgba(0, 0, 0, 0.03);\n    resize: none;\n}\n\n#demonstration .trumbowyg {\n    font-size: 16px;\n    line-height: 2;\n\n    p {\n        margin: 0 0 32px;\n    }\n\n    button {\n        font-weight: 400;\n    }\n}\n\n#trumbowyg-demo:not(.trumbowyg-textarea) {\n    color: transparent;\n    overflow: hidden;\n    border: 1px solid #dbdfe0;\n}\n\n.demo-switcher {\n    position: absolute;\n    bottom: -20px;\n    left: 50%;\n    transform: translateX(-50%);\n    z-index: 10;\n    margin: 0 auto;\n    width: 250px;\n    height: 40px;\n    border-radius: 50px;\n    border: 1px solid #dbdfe0;\n    background: variables.$white;\n\n    .button {\n        display: block;\n        float: left;\n        padding: 10px;\n        margin: 0;\n        border: none;\n        width: 50%;\n        background: none;\n        color: variables.$text-color;\n        font-weight: 300;\n        transition: color variables.$transition-duration, text-indent variables.$transition-duration;\n\n        &:first-child {\n            text-indent: 5px;\n        }\n\n        &:last-child {\n            text-indent: -5px;\n        }\n\n        &.current {\n            text-indent: 0;\n            color: variables.$white;\n        }\n    }\n\n    &::after {\n        content: \"\";\n        display: block;\n        width: 50%;\n        height: 100%;\n        border-radius: 50px;\n        background: variables.$primary-color;\n        transition: margin-left variables.$transition-duration;\n    }\n\n    &.current-plugins {\n        &::after {\n            margin-left: 50%;\n        }\n    }\n}\n\n.header-logo-animation {\n    position: absolute;\n    overflow: hidden;\n    top: -30px;\n    left: 91.5%;\n    width: 150px;\n    height: 150px;\n\n    svg {\n        position: absolute;\n        top: 0;\n        left: 0;\n        fill: variables.$white;\n        height: 25px;\n        width: 25px;\n    }\n\n    .header-logo-animation-strong {\n        animation: headerLogoStrong 1s linear infinite;\n        animation-delay: -0.85s;\n    }\n\n    .header-logo-animation-p {\n        animation: headerLogoP 1s linear infinite;\n        animation-delay: -0.2s;\n    }\n\n    .header-logo-animation-link {\n        animation: headerLogoLink 1s linear infinite;\n        animation-delay: -0.4s;\n    }\n\n    .header-logo-animation-blockquote {\n        animation: headerLogoBlockquote 1s linear infinite;\n        animation-delay: -0.6s;\n    }\n\n    .header-logo-animation-view-html {\n        animation: headerLogoViewHtml 1s linear infinite;\n        animation-delay: -0.3s;\n    }\n}\n\n@keyframes headerLogoStrong {\n    0% {\n        opacity: 1;\n        transform: translateX(-30px) translateY(70px);\n    }\n    20% {\n        transform: translateX(15px) translateY(80px);\n    }\n    30% {\n        transform: translateX(35px) translateY(75px);\n    }\n    40% {\n        transform: translateX(40px) translateY(60px);\n    }\n    50% {\n        opacity: 1;\n        transform: translateX(35px) translateY(40px);\n    }\n    100% {\n        opacity: 0;\n        transform: translateX(10px) translateY(0) scale(0.5);\n    }\n}\n\n@keyframes headerLogoP {\n    0% {\n        opacity: 1;\n        transform: translateX(-30px) translateY(60px);\n    }\n    20% {\n        transform: translateX(10px) translateY(60px);\n    }\n    30% {\n        transform: translateX(20px) translateY(60px);\n    }\n    40% {\n        transform: translateX(25px) translateY(55px);\n    }\n    50% {\n        opacity: 1;\n        transform: translateX(32px) translateY(40px);\n    }\n    90%,\n    100% {\n        opacity: 0;\n        transform: translateX(35px) translateY(20px) scale(0.5);\n    }\n}\n\n@keyframes headerLogoLink {\n    0% {\n        opacity: 1;\n        transform: translateX(-30px) translateY(90px);\n    }\n    20% {\n        transform: translateX(15px) translateY(100px);\n    }\n    30% {\n        transform: translateX(25px) translateY(95px);\n    }\n    40% {\n        transform: translateX(30px) translateY(80px);\n    }\n    50% {\n        opacity: 1;\n        transform: translateX(30px) translateY(70px);\n    }\n    90%,\n    100% {\n        opacity: 0;\n        transform: translateX(10px) translateY(0) scale(0.5);\n    }\n}\n\n@keyframes headerLogoBlockquote {\n    0% {\n        opacity: 1;\n        transform: translateX(-30px) translateY(55px);\n    }\n    30% {\n        transform: translateX(5px) translateY(50px);\n    }\n    40% {\n        transform: translateX(10px) translateY(45px);\n    }\n    50% {\n        opacity: 1;\n        transform: translateX(13px) translateY(40px);\n    }\n    100% {\n        opacity: 0;\n        transform: translateX(10px) translateY(10px) scale(0.5);\n    }\n}\n\n@keyframes headerLogoViewHtml {\n    0% {\n        opacity: 1;\n        transform: translateX(-30px) translateY(90px);\n    }\n    40% {\n        transform: translateX(30px) translateY(105px);\n    }\n    50% {\n        transform: translateX(40px) translateY(100px);\n    }\n    60% {\n        opacity: 1;\n        transform: translateX(50px) translateY(90px);\n    }\n    100% {\n        opacity: 0;\n        transform: translateX(70px) translateY(70px) scale(0.5);\n    }\n}\n"
  },
  {
    "path": "docs/scss/_highlightjs-github.scss",
    "content": "/*!\n    Theme: GitHub\n    Description: Light theme as seen on github.com\n    Author: github.com\n    Maintainer: @Hirse\n    Updated: 2021-05-15\n\n    Outdated base version: https://github.com/primer/github-syntax-light\n    Current colors taken from GitHub's CSS\n*/\n\npre code.hljs {\n    display: block;\n    overflow-x: auto;\n    padding: 0 1.5em;\n    border-radius: 8px;\n    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.02);\n}\n\ncode.hljs {\n    padding: 3px 5px;\n}\n\n.hljs {\n    color: #24292e;\n    background: #fff\n}\n\n.hljs-doctag, .hljs-keyword, .hljs-meta .hljs-keyword, .hljs-template-tag, .hljs-template-variable, .hljs-type, .hljs-variable.language_ {\n    color: #d73a49\n}\n\n.hljs-title, .hljs-title.class_, .hljs-title.class_.inherited__, .hljs-title.function_ {\n    color: #6f42c1\n}\n\n.hljs-attr, .hljs-attribute, .hljs-literal, .hljs-meta, .hljs-number, .hljs-operator, .hljs-selector-attr, .hljs-selector-class, .hljs-selector-id, .hljs-variable {\n    color: #005cc5\n}\n\n.hljs-meta .hljs-string, .hljs-regexp, .hljs-string {\n    color: #032f62\n}\n\n.hljs-built_in, .hljs-symbol {\n    color: #e36209\n}\n\n.hljs-code, .hljs-comment, .hljs-formula {\n    color: #6a737d\n}\n\n.hljs-comment {\n    font-style: italic;\n}\n\n.hljs-name, .hljs-quote, .hljs-selector-pseudo, .hljs-selector-tag {\n    color: #22863a\n}\n\n.hljs-subst {\n    color: #24292e\n}\n\n.hljs-section {\n    color: #005cc5;\n    font-weight: 700\n}\n\n.hljs-bullet {\n    color: #735c0f\n}\n\n.hljs-emphasis {\n    color: #24292e;\n    font-style: italic\n}\n\n.hljs-strong {\n    color: #24292e;\n    font-weight: 700\n}\n\n.hljs-addition {\n    color: #22863a;\n    background-color: #f0fff4\n}\n\n.hljs-deletion {\n    color: #b31d28;\n    background-color: #ffeef0\n}\n"
  },
  {
    "path": "docs/scss/_introduction.scss",
    "content": "@use \"variables\";\n\n.section-introduction {\n    margin-top: 50px;\n    padding-bottom: 70px;\n\n    .introduction-section {\n        height: 300px;\n    }\n\n    .introduction-section-col {\n        position: relative;\n        float: left;\n        width: 30%;\n        margin-right: 5%;\n\n        &:last-child {\n            margin-right: 0;\n        }\n    }\n\n    .introduction-section-col-title {\n        font-size: 28px;\n        font-weight: 300;\n        margin-bottom: 0;\n        padding-top: 50px;\n\n        img {\n            height: 40px;\n            margin-right: 8px;\n            transform: translateY(-3px);\n\n            &.illu-lightweight {\n                transform: translateY(0px);\n            }\n        }\n    }\n\n    .introduction-section-col-description {\n        font-size: 18px;\n        line-height: 28px;\n        margin-top: 10px;\n    }\n}\n"
  },
  {
    "path": "docs/scss/_languages.scss",
    "content": "@use \"variables\";\n\n.languages {\n    p {\n        text-align: center;\n        margin: 0 0 5px;\n        font-size: 18px;\n        color: variables.$white;\n\n        a {\n            color: variables.$primary-color-dark;\n        }\n    }\n\n    .languages-columns {\n        display: flex;\n    }\n\n    .col-globe {\n        flex: 1.07;\n        margin-top: 30px;\n\n        .globe {\n            width: 90%;\n            transform: translateX(-40px);\n        }\n    }\n\n    .col-list {\n        flex: 0.93;\n        padding-top: 80px;\n        line-height: 1.6;\n        font-weight: 400;\n\n        .continent-name {\n            color: variables.$white;\n            font-size: 22px;\n            font-weight: 400;\n            background: none;\n            border: none;\n            padding: 0;\n            margin: 0;\n\n            &:focus {\n                outline: none;\n            }\n\n            &::after {\n                content: \"\";\n                display: inline-block;\n                height: 0;\n                width: 0;\n                border: 6px solid transparent;\n                border-left-color: variables.$white;\n                transform: translateX(5px) translateY(-1px);\n            }\n        }\n\n        li[style] {\n            .continent-name {\n                &::after {\n                    border-left-color: transparent;\n                    border-top-color: variables.$white;\n                    transform: translateX(2px) translateY(2px);\n                }\n            }\n        }\n\n        .lang-code {\n            display: inline-block;\n            min-width: 30px;\n            padding-right: 8px;\n            opacity: 0.6;\n            transition: opacity variables.$transition-duration;\n        }\n\n        .lang-name {\n            transition: padding-left variables.$transition-duration;\n        }\n\n        a {\n            color: variables.$primary-color-dark;\n            transition: color variables.$transition-duration;\n\n            &:hover {\n                color: variables.$white;\n                text-decoration: none;\n\n                .lang-code {\n                    opacity: 1;\n                }\n\n                .lang-name {\n                    padding-left: 8px;\n                }\n            }\n        }\n\n        ul,\n        li {\n            margin: 0;\n            padding: 0;\n            list-style: none;\n        }\n\n        > ul {\n            padding-right: 50px;\n\n            > li {\n                overflow: hidden;\n                transition: height variables.$transition-duration linear;\n\n                &[data-height] {\n                    height: 30px;\n                }\n\n                ul {\n                    padding: 15px 0;\n                    columns: 2;\n                    line-height: 1.8;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "docs/scss/_normalize.scss",
    "content": "/*! normalize.css v1.1.3 | MIT License | git.io/normalize */\n\n/* ==========================================================================\n   HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined in IE 6/7/8/9 and Firefox 3.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n    display: block;\n}\n\n/**\n * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3.\n */\n\naudio,\ncanvas,\nvideo {\n    display: inline-block;\n    *display: inline;\n    *zoom: 1;\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n    display: none;\n    height: 0;\n}\n\n/**\n * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4.\n * Known issue: no IE 6 support.\n */\n\n[hidden] {\n    display: none;\n}\n\n/* ==========================================================================\n   Base\n   ========================================================================== */\n\n/**\n * 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using\n *    `em` units.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n    font-size: 100%; /* 1 */\n    -ms-text-size-adjust: 100%; /* 2 */\n    -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Address `font-family` inconsistency between `textarea` and other form\n * elements.\n */\n\nhtml,\nbutton,\ninput,\nselect,\ntextarea {\n    font-family: sans-serif;\n}\n\n/**\n * Address margins handled incorrectly in IE 6/7.\n */\n\nbody {\n    margin: 0;\n}\n\n/* ==========================================================================\n   Links\n   ========================================================================== */\n\n/**\n * Address `outline` inconsistency between Chrome and other browsers.\n */\n\na:focus {\n    outline: thin dotted;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n    outline: 0;\n}\n\n/* ==========================================================================\n   Typography\n   ========================================================================== */\n\n/**\n * Address font sizes and margins set differently in IE 6/7.\n * Address font sizes within `section` and `article` in Firefox 4+, Safari 5,\n * and Chrome.\n */\n\nh1 {\n    font-size: 2em;\n    margin: 0.67em 0;\n}\n\nh2 {\n    font-size: 1.5em;\n    margin: 0.83em 0;\n}\n\nh3 {\n    font-size: 1.17em;\n    margin: 1em 0;\n}\n\nh4 {\n    font-size: 1em;\n    margin: 1.33em 0;\n}\n\nh5 {\n    font-size: 0.83em;\n    margin: 1.67em 0;\n}\n\nh6 {\n    font-size: 0.67em;\n    margin: 2.33em 0;\n}\n\n/**\n * Address styling not present in IE 7/8/9, Safari 5, and Chrome.\n */\n\nabbr[title] {\n    border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome.\n */\n\nb,\nstrong {\n    font-weight: bold;\n}\n\nblockquote {\n    margin: 1em 40px;\n}\n\n/**\n * Address styling not present in Safari 5 and Chrome.\n */\n\ndfn {\n    font-style: italic;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n * Known issue: no IE 6/7 normalization.\n */\n\nhr {\n    -moz-box-sizing: content-box;\n    box-sizing: content-box;\n    height: 0;\n}\n\n/**\n * Address styling not present in IE 6/7/8/9.\n */\n\nmark {\n    background: #ff0;\n    color: #000;\n}\n\n/**\n * Address margins set differently in IE 6/7.\n */\n\np,\npre {\n    margin: 1em 0;\n}\n\n/**\n * Correct font family set oddly in IE 6, Safari 4/5, and Chrome.\n */\n\ncode,\nkbd,\npre,\nsamp {\n    font-family: monospace, serif;\n    _font-family: 'courier new', monospace;\n    font-size: 1em;\n}\n\n/**\n * Improve readability of pre-formatted text in all browsers.\n */\n\npre {\n    white-space: pre;\n    white-space: pre-wrap;\n    word-wrap: break-word;\n}\n\n/**\n * Address CSS quotes not supported in IE 6/7.\n */\n\nq {\n    quotes: none;\n}\n\n/**\n * Address `quotes` property not supported in Safari 4.\n */\n\nq:before,\nq:after {\n    content: '';\n    content: none;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n    font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n    font-size: 75%;\n    line-height: 0;\n    position: relative;\n    vertical-align: baseline;\n}\n\nsup {\n    top: -0.5em;\n}\n\nsub {\n    bottom: -0.25em;\n}\n\n/* ==========================================================================\n   Lists\n   ========================================================================== */\n\n/**\n * Address margins set differently in IE 6/7.\n */\n\ndl,\nmenu,\nol,\nul {\n    margin: 1em 0;\n}\n\ndd {\n    margin: 0 0 0 40px;\n}\n\n/**\n * Address paddings set differently in IE 6/7.\n */\n\nmenu,\nol,\nul {\n    padding: 0 0 0 40px;\n}\n\n/**\n * Correct list images handled incorrectly in IE 7.\n */\n\nnav ul,\nnav ol {\n    list-style: none;\n    list-style-image: none;\n}\n\n/* ==========================================================================\n   Embedded content\n   ========================================================================== */\n\n/**\n * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3.\n * 2. Improve image quality when scaled in IE 7.\n */\n\nimg {\n    border: 0; /* 1 */\n    -ms-interpolation-mode: bicubic; /* 2 */\n}\n\n/**\n * Correct overflow displayed oddly in IE 9.\n */\n\nsvg:not(:root) {\n    overflow: hidden;\n}\n\n/* ==========================================================================\n   Figures\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11.\n */\n\nfigure {\n    margin: 0;\n}\n\n/* ==========================================================================\n   Forms\n   ========================================================================== */\n\n/**\n * Correct margin displayed oddly in IE 6/7.\n */\n\nform {\n    margin: 0;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n    border: 1px solid #c0c0c0;\n    margin: 0 2px;\n    padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct color not being inherited in IE 6/7/8/9.\n * 2. Correct text not wrapping in Firefox 3.\n * 3. Correct alignment displayed oddly in IE 6/7.\n */\n\nlegend {\n    border: 0; /* 1 */\n    padding: 0;\n    white-space: normal; /* 2 */\n    *margin-left: -7px; /* 3 */\n}\n\n/**\n * 1. Correct font size not being inherited in all browsers.\n * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5,\n *    and Chrome.\n * 3. Improve appearance and consistency in all browsers.\n */\n\nbutton,\ninput,\nselect,\ntextarea {\n    font-size: 100%; /* 1 */\n    margin: 0; /* 2 */\n    vertical-align: baseline; /* 3 */\n    *vertical-align: middle; /* 3 */\n}\n\n/**\n * Address Firefox 3+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\nbutton,\ninput {\n    line-height: normal;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+.\n * Correct `select` style inheritance in Firefox 4+ and Opera.\n */\n\nbutton,\nselect {\n    text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n * 4. Remove inner spacing in IE 7 without affecting normal text inputs.\n *    Known issue: inner spacing remains in IE 6.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n    -webkit-appearance: button; /* 2 */\n    cursor: pointer; /* 3 */\n    *overflow: visible; /* 4 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n    cursor: default;\n}\n\n/**\n * 1. Address box sizing set to content-box in IE 8/9.\n * 2. Remove excess padding in IE 8/9.\n * 3. Remove excess padding in IE 7.\n *    Known issue: excess padding remains in IE 6.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n    box-sizing: border-box; /* 1 */\n    padding: 0; /* 2 */\n    *height: 13px; /* 3 */\n    *width: 13px; /* 3 */\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n    -webkit-appearance: textfield; /* 1 */\n    -moz-box-sizing: content-box;\n    -webkit-box-sizing: content-box; /* 2 */\n    box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari 5 and Chrome\n * on OS X.\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n    -webkit-appearance: none;\n}\n\n/**\n * Remove inner padding and border in Firefox 3+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n    border: 0;\n    padding: 0;\n}\n\n/**\n * 1. Remove default vertical scrollbar in IE 6/7/8/9.\n * 2. Improve readability and alignment in all browsers.\n */\n\ntextarea {\n    overflow: auto; /* 1 */\n    vertical-align: top; /* 2 */\n}\n\n/* ==========================================================================\n   Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n    border-collapse: collapse;\n    border-spacing: 0;\n}\n"
  },
  {
    "path": "docs/scss/_plugins-packages.scss",
    "content": "@use \"variables\";\n\n.plugins-packages {\n    .wrapper {\n        display: flex;\n    }\n\n    .col-plugins {\n        flex: 1.07;\n    }\n\n    .col-packages {\n        flex: 0.93;\n    }\n\n    .section-title {\n        text-align: left;\n        transform: translateX(-5px);\n    }\n\n    p {\n        padding: 0 100px 0 0;\n        line-height: 1.6;\n    }\n\n    ul,\n    li {\n        margin: 0;\n        padding: 0;\n        list-style: none;\n    }\n\n    ul {\n        columns: 2;\n        margin: 50px 0 0;\n        max-width: 500px;\n    }\n\n    li {\n        a {\n            position: relative;\n            display: inline-block;\n            overflow: visible;\n            color: variables.$text-color;\n            transition: color variables.$transition-duration, transform variables.$transition-duration;\n            line-height: 1.8;\n\n            &:hover {\n                color: variables.$primary-color;\n                text-decoration: none;\n            }\n\n            img,\n            svg {\n                display: inline-block;\n                color: variables.$primary-color;\n                fill: variables.$primary-color;\n                width: 20px;\n                height: 20px;\n                margin-right: 8px;\n                vertical-align: sub;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "docs/scss/_section.scss",
    "content": "@use \"variables\";\n\n.section {\n    position: relative;\n    padding-bottom: 100px;\n\n    &-primary {\n        color: variables.$primary-color-dark;\n        background: linear-gradient(to bottom left, variables.$primary-color, variables.$primary-color-light);\n\n        .section-title {\n            color: variables.$white;\n        }\n\n        a {\n            color: variables.$white;\n        }\n    }\n\n    &-secondary {\n        background: variables.$grey;\n    }\n\n    h4 {\n        font-weight: 400;\n        color: variables.$text-color;\n        font-size: 28px;\n        padding-top: 80px;\n    }\n}\n\n.section-title {\n    text-align: center;\n    font-family: variables.$panton;\n    font-size: 100px;\n    color: variables.$primary-color;\n    padding-top: 100px;\n    padding-bottom: 30px;\n}\n\n.section-subtitle {\n    margin-top: -22px;\n    font-size: 23px;\n    color: variables.$text-color;\n    font-weight: 400;\n}\n"
  },
  {
    "path": "docs/scss/_variables.scss",
    "content": "$primary-color: #ff974a;\n$primary-color-light: #ffb864;\n$primary-color-dark: #b65207;\n$secondary-color: #f48d40;\n$text-color: #392813;\n$grey: #f4f7fa;\n$white: #fff;\n\n$panton: \"Panton\", sans-serif;\n$font: \"Open Sans\", sans-serif;\n\n$radius: 6px;\n\n$transition-duration: 150ms;\n"
  },
  {
    "path": "docs/scss/main.scss",
    "content": "@use \"normalize\";\n@use \"variables\";\n@use \"font\";\n@use \"base\";\n@use \"buttons\";\n@use \"header\";\n@use \"section\";\n@use \"introduction\";\n@use \"get-started\";\n@use \"languages\";\n@use \"plugins-packages\";\n@use \"donate\";\n@use \"footer\";\n\n@use \"highlightjs-github\";\n@use \"documentation\";\n"
  },
  {
    "path": "gulpfile.mjs",
    "content": "// jshint node:true\n'use strict';\n\nimport fs from 'fs';\n\nimport gulp from 'gulp';\nimport gulpAutoprefixer from 'gulp-autoprefixer';\nimport gulpConcat from 'gulp-concat';\nimport gulpHeader from 'gulp-header';\nimport gulpJsHint from 'gulp-jshint';\nimport gulpLivereload from 'gulp-livereload';\nimport gulpCleanCss from 'gulp-clean-css';\nimport gulpNewer from 'gulp-newer';\nimport gulpRename from 'gulp-rename';\nimport gulpSassPlugin from 'gulp-sass';\nimport gulpSize from 'gulp-size';\nimport gulpSourcemaps from 'gulp-sourcemaps';\nimport gulpSvgMin from 'gulp-svgmin';\nimport gulpSvgStore from 'gulp-svgstore';\nimport gulpTerser from 'gulp-terser';\nimport {deleteAsync} from 'del';\nimport * as sass from 'sass';\n\nconst gulpSass = () => gulpSassPlugin(sass)();\n\nconst paths = {\n    langs: ['src/langs/**.js', '!src/langs/en.js'],\n    icons: ['src/ui/icons/**.svg', 'plugins/*/ui/icons/**.svg'],\n    scripts: ['src/trumbowyg.js'],\n    styles: ['src/ui/sass/trumbowyg.scss'],\n    pluginsScripts: ['plugins/*/**.js'],\n    pluginsStyles: ['plugins/*/ui/sass/**.scss']\n};\n\nconst pkg = JSON.parse(fs.readFileSync('./package.json', 'utf-8'));\nconst banner = [\n    '/**',\n    ' * <%= pkg.title %> v<%= pkg.version %> - <%= pkg.description %>',\n    ' * <%= description %>',\n    ' * ------------------------',\n    ' * @link <%= pkg.homepage %>',\n    ' * @license <%= pkg.license %>',\n    ' * @author <%= pkg.author.name %>',\n    ' *         Twitter : @AlexandreDemode',\n    ' *         Website : <%= pkg.author.url.replace(\"https://\", \"\") %>',\n    ' */',\n    '\\n'\n].join('\\n');\nconst bannerLight = [\n    '/** <%= pkg.title %> v<%= pkg.version %> - <%= pkg.description %>',\n    ' - <%= pkg.homepage.replace(\"https://\", \"\") %>',\n    ' - License <%= pkg.license %>',\n    ' - Author : <%= pkg.author.name %>',\n    ' / <%= pkg.author.url.replace(\"https://\", \"\") %>',\n    ' */',\n    '\\n'\n].join('');\n\n\nconst clean = function () {\n    return deleteAsync(['dist/*']);\n};\n\nconst lint = function () {\n    return gulp.src([\n        ...paths.scripts,\n        ...paths.pluginsScripts,\n        ...paths.langs,\n    ])\n        .pipe(gulpJsHint())\n        .pipe(gulpJsHint.reporter('jshint-stylish', {}))\n        .pipe(gulpJsHint.reporter('fail', {}));\n};\n\nconst scripts = function scripts() {\n    return gulp.src(paths.scripts)\n        .pipe(gulpHeader(banner, {pkg: pkg, description: 'Trumbowyg core file'}))\n        .pipe(gulpNewer('dist/trumbowyg.js'))\n        .pipe(gulpConcat('trumbowyg.js', {newLine: '\\r\\n\\r\\n'}))\n        .pipe(gulp.dest('dist/'))\n        .pipe(gulpSize({title: 'trumbowyg.js'}))\n        .pipe(gulpRename({suffix: '.min'}))\n        .pipe(gulpTerser({\n            format: {\n                comments: false\n            }\n        }))\n        .pipe(gulpHeader(bannerLight, {pkg: pkg}))\n        .pipe(gulp.dest('dist/'))\n        .pipe(gulpSize({title: 'trumbowyg.min.js'}));\n};\n\nconst pluginsScripts = function pluginsScripts() {\n    return gulp.src(paths.pluginsScripts)\n        .pipe(gulp.dest('dist/plugins/'))\n        .pipe(gulpRename({suffix: '.min'}))\n        .pipe(gulpTerser({\n            format: {\n                comments: /trumbowyg\\./\n            }\n        }))\n        .pipe(gulp.dest('dist/plugins/'));\n};\n\nconst langs = function langs() {\n    return gulp.src(paths.langs)\n        .pipe(gulp.dest('dist/langs/'))\n        .pipe(gulpRename({suffix: '.min'}))\n        .pipe(gulpTerser({\n            format: {\n                comments: 'all'\n            }\n        }))\n        .pipe(gulp.dest('dist/langs/'));\n};\n\n\nconst icons = function () {\n    return gulp.src(paths.icons)\n        .pipe(gulpRename({prefix: 'trumbowyg-'}))\n        .pipe(gulpSvgMin())\n        .pipe(gulpSvgStore({inlineSvg: true}))\n        .pipe(gulp.dest('dist/ui/'));\n};\n\n\nconst styles = function () {\n    let stylesPipe = gulp.src(paths.styles)\n        .pipe(gulpSass());\n\n    if (process.env.ENV !== 'production') {\n        stylesPipe = stylesPipe.pipe(gulpSourcemaps.init());\n    }\n\n    stylesPipe = stylesPipe\n        .pipe(gulpAutoprefixer(['last 2 version', '> 1%'], {cascade: true}))\n        .pipe(gulpHeader(banner, {pkg: pkg, description: 'Default stylesheet for Trumbowyg editor'}))\n        .pipe(gulp.dest('dist/ui/'))\n        .pipe(gulpSize({title: 'trumbowyg.css'}))\n        .pipe(gulpRename({suffix: '.min'}))\n        .pipe(gulpCleanCss())\n        .pipe(gulpHeader(bannerLight, {pkg: pkg}));\n\n    if (process.env.ENV !== 'production') {\n        stylesPipe = stylesPipe.pipe(gulpSourcemaps.write('.'));\n    }\n\n    stylesPipe = stylesPipe\n        .pipe(gulp.dest('dist/ui/'))\n        .pipe(gulpSize({title: 'trumbowyg.min.css'}));\n\n    return stylesPipe;\n};\n\nconst sassDist = gulp.series(styles, function sassDist() {\n    return gulp.src(paths.styles)\n        .pipe(gulpHeader(banner, {pkg: pkg, description: 'Default stylesheet for Trumbowyg editor'}))\n        .pipe(gulp.dest('dist/ui/sass'));\n});\n\nconst pluginsStyles = function () {\n    return gulp.src(paths.pluginsStyles)\n        .pipe(gulpSass())\n        .pipe(gulpAutoprefixer(['last 2 version', '> 1%'], {cascade: true}))\n        .pipe(gulpHeader(banner, {pkg: pkg, description: 'Trumbowyg plugin stylesheet'}))\n        .pipe(gulpRename(function (path) {\n            path.dirname += '/..';\n        }))\n        .pipe(gulp.dest('dist/plugins/'))\n        .pipe(gulpRename({suffix: '.min'}))\n        .pipe(gulpCleanCss())\n        .pipe(gulpHeader(bannerLight, {pkg: pkg}))\n        .pipe(gulp.dest('dist/plugins/'))\n        .pipe(gulpSize({title: 'Plugins styles'}));\n};\n\nconst pluginsSassDist = gulp.series(pluginsStyles, function pluginsSassDist() {\n    return gulp.src(paths.pluginsStyles)\n        .pipe(gulpHeader(banner, {pkg: pkg, description: 'Trumbowyg plugin stylesheet'}))\n        .pipe(gulp.dest('dist/plugins'));\n});\n\n\nconst watch = function () {\n    gulp.watch([\n        ...paths.scripts,\n        ...paths.pluginsScripts,\n        ...paths.langs,\n    ], lint);\n    gulp.watch(paths.icons, icons);\n    gulp.watch(paths.scripts, scripts);\n    gulp.watch(paths.langs, langs);\n    gulp.watch(paths.pluginsScripts, pluginsScripts);\n    gulp.watch(paths.pluginsStyles, pluginsStyles);\n    gulp.watch(paths.styles, styles);\n\n    gulp.watch(['dist/**', 'dist/*/**'], function (file) {\n        gulpLivereload.changed(file);\n    });\n\n    gulpLivereload.listen();\n};\n\nconst build = gulp.series(clean, gulp.parallel(\n    scripts,\n    pluginsScripts,\n    langs,\n    icons,\n    sassDist,\n    pluginsSassDist\n));\n\nconst buildAndWatch = gulp.series(build, watch);\n\nexport default buildAndWatch;\nexport {\n    clean,\n    build,\n    lint,\n    watch\n};\n"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Trumbowyg by Alex-D</title>\n    <base href=\"/test/base/url/\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">\n    <style>\n        html,\n        body {\n            margin: 0;\n            padding: 0;\n            background-color: #f4f7fa;\n            font-family: \"Trebuchet MS\", Verdana, Arial, Helvetica, sans-serif;\n        }\n\n        header {\n            text-align: center;\n        }\n\n        .container {\n            max-width: 960px;\n            margin: 0 auto;\n        }\n\n        .dark-section {\n            background: #111;\n            color: #ddd;\n            margin-top: 50px;\n            padding: 50px 0 100px;\n        }\n\n        .dark-section .title {\n            font-weight: normal;\n            text-align: center;\n            font-size: 32px;\n            margin: 20px 0 50px;\n        }\n\n        .form-submit {\n            background: transparent;\n            border: 1px solid #555;\n            color: #ccc;\n            padding: 7px 13px;\n            margin-right: 17px;\n            float: right;\n        }\n\n        .trumbowyg {\n            margin-bottom: 32px;\n        }\n\n        h2 {\n            font-size: 26px;\n            margin-top: 0;\n        }\n\n        h1 + pre,\n        h2 + pre,\n        h3 + pre,\n        h4 + pre {\n            margin-top: -20px;\n        }\n\n        p {\n            margin-top: 0;\n        }\n\n        :root {\n            --tbw-cell-vertical-padding: 4px;\n            --tbw-cell-horizontal-padding: 8px;\n            --tbw-cell-line-height: 1.5em;\n        }\n\n        table {\n            margin-bottom: var(--tbw-cell-line-height);\n        }\n\n        th,\n        td {\n            height: calc(var(--tbw-cell-vertical-padding) * 2 + var(--tbw-cell-line-height));\n            min-width: calc(var(--tbw-cell-horizontal-padding) * 2);\n            padding: var(--tbw-cell-vertical-padding) var(--tbw-cell-horizontal-padding);\n            border: 1px solid #e7eaec;\n        }\n\n        thead {\n            background: #FFFFFF;\n        }\n\n        /* Custom tag classes test */\n        .container img.class-image {\n            max-width: 50%;\n        }\n        .container [class^=\"class-\"] {\n            border-bottom: 3px solid #89ff4a;\n        }\n    </style>\n    <link rel=\"stylesheet\" href=\"/dist/ui/trumbowyg.css\">\n    <link rel=\"stylesheet\" href=\"/dist/plugins/colors/ui/trumbowyg.colors.css\">\n</head>\n<body>\n<div class=\"container\">\n    <header>\n        <h1>Trumbowyg examples</h1>\n\n        <p>\n            Close an editor on clic on \"Close\" in top right corner. <br>\n            To reopen an editor, double-click on his text.\n        </p>\n    </header>\n\n    <div id=\"default-editor\">\n        <h2>This editor is the default build of Trumbowyg.</h2>\n        <p>\n            Lorem ipsum dolor sit amet, <a href=\"https://alex-d.github.io/Trumbowyg/\">consectetur adipisicing</a> elit.\n            Possimus, aliquam, minima fugiat placeat provident optio nam reiciendis eius beatae quibusdam!\n        </p>\n        <p>\n            The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n            alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n            qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n            anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n        </p>\n        <code><pre>\n$('#default-editor').trumbowyg();\n                </pre>\n        </code>\n    </div>\n    <button id=\"reset-default-editor\">Reset</button>\n\n    <div id=\"simple-editor\">\n        <h2>This is a minimalist demo of Trumbowyg.</h2>\n        <p>\n            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n            optio nam reiciendis eius beatae quibusdam!\n        </p>\n        <code><pre>\n$('#simple-editor').trumbowyg({\n    btns: ['strong', 'em', 'del']\n});\n                </pre>\n        </code>\n    </div>\n\n    <div id=\"upload-editor\">\n        <h2>This is a minimalist demo of Trumbowyg with upload image plugin.</h2>\n        <p>\n            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n            optio nam reiciendis eius beatae quibusdam!\n        </p>\n        <code><pre>\n$('#simple-editor').trumbowyg({\n    btns: ['strong', 'em', 'del', 'upload'],\n    btnsDef: {\n        upload: {\n            ico: 'insertImage'\n        }\n    }\n});\n                </pre>\n        </code>\n    </div>\n\n    <div id=\"flat-buttonpane\">\n        <h2>All buttons of Trumbowyg are here.</h2>\n        <p>\n            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus, aliquam, minima fugiat placeat provident\n            optio nam reiciendis eius beatae quibusdam!\n        </p>\n    </div>\n\n    <div id=\"customized-buttonpane\">\n        <h2>This is a demo of Trumbowyg with a customized button pane & tagClasses</h2>\n        <p>\n            The text is derived from Cicero's De Finibus Bonorum et Malorum (On the Ends of Goods and Evils, or\n            alternatively [About] The Purposes of Good and Evil ). The original passage began: Neque porro quisquam est\n            qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit (Translation: &quot;Neither is there\n            anyone who loves grief itself since it is grief and thus wants to obtain it&quot;).\n        </p>\n        <p style=\"text-align: center;\">\n            <img src=\"https://raw.githubusercontent.com/Alex-D/Trumbowyg/develop/banner.jpg\" alt=\"Trumbowyg logo\">\n        </p>\n        <p>\n            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos, minima, asperiores libero architecto\n            sequi fugit dolore sunt in officiis facere ut quaerat ullam laudantium delectus aliquam tenetur alias! Ea,\n            nisi, est earum temporibus dolores quas qui repellendus aliquid voluptatibus tempore facilis eligendi omnis\n            reiciendis nihil ullam quo dolorem nam deleniti. Fugit dignissimos dolorum dolore voluptate repudiandae\n            recusandae debitis. Neque, adipisci, maiores magni aliquam molestiae ex natus minus quod tempora nemo\n            debitis eum laboriosam voluptatum ut architecto animi nobis vero quis dolore eaque! Corporis, dolore, illum,\n            autem in eum ea doloribus ut consequuntur modi et ullam adipisci blanditiis corrupti ab voluptate.\n        </p>\n        <p>\n            It is not known exactly when the text acquired its current standard form; it may have been as late as the\n            1960s. The passage was discovered by Richard McClintock, a Latin scholar who is the publications director at\n            Hampden-Sydney College in Virginia, by searching for citings of the rarely used word 'consectetur' in\n            classical literature.\n        </p>\n        <code><pre>\n/* Add new words for customs btnsDef just below */\n$.extend(true, $.trumbowyg.langs, {\nfr: {\n    align: 'Alignement',\n    image: 'Image'\n}\n});\n$('#customized-buttonpane').trumbowyg({\nlang: 'fr',\nfixedBtnPane: true,\nsemantic: false,\nbtnsDef: {\n    // Customizables dropdowns\n    align: {\n        dropdown: ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n        ico: 'justifyLeft'\n    },\n    image: {\n        dropdown: ['insertImage', 'upload', 'base64'],\n        ico: 'insertImage'\n    }\n},\nbtns: ['viewHTML',\n    ['formatting'],\n    ['align'],\n    ['image'],\n    ['preformatted'],\n    'fullscreen', 'close']\n});\n                </pre>\n        </code>\n    </div>\n\n    <textarea id=\"form-content\" cols=\"30\" rows=\"10\" required>\n                <h1>This editor is create from a textarea</h1>\n                <p>\n                    Even though using &quot;lorem ipsum&quot; often arouses curiosity due to its resemblance to classical Latin, it is not intended to have meaning. Where text is visible in a document, people tend to focus on the textual content rather than upon overall presentation, so publishers use lorem ipsum when displaying a typeface or design in order to direct the focus to presentation. &quot;Lorem ipsum&quot; also approximates a typical distribution of spaces in English. <br>\n                    The most common lorem ipsum text reads as follows: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n                </p>\n                <code><pre>\n$('#form-content').trumbowyg({\n    lang: 'fr',\n    mobile: true,\n    fixedBtnPane: true,\n    fixedFullWidth: true,\n    semantic: true,\n    resetCss: true,\n    autoAjustHeight: true,\n    autogrow: true\n});\n                </pre></code>\n            </textarea>\n\n    <textarea id=\"empty-textarea\" cols=\"30\" rows=\"10\" required></textarea>\n\n    <textarea id=\"disabled-textarea\" cols=\"30\" rows=\"10\" disabled>\n                Disabled textarea\n            </textarea>\n    <button id=\"enable-disabled-textarea\">Enable</button>\n    <button id=\"disable-disabled-textarea\">Disable</button>\n\n    <div id=\"dynamic-iframe-example\"></div>\n</div>\n\n<div class=\"dark-section\">\n    <div class=\"container\">\n        <form action=\"#\">\n            <h2 class=\"title\">The dark side of Trumbowyg</h2>\n\n            <div class=\"trumbowyg-dark\">\n                <textarea\n                    id=\"placeholder-editor\"\n                    cols=\"30\"\n                    rows=\"10\"\n                    placeholder=\"This is a placeholder...\"\n                    required\n                ></textarea>\n            </div>\n\n            <button type=\"submit\" class=\"form-submit\">Submit</button>\n        </form>\n    </div>\n</div>\n\n<script src=\"/node_modules/jquery/dist/jquery.min.js\"></script>\n<script src=\"/dist/trumbowyg.js\"></script>\n<script src=\"/dist/langs/fr.min.js\"></script>\n<script src=\"/dist/plugins/base64/trumbowyg.base64.js\"></script>\n<script src=\"/dist/plugins/colors/trumbowyg.colors.js\"></script>\n<script src=\"/dist/plugins/noembed/trumbowyg.noembed.js\"></script>\n<script src=\"/dist/plugins/pasteimage/trumbowyg.pasteimage.js\"></script>\n<script src=\"/dist/plugins/template/trumbowyg.template.js\"></script>\n<script src=\"/dist/plugins/preformatted/trumbowyg.preformatted.js\"></script>\n<script src=\"/dist/plugins/ruby/trumbowyg.ruby.js\"></script>\n<script src=\"/dist/plugins/upload/trumbowyg.upload.js\"></script>\n<script>\n    /** Default editor configuration **/\n    $('#default-editor, #empty-textarea, #disabled-textarea')\n        .trumbowyg()\n        .on('tbwinit tbwfocus tbwblur tbwchange tbwresize tbwpaste tbwopenfullscreen tbwclosefullscreen tbwclose', function (e) {\n            console.log(e.type);\n        });\n\n    $('#reset-default-editor').click(function () {\n        $('#default-editor').trumbowyg('empty');\n        console.log($('#default-editor').trumbowyg('html'));\n    });\n\n    $('#enable-disabled-textarea').click(function () {\n        $('#disabled-textarea').trumbowyg('enable');\n    });\n    $('#disable-disabled-textarea').click(function () {\n        $('#disabled-textarea').trumbowyg('disable');\n    });\n\n\n    /** Minimal configuration **/\n    $('#simple-editor')\n        .trumbowyg({\n            btns: ['strong', 'em', 'del']\n        });\n\n\n    /** Minimal with upload **/\n    $('#upload-editor')\n        .trumbowyg({\n            btns: ['strong', 'em', 'del', 'upload'],\n            btnsDef: {\n                upload: {\n                    ico: 'insertImage',\n                    title: 'insertImage'\n                }\n            }\n        });\n\n\n    /* Add imgur parameters to upload plugin */\n    var uploadOptions = {\n        serverPath: 'https://api.imgur.com/3/image',\n        fileFieldName: 'image',\n        headers: {'Authorization': 'Client-ID 9e57cb1c4791cea'},\n        urlPropertyName: 'data.link',\n        imageWidthModalEdit: true\n    };\n\n    /** Full flat button pane **/\n    $('#flat-buttonpane')\n        .trumbowyg({\n            btns: [\n                ['viewHTML'],\n                ['p', 'blockquote', 'h1', 'h2', 'h3', 'h4'],\n                ['strong', 'em', 'underline', 'del'],\n                ['superscript', 'subscript'],\n                ['createLink', 'unlink'],\n                ['insertImage'],\n                ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n                ['unorderedList', 'orderedList'],\n                ['horizontalRule'],\n                ['removeformat'],\n\n                ['upload', 'base64', 'noembed'],\n                ['ruby'],\n                ['foreColor', 'backColor'],\n                ['preformatted'],\n                ['template'],\n                ['fullscreen', 'close']\n            ],\n            plugins: {\n                upload: uploadOptions,\n                templates: [\n                    {\n                        name: 'Template 1',\n                        html: '<p>I am a template!</p>'\n                    },\n                    {\n                        name: 'Template 2',\n                        html: '<p>I am a different template!</p>'\n                    }\n                ]\n            }\n        });\n\n\n    // Customized button pane + buttons groups + dropdowns\n    // Use upload and base64 plugins\n\n    /* Add new words for customs btnsDef just below */\n    $.extend(true, $.trumbowyg.langs, {\n        fr: {\n            align: 'Alignement',\n            image: 'Image'\n        }\n    });\n    var customizedButtonPaneTbwOptions = {\n        lang: 'fr',\n        fixedBtnPane: true,\n        semantic: false,\n        btnsDef: {\n            // Customizable dropdowns\n            align: {\n                dropdown: ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n                ico: 'justifyLeft'\n            },\n            image: {\n                dropdown: ['insertImage', 'upload', 'base64', 'noembed'],\n                ico: 'insertImage'\n            }\n        },\n        btns: [\n            ['viewHTML'],\n            ['formatting'],\n            ['bold', 'italic', 'strikethrough'],\n            ['link'],\n            ['align'],\n            ['image'],\n            ['foreColor', 'backColor'],\n            ['preformatted'],\n            ['fullscreen', 'close']\n        ],\n        changeActiveDropdownIcon: true,\n        minimalLinks: true,\n        defaultLinkTarget: '_blank',\n        plugins: {\n            upload: uploadOptions\n        },\n        tagClasses: {\n            img: 'class-image',\n            p: 'class-paragraph',\n            b: 'class-bold',\n            i: 'class-italic',\n            s: 'class-strikethrough',\n            a: 'class-link',\n        }\n    };\n    $('#customized-buttonpane')\n        .trumbowyg(customizedButtonPaneTbwOptions)\n        .on('dblclick', function () {\n            $(this).trumbowyg(customizedButtonPaneTbwOptions);\n        });\n\n\n    /** Simple customization with current options **/\n    var formTbwOptions = {\n        lang: 'fr',\n        mobile: true,\n        fixedBtnPane: true,\n        fixedFullWidth: true,\n        semantic: true,\n        resetCss: true,\n        removeformatPasted: true,\n        tagsToRemove: ['script', 'style'],\n        imageWidthModalEdit: true,\n\n        autogrow: true,\n        autogrowOnEnter: true,\n\n        btnsDef: {\n            strong: {\n                fn: 'bold',\n                key: 'G'\n            }\n        }\n    };\n    $('#form-content')\n        .trumbowyg(formTbwOptions)\n        .on('dblclick', function () {\n            $(this).trumbowyg(formTbwOptions);\n        });\n\n\n    /** Dynamic Iframe **/\n\n        // Create the iframe element.\n    var $iframe = $('<iframe/>').css({\n            width: '100%',\n            height: 400,\n            border: 0\n        });\n    $('#dynamic-iframe-example').append($iframe);\n    // Get the document of the iframe.\n    var $editor = $('<div>', {\n        id: 'editor'\n    }).html(\n        '<h2>This is within an iframe</h2> <p>Soc'\n        + 'tempor pulvinar ac ultricies, placerat in, elementum,'\n        + 'adipiscing pid, mid augue pulvinar eros nisi! In magn'\n        + 'magnis. Porttitor platea turpis nisi. Pulvinar massa,'\n        + ' habitasse <strong>a nunc rhoncus adipiscing</strong></p>');\n\n    setTimeout(function () {\n        var contextIframe = $iframe.contents()[0];\n        // Set the style on the head of the iframe.\n        $('head', contextIframe).append($('<link>', {\n            href: '/dist/ui/trumbowyg.css',\n            rel: 'stylesheet'\n        }));\n        // Set the content to be editable.\n        $('body', contextIframe).append($editor);\n\n        $editor\n            .trumbowyg()\n            .on('dblclick', function () {\n                $(this).trumbowyg();\n            });\n    }, 500);\n\n\n    /** Editor with placeholder **/\n    $('#placeholder-editor')\n        .trumbowyg({\n            autogrowOnEnter: true\n        })\n        .on('dblclick', function () {\n            $(this).trumbowyg();\n        })\n        .on('tbwfocus', function () {\n            console.log('focus event fired');\n        })\n        .on('tbwblur', function () {\n            console.log('blur event fired');\n        });\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"trumbowyg\",\n  \"title\": \"Trumbowyg\",\n  \"description\": \"A lightweight WYSIWYG editor\",\n  \"version\": \"2.31.0\",\n  \"main\": \"dist/trumbowyg.js\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"dev\": \"gulp\",\n    \"build\": \"gulp build\",\n    \"clean\": \"gulp clean\",\n    \"lint\": \"gulp lint\",\n    \"lint:editorconfig\": \"editorconfig-checker\"\n  },\n  \"devDependencies\": {\n    \"del\": \"^8.0.0\",\n    \"editorconfig-checker\": \"^6.0.1\",\n    \"gulp\": \"^5.0.0\",\n    \"gulp-autoprefixer\": \"^9.0.0\",\n    \"gulp-clean-css\": \"^4.3.0\",\n    \"gulp-concat\": \"^2.6.1\",\n    \"gulp-header\": \"^2.0.9\",\n    \"gulp-jshint\": \"^2.1.0\",\n    \"gulp-livereload\": \"^4.0.2\",\n    \"gulp-newer\": \"^1.4.0\",\n    \"gulp-rename\": \"^2.0.0\",\n    \"gulp-sass\": \"^6.0.0\",\n    \"gulp-size\": \"^5.0.0\",\n    \"gulp-sourcemaps\": \"^3.0.0\",\n    \"gulp-svgmin\": \"^4.1.0\",\n    \"gulp-svgstore\": \"^9.0.0\",\n    \"gulp-terser\": \"^2.1.0\",\n    \"jquery\": \"^4.0.0-beta.2\",\n    \"jshint\": \"^2.13.6\",\n    \"jshint-stylish\": \"^2.2.1\",\n    \"sass\": \"^1.83.4\"\n  },\n  \"peerDependencies\": {\n    \"jquery\": \">=1.8\"\n  },\n  \"homepage\": \"https://alex-d.github.io/Trumbowyg/\",\n  \"author\": {\n    \"name\": \"Alexandre Demode (Alex-D)\",\n    \"email\": \"contact@alex-d.fr\",\n    \"url\": \"https://alex-d.fr\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Alex-D/Trumbowyg.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/Alex-D/Trumbowyg/issues\"\n  },\n  \"keywords\": [\n    \"wysiwyg\",\n    \"editor\",\n    \"rich text\",\n    \"contenteditable\",\n    \"trumbowyg\"\n  ],\n  \"volta\": {\n    \"node\": \"22.13.1\"\n  }\n}\n"
  },
  {
    "path": "plugins/allowtagsfrompaste/trumbowyg.allowtagsfrompaste.js",
    "content": "/* ===========================================================\n * trumbowyg.allowTagsFromPaste.js v1.0.2\n * It cleans tags from pasted text, whilst allowing several specified tags\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author\t: Fathi Anshory (0x00000F5C)\n * Twitter\t: @fscchannl\n * Notes:\n *  - removeformatPasted must be set to FALSE since it was applied prior to pasteHandlers, or else it will be useless\n *\t- It is most advisable to use along with the cleanpaste plugin, or else you'd end up with dirty markup\n */\n\n(function ($) {\n    'use strict';\n\n    var defaultOptions = {\n        // When empty, all tags are allowed making this plugin useless\n        // If you want to remove all tags, use removeformatPasted core option instead\n        allowedTags: [],\n        // List of tags which can be allowed\n        removableTags: [\n            'a',\n            'abbr',\n            'address',\n            'b',\n            'bdi',\n            'bdo',\n            'blockquote',\n            'br',\n            'cite',\n            'code',\n            'del',\n            'dfn',\n            'details',\n            'em',\n            'h1',\n            'h2',\n            'h3',\n            'h4',\n            'h5',\n            'h6',\n            'hr',\n            'i',\n            'ins',\n            'kbd',\n            'mark',\n            'meter',\n            'pre',\n            'progress',\n            'q',\n            'rp',\n            'rt',\n            'ruby',\n            's',\n            'samp',\n            'small',\n            'span',\n            'strong',\n            'sub',\n            'summary',\n            'sup',\n            'time',\n            'u',\n            'var',\n            'wbr',\n            'img',\n            'map',\n            'area',\n            'canvas',\n            'figcaption',\n            'figure',\n            'picture',\n            'audio',\n            'source',\n            'track',\n            'video',\n            'ul',\n            'ol',\n            'li',\n            'dl',\n            'dt',\n            'dd',\n            'table',\n            'caption',\n            'th',\n            'tr',\n            'td',\n            'thead',\n            'tbody',\n            'tfoot',\n            'col',\n            'colgroup',\n            'style',\n            'div',\n            'p',\n            'form',\n            'input',\n            'textarea',\n            'button',\n            'select',\n            'optgroup',\n            'option',\n            'label',\n            'fieldset',\n            'legend',\n            'datalist',\n            'keygen',\n            'output',\n            'iframe',\n            'link',\n            'nav',\n            'header',\n            'hgroup',\n            'footer',\n            'main',\n            'section',\n            'article',\n            'aside',\n            'dialog',\n            'script',\n            'noscript',\n            'embed',\n            'object',\n            'param'\n        ]\n    };\n\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            allowTagsFromPaste: {\n                init: function (trumbowyg) {\n                    if (!trumbowyg.o.plugins.allowTagsFromPaste) {\n                        return;\n                    }\n\n                    // Force disable remove format pasted\n                    trumbowyg.o.removeformatPasted = false;\n\n                    var allowedTags = trumbowyg.o.plugins.allowTagsFromPaste.allowedTags || defaultOptions.allowedTags;\n                    var removableTags = trumbowyg.o.plugins.allowTagsFromPaste.removableTags || defaultOptions.removableTags;\n\n                    if (allowedTags.length === 0) {\n                        return;\n                    }\n\n                    // Get list of tags to remove\n                    var tagsToRemove = $(removableTags).not(allowedTags).get();\n\n                    trumbowyg.pasteHandlers.push(function () {\n                        setTimeout(function () {\n                            var processNodes = trumbowyg.$ed.html();\n                            $.each(tagsToRemove, function (iterator, tagName) {\n                                processNodes = processNodes.replace(new RegExp('<\\\\/?' + tagName + '(\\\\s[^>]*)?>', 'gi'), '');\n                            });\n                            trumbowyg.$ed.html(processNodes);\n                        }, 0);\n                    });\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/base64/trumbowyg.base64.js",
    "content": "/* ===========================================================\n * trumbowyg.base64.js v1.0\n * Base64 plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Cyril Biencourt (lizardK)\n */\n\n(function ($) {\n    'use strict';\n\n    var isSupported = function () {\n        return typeof FileReader !== 'undefined';\n    };\n\n    var isValidImage = function (type) {\n        return /^data:image\\/[a-z]?/i.test(type);\n    };\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                base64: 'Image as base64',\n                file: 'File',\n                errFileReaderNotSupported: 'FileReader is not supported by your browser.',\n                errInvalidImage: 'Invalid image file.'\n            },\n            az: {\n                base64: 'base64 olaraq şəkil',\n                file: 'Fayl',\n                errFileReaderNotSupported: 'FileReader brauzeriniz tərəfindən dəstəklənmir.',\n                errInvalidImage: 'Yanlış şəkil faylı.'\n            },\n            by: {\n                base64: 'Выява (фармат base64)',\n                file: 'Файл',\n                errFileReaderNotSupported: 'FileReader не падтрымліваецца вашым браўзэрам.',\n                errInvalidImage: 'Несапраўдны файл выявы.'\n            },\n            cs: {\n                base64: 'Vložit obrázek',\n                file: 'Soubor'\n            },\n            da: {\n                base64: 'Billede som base64',\n                file: 'Fil',\n                errFileReaderNotSupported: 'FileReader er ikke understøttet af din browser.',\n                errInvalidImage: 'Ugyldig billedfil.'\n            },\n            de: {\n                base64: 'Bild als base64',\n                file: 'Datei',\n                errFileReaderNotSupported: 'FileReader ist nicht in deinem Browser unterstützt.',\n                errInvalidImage: 'Ungültige Bilddatei.'\n            },\n            et: {\n                base64: 'Pilt base64 formaadis',\n                file: 'Fail',\n                errFileReaderNotSupported: 'Teie veebilehitseja ei toeta FileReader funktsiooni.',\n                errInvalidImage: 'Vigane pildifail.'\n            },\n            fr: {\n                base64: 'Image en base64',\n                file: 'Fichier',\n                errFileReaderNotSupported: 'FileReader n\\'est pas supporté par votre navigateur.',\n                errInvalidImage: 'Fichier image invalide.'\n            },\n            hu: {\n                base64: 'Kép beszúrás inline',\n                file: 'Fájl',\n                errFileReaderNotSupported: 'Ez a böngésző nem támogatja a FileReader funkciót.',\n                errInvalidImage: 'Érvénytelen képfájl.'\n            },\n            ja: {\n                base64: '画像 (Base64形式)',\n                file: 'ファイル',\n                errFileReaderNotSupported: 'あなたのブラウザーはFileReaderをサポートしていません',\n                errInvalidImage: '画像形式が正しくありません'\n            },\n            ko: {\n                base64: '그림 넣기(base64)',\n                file: '파일',\n                errFileReaderNotSupported: 'FileReader가 현재 브라우저를 지원하지 않습니다.',\n                errInvalidImage: '유효하지 않은 파일'\n            },\n            nl: {\n                base64: 'Afbeelding inline',\n                file: 'Bestand',\n                errFileReaderNotSupported: 'Uw browser ondersteunt deze functionaliteit niet.',\n                errInvalidImage: 'De gekozen afbeelding is ongeldig.'\n            },\n            pt_br: {\n                base64: 'Imagem em base64',\n                file: 'Arquivo',\n                errFileReaderNotSupported: 'FileReader não é suportado pelo seu navegador.',\n                errInvalidImage: 'Arquivo de imagem inválido.'\n            },\n            ru: {\n                base64: 'Изображение как код в base64',\n                file: 'Файл',\n                errFileReaderNotSupported: 'FileReader не поддерживается вашим браузером.',\n                errInvalidImage: 'Недопустимый файл изображения.'\n            },\n            sl: {\n                base64: 'Slika kot base64',\n                file: 'Datoteka',\n                errFileReaderNotSupported: 'FileReader ni podprt v tem brskalniku.',\n                errInvalidImage: 'Neveljavna datoteka s sliko.'\n            },\n            tr: {\n                base64: 'Base64 olarak resim',\n                file: 'Dosya',\n                errFileReaderNotSupported: 'FileReader tarayıcınız tarafından desteklenmiyor.',\n                errInvalidImage: 'Geçersiz resim dosyası.'\n            },\n            zh_cn: {\n                base64: '图片（Base64编码）',\n                file: '文件'\n            },\n            zh_tw: {\n                base64: '圖片(base64編碼)',\n                file: '檔案',\n                errFileReaderNotSupported: '你的瀏覽器不支援FileReader',\n                errInvalidImage: '不正確的檔案格式'\n            },\n        },\n        // jshint camelcase:true\n\n        plugins: {\n            base64: {\n                shouldInit: isSupported,\n                init: function (trumbowyg) {\n                    var btnDef = {\n                        isSupported: isSupported,\n                        fn: function () {\n                            trumbowyg.saveRange();\n\n                            var file;\n                            var $modal = trumbowyg.openModalInsert(\n                                // Title\n                                trumbowyg.lang.base64,\n\n                                // Fields\n                                {\n                                    file: {\n                                        type: 'file',\n                                        required: true,\n                                        attributes: {\n                                            accept: 'image/*'\n                                        }\n                                    },\n                                    alt: {\n                                        label: 'description',\n                                        value: trumbowyg.getRangeText()\n                                    }\n                                },\n\n                                // Callback\n                                function (values) {\n                                    var fReader = new FileReader();\n\n                                    fReader.onloadend = function (e) {\n                                        if (isValidImage(e.target.result)) {\n                                            trumbowyg.execCmd('insertImage', fReader.result, false, true);\n                                            $(['img[src=\"', fReader.result, '\"]:not([alt])'].join(''), trumbowyg.$box).attr('alt', values.alt);\n                                            trumbowyg.syncCode();\n                                            trumbowyg.closeModal();\n                                        } else {\n                                            trumbowyg.addErrorOnModalField(\n                                                $('input[type=file]', $modal),\n                                                trumbowyg.lang.errInvalidImage\n                                            );\n                                        }\n                                    };\n\n                                    fReader.readAsDataURL(file);\n                                }\n                            );\n\n                            $('input[type=file]').on('change', function (e) {\n                                file = e.target.files[0];\n                            });\n                        }\n                    };\n\n                    trumbowyg.addBtnDef('base64', btnDef);\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/cleanpaste/trumbowyg.cleanpaste.js",
    "content": "/* ===========================================================\n * trumbowyg.cleanpaste.js v1.0\n * Font Clean paste plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Authors : Eric Radin\n *           Todd Graham (slackwalker)\n *\n * This plugin will perform a \"cleaning\" on any paste, in particular\n * it will clean pasted content of microsoft word document tags and classes.\n */\n\n(function ($) {\n    'use strict';\n\n    function checkValidTags(snippet) {\n        var theString = snippet;\n\n        // Replace uppercase element names with lowercase\n        theString = theString.replace(/<[^> ]*/g, function (match) {\n            return match.toLowerCase();\n        });\n\n        // Replace uppercase attribute names with lowercase\n        theString = theString.replace(/<[^>]*>/g, function (match) {\n            match = match.replace(/ [^=]+=/g, function (match2) {\n                return match2.toLowerCase();\n            });\n            return match;\n        });\n\n        // Put quotes around unquoted attributes\n        theString = theString.replace(/<[^>]*>/g, function (match) {\n            match = match.replace(/( [^=]+=)([^\"][^ >]*)/g, '$1\\\"$2\\\"');\n            return match;\n        });\n\n        return theString;\n    }\n\n    function cleanIt(html) {\n        // first make sure all tags and attributes are made valid\n        html = checkValidTags(html);\n\n        // Replace opening bold tags with strong\n        html = html.replace(/<b(\\s+|>)/g, '<strong$1');\n        // Replace closing bold tags with closing strong\n        html = html.replace(/<\\/b(\\s+|>)/g, '</strong$1');\n\n        // Replace italic tags with em\n        html = html.replace(/<i(\\s+|>)/g, '<em$1');\n        // Replace closing italic tags with closing em\n        html = html.replace(/<\\/i(\\s+|>)/g, '</em$1');\n\n        // strip out comments -cgCraft\n        html = html.replace(/<!(?:--[\\s\\S]*?--\\s*)?>\\s*/g, '');\n\n        // strip out &nbsp; -cgCraft\n        html = html.replace(/&nbsp;/gi, ' ');\n        // strip out extra spaces -cgCraft\n        html = html.replace(/ <\\//gi, '</');\n\n        // Remove multiple spaces\n        html.replace(/\\s+/g, ' ');\n\n        // strip &nbsp; -cgCraft\n        html = html.replace(/^\\s*|\\s*$/g, '');\n\n        // Strip out unaccepted attributes\n        html = html.replace(/<[^>]*>/g, function (match) {\n            match = match.replace(/ ([^=]+)=\"[^\"]*\"/g, function (match2, attributeName) {\n                if (['alt', 'href', 'src', 'title'].indexOf(attributeName) !== -1) {\n                    return match2;\n                }\n                return '';\n            });\n            return match;\n        });\n\n        // Final clean out for MS Word crud\n        html = html.replace(/<\\?xml[^>]*>/g, '');\n        html = html.replace(/<[^ >]+:[^>]*>/g, '');\n        html = html.replace(/<\\/[^ >]+:[^>]*>/g, '');\n\n        // remove unwanted tags\n        html = html.replace(/<(div|span|style|meta|link).*?>/gi, '');\n\n        return html;\n    }\n\n    // clean editor\n    // this will clean the inserted contents\n    // it does a compare, before and after paste to determine the\n    // pasted contents\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            cleanPaste: {\n                init: function (trumbowyg) {\n                    trumbowyg.pasteHandlers.push(function (pasteEvent) {\n                        setTimeout(function () {\n                            try {\n                                trumbowyg.saveRange();\n\n                                var clipboardData = (pasteEvent.originalEvent || pasteEvent).clipboardData,\n                                pastedData = clipboardData.getData('Text'),\n                                node = trumbowyg.doc.getSelection().focusNode,\n                                range = trumbowyg.doc.createRange(),\n                                cleanedPaste = cleanIt(pastedData.trim()),\n                                newNode = $(cleanedPaste)[0] || trumbowyg.doc.createTextNode(cleanedPaste);\n\n                                if (trumbowyg.$ed.html() === '') {\n                                    // simply append if there is no content in editor\n                                    trumbowyg.$ed[0].appendChild(newNode);\n                                } else {\n                                    // insert pasted content behind last focused node\n                                    range.setStartAfter(node);\n                                    range.setEndAfter(node);\n                                    trumbowyg.doc.getSelection().removeAllRanges();\n                                    trumbowyg.doc.getSelection().addRange(range);\n\n                                    trumbowyg.range.insertNode(newNode);\n                                }\n\n                                // now set cursor right after pasted content\n                                range = trumbowyg.doc.createRange();\n                                range.setStartAfter(newNode);\n                                range.setEndAfter(newNode);\n                                trumbowyg.doc.getSelection().removeAllRanges();\n                                trumbowyg.doc.getSelection().addRange(range);\n\n                                // prevent defaults\n                                pasteEvent.stopPropagation();\n                                pasteEvent.preventDefault();\n\n                                // save new node as focused node\n                                trumbowyg.saveRange();\n                                trumbowyg.syncCode();\n                                trumbowyg.$c.trigger('tbwchange');\n                            } catch (c) {\n                            }\n                        }, 0);\n                    });\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/colors/trumbowyg.colors.js",
    "content": "/* ===========================================================\n * trumbowyg.colors.js v1.2\n * Colors picker plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Alexandre Demode (Alex-D)\n *          Twitter : @AlexandreDemode\n *          Website : alex-d.fr\n */\n\n(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                foreColor: 'Text color',\n                backColor: 'Background color',\n                foreColorRemove: 'Remove text color',\n                backColorRemove: 'Remove background color'\n            },\n            az: {\n                foreColor: 'Yazı rəngi',\n                backColor: 'Arxa plan rəngi',\n                foreColorRemove: 'Yazı rəngini sil',\n                backColorRemove: 'Arxa plan rəngini sil'\n            },\n            by: {\n                foreColor: 'Колер тэксту',\n                backColor: 'Колер фону тэксту',\n                foreColorRemove: 'Выдаліць колер тэксту',\n                backColorRemove: 'Выдаліць колер фону тэксту'\n            },\n            ca: {\n                foreColor: 'Color del text',\n                backColor: 'Color del fons',\n                foreColorRemove: 'Eliminar color del text',\n                backColorRemove: 'Eliminar color del fons'\n            },\n            cs: {\n                foreColor: 'Barva textu',\n                backColor: 'Barva pozadí'\n            },\n            da: {\n                foreColor: 'Tekstfarve',\n                backColor: 'Baggrundsfarve'\n            },\n            de: {\n                foreColor: 'Textfarbe',\n                backColor: 'Hintergrundfarbe',\n                foreColorRemove: 'Textfarbe entfernen',\n                backColorRemove: 'Hintergundfarbe entfernen'\n            },\n            es: {\n                foreColor: 'Color del texto',\n                backColor: 'Color del fondo',\n                foreColorRemove: 'Eliminar color del texto',\n                backColorRemove: 'Eliminar color del fondo'\n            },\n            et: {\n                foreColor: 'Teksti värv',\n                backColor: 'Taustavärv',\n                foreColorRemove: 'Eemalda teksti värv',\n                backColorRemove: 'Eemalda taustavärv'\n            },\n            fr: {\n                foreColor: 'Couleur du texte',\n                backColor: 'Couleur de fond',\n                foreColorRemove: 'Supprimer la couleur du texte',\n                backColorRemove: 'Supprimer la couleur de fond'\n            },\n            hu: {\n                foreColor: 'Betű szín',\n                backColor: 'Háttér szín',\n                foreColorRemove: 'Betű szín eltávolítása',\n                backColorRemove: 'Háttér szín eltávolítása'\n            },\n            ja: {\n                foreColor: '文字色',\n                backColor: '背景色'\n            },\n            ko: {\n                foreColor: '글자색',\n                backColor: '배경색',\n                foreColorRemove: '글자색 지우기',\n                backColorRemove: '배경색 지우기'\n            },\n            nl: {\n                foreColor: 'Tekstkleur',\n                backColor: 'Achtergrondkleur'\n            },\n            pt_br: {\n                foreColor: 'Cor de fonte',\n                backColor: 'Cor de fundo'\n            },\n            ru: {\n                foreColor: 'Цвет текста',\n                backColor: 'Цвет выделения текста',\n                foreColorRemove: 'Очистить цвет текста',\n                backColorRemove: 'Очистить цвет выделения текста'\n            },\n            sl: {\n                foreColor: 'Barva teksta',\n                backColor: 'Barva ozadja',\n                foreColorRemove: 'Ponastavi barvo teksta',\n                backColorRemove: 'Ponastavi barvo ozadja',\n            },\n            sk: {\n                foreColor: 'Farba textu',\n                backColor: 'Farba pozadia'\n            },\n            tr: {\n                foreColor: 'Yazı rengi',\n                backColor: 'Arka plan rengi',\n                foreColorRemove: 'Yazı rengini kaldır',\n                backColorRemove: 'Arka plan rengini kaldır'\n            },\n            zh_cn: {\n                foreColor: '文字颜色',\n                backColor: '背景颜色'\n            },\n            zh_tw: {\n                foreColor: '文字顏色',\n                backColor: '背景顏色'\n            },\n        }\n    });\n\n    // jshint camelcase:true\n\n\n    function hex(x) {\n        return ('0' + parseInt(x).toString(16)).slice(-2);\n    }\n\n    function colorToHex(rgb) {\n        if (rgb.search('rgb') === -1) {\n            return rgb.replace('#', '');\n        } else if (rgb === 'rgba(0, 0, 0, 0)') {\n            return 'transparent';\n        } else {\n            rgb = rgb.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d?(.\\d+)))?\\)$/);\n            if (rgb == null) {\n                return 'transparent'; // No match, return transparent as unkown color\n            }\n            return hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);\n        }\n    }\n\n    function colorTagHandler(element, trumbowyg) {\n        var tags = [];\n\n        if (!element.style) {\n            return tags;\n        }\n\n        // background color\n        if (element.style.backgroundColor !== '') {\n            var backColor = colorToHex(element.style.backgroundColor);\n            if (trumbowyg.o.plugins.colors.colorList.indexOf(backColor) >= 0) {\n                tags.push('backColor' + backColor);\n            } else {\n                tags.push('backColorFree');\n            }\n        }\n\n        // text color\n        var foreColor;\n        if (element.style.color !== '') {\n            foreColor = colorToHex(element.style.color);\n        } else if (element.hasAttribute('color')) {\n            foreColor = colorToHex(element.getAttribute('color'));\n        }\n        if (foreColor) {\n            if (trumbowyg.o.plugins.colors.colorList.indexOf(foreColor) >= 0) {\n                tags.push('foreColor' + foreColor);\n            } else {\n                tags.push('foreColorFree');\n            }\n        }\n\n        return tags;\n    }\n\n    var defaultOptions = {\n        colorList: [\n            'ffffff', '000000', 'eeece1', '1f497d', '4f81bd', 'c0504d', '9bbb59', '8064a2', '4bacc6', 'f79646', 'ffff00',\n            'f2f2f2', '7f7f7f', 'ddd9c3', 'c6d9f0', 'dbe5f1', 'f2dcdb', 'ebf1dd', 'e5e0ec', 'dbeef3', 'fdeada', 'fff2ca',\n            'd8d8d8', '595959', 'c4bd97', '8db3e2', 'b8cce4', 'e5b9b7', 'd7e3bc', 'ccc1d9', 'b7dde8', 'fbd5b5', 'ffe694',\n            'bfbfbf', '3f3f3f', '938953', '548dd4', '95b3d7', 'd99694', 'c3d69b', 'b2a2c7', 'b7dde8', 'fac08f', 'f2c314',\n            'a5a5a5', '262626', '494429', '17365d', '366092', '953734', '76923c', '5f497a', '92cddc', 'e36c09', 'c09100',\n            '7f7f7f', '0c0c0c', '1d1b10', '0f243e', '244061', '632423', '4f6128', '3f3151', '31859b', '974806', '7f6000'\n        ],\n        foreColorList: null, // fallbacks on colorList\n        backColorList: null, // fallbacks on colorList\n        allowCustomForeColor: true,\n        allowCustomBackColor: true,\n        displayAsList: false,\n    };\n\n    // Add all colors in two dropdowns\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            color: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.colors = trumbowyg.o.plugins.colors || defaultOptions;\n                    var dropdownClass = trumbowyg.o.plugins.colors.displayAsList ? trumbowyg.o.prefix + 'dropdown--color-list' : '';\n\n                    var foreColorBtnDef = {\n                        dropdown: buildDropdown('foreColor', trumbowyg),\n                        dropdownClass: dropdownClass,\n                    },\n                    backColorBtnDef = {\n                        dropdown: buildDropdown('backColor', trumbowyg),\n                        dropdownClass: dropdownClass,\n                    };\n\n                    trumbowyg.addBtnDef('foreColor', foreColorBtnDef);\n                    trumbowyg.addBtnDef('backColor', backColorBtnDef);\n                },\n                tagHandler: colorTagHandler\n            }\n        }\n    });\n\n    function buildDropdown(fn, trumbowyg) {\n        var dropdown = [],\n            trumbowygColorOptions = trumbowyg.o.plugins.colors,\n            colorList = trumbowygColorOptions[fn + 'List'] || trumbowygColorOptions.colorList;\n\n        $.each(colorList, function (i, color) {\n            var btn = fn + color,\n                btnDef = {\n                    fn: fn,\n                    forceCss: true,\n                    hasIcon: false,\n                    text: trumbowyg.lang['#' + color] || ('#' + color),\n                    param: '#' + color,\n                    style: 'background-color: #' + color + ';'\n                };\n\n            if (trumbowygColorOptions.displayAsList && fn === 'foreColor') {\n                btnDef.style = 'color: #' + color + ' !important;';\n            }\n\n            trumbowyg.addBtnDef(btn, btnDef);\n            dropdown.push(btn);\n        });\n\n        // Remove color\n        var removeColorButtonName = fn + 'Remove',\n            removeColorBtnDef = {\n                fn: 'removeFormat',\n                hasIcon: false,\n                param: fn,\n                style: 'background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAG0lEQVQIW2NkQAAfEJMRmwBYhoGBYQtMBYoAADziAp0jtJTgAAAAAElFTkSuQmCC);'\n            };\n\n        if (trumbowygColorOptions.displayAsList) {\n            removeColorBtnDef.style = '';\n        }\n\n        trumbowyg.addBtnDef(removeColorButtonName, removeColorBtnDef);\n        dropdown.push(removeColorButtonName);\n\n        // Custom color\n        if (trumbowygColorOptions['allowCustom' + fn.charAt(0).toUpperCase() + fn.substr(1)]) {\n            // add free color btn\n            var freeColorButtonName = fn + 'Free',\n                freeColorBtnDef = {\n                    fn: function () {\n                        trumbowyg.openModalInsert(trumbowyg.lang[fn],\n                            {\n                                color: {\n                                    label: fn,\n                                    forceCss: true,\n                                    type: 'color',\n                                    value: '#FFFFFF'\n                                }\n                            },\n                            // callback\n                            function (values) {\n                                trumbowyg.execCmd(fn, values.color);\n                                return true;\n                            }\n                        );\n                    },\n                    hasIcon: false,\n                    text: '#',\n                    // style adjust for displaying the text\n                    style: 'text-indent: 0; line-height: 20px; padding: 0 5px;'\n                };\n\n            trumbowyg.addBtnDef(freeColorButtonName, freeColorBtnDef);\n            dropdown.push(freeColorButtonName);\n        }\n\n        return dropdown;\n    }\n})(jQuery);\n"
  },
  {
    "path": "plugins/colors/ui/sass/trumbowyg.colors.scss",
    "content": ".trumbowyg-dropdown-foreColor:not(.trumbowyg-dropdown--color-list),\n.trumbowyg-dropdown-backColor:not(.trumbowyg-dropdown--color-list) {\n    max-width: 276px;\n    padding: 7px 5px;\n    overflow: initial;\n\n    button {\n        display: block;\n        position: relative;\n        float: left;\n        text-indent: -9999px;\n        height: 20px;\n        width: 20px;\n        border: 1px solid #333;\n        padding: 0;\n        margin: 2px;\n\n        &:hover,\n        &:focus {\n            &::after {\n                content: \" \";\n                display: block;\n                position: absolute;\n                top: -5px;\n                left: -5px;\n                width: 27px;\n                height: 27px;\n                background: inherit;\n                border: 1px solid #fff;\n                box-shadow: #000 0 0 2px;\n                z-index: 10;\n            }\n        }\n    }\n}\n\n.trumbowyg-dropdown-backColor.trumbowyg-dropdown--color-list {\n    button:not(.trumbowyg-backColorRemove-dropdown-button) {\n        position: relative;\n        color: #fff !important;\n\n        &:hover,\n        &:focus {\n            &::after {\n                content: \" \";\n                display: block;\n                position: absolute;\n                top: 13px;\n                left: 0;\n                width: 0;\n                height: 0;\n                border: 5px solid transparent;\n                border-left-color: #fff;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/emoji/trumbowyg.emoji.js",
    "content": "/* ===========================================================\n * trumbowyg.emoji.js v0.1\n * Emoji picker plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Nicolas Pion\n *          Twitter : @nicolas_pion\n */\n\n(function ($) {\n    'use strict';\n\n    var defaultOptions = {\n        emojiList: [\n            '&#x2049',\n            '&#x2122',\n            '&#x2139',\n            '&#x2194',\n            '&#x2195',\n            '&#x2196',\n            '&#x2197',\n            '&#x2198',\n            '&#x2199',\n            '&#x2328',\n            '&#x2600',\n            '&#x2601',\n            '&#x2602',\n            '&#x2603',\n            '&#x2604',\n            '&#x2611',\n            '&#x2614',\n            '&#x2615',\n            '&#x2618',\n            '&#x2620',\n            '&#x2622',\n            '&#x2623',\n            '&#x2626',\n            '&#x2638',\n            '&#x2639',\n            '&#x2640',\n            '&#x2642',\n            '&#x2648',\n            '&#x2649',\n            '&#x2650',\n            '&#x2651',\n            '&#x2652',\n            '&#x2653',\n            '&#x2660',\n            '&#x2663',\n            '&#x2665',\n            '&#x2666',\n            '&#x2668',\n            '&#x2692',\n            '&#x2693',\n            '&#x2694',\n            '&#x2695',\n            '&#x2696',\n            '&#x2697',\n            '&#x2699',\n            '&#x2702',\n            '&#x2705',\n            '&#x2708',\n            '&#x2709',\n            '&#x2712',\n            '&#x2714',\n            '&#x2716',\n            '&#x2721',\n            '&#x2728',\n            '&#x2733',\n            '&#x2734',\n            '&#x2744',\n            '&#x2747',\n            '&#x2753',\n            '&#x2754',\n            '&#x2755',\n            '&#x2757',\n            '&#x2763',\n            '&#x2764',\n            '&#x2795',\n            '&#x2796',\n            '&#x2797',\n            '&#x2934',\n            '&#x2935',\n            '&#x3030',\n            '&#x3297',\n            '&#x3299',\n            '&#x1F600',\n            '&#x1F603',\n            '&#x1F604',\n            '&#x1F601',\n            '&#x1F606',\n            '&#x1F605',\n            '&#x1F602',\n            '&#x1F923',\n            '&#x263A',\n            '&#x1F60A',\n            '&#x1F607',\n            '&#x1F642',\n            '&#x1F643',\n            '&#x1F609',\n            '&#x1F60C',\n            '&#x1F972',\n            '&#x1F60D',\n            '&#x1F970',\n            '&#x1F618',\n            '&#x1F617',\n            '&#x1F619',\n            '&#x1F61A',\n            '&#x1F60B',\n            '&#x1F61B',\n            '&#x1F61D',\n            '&#x1F61C',\n            '&#x1F92A',\n            '&#x1F928',\n            '&#x1F9D0',\n            '&#x1F913',\n            '&#x1F60E',\n            '&#x1F929',\n            '&#x1F973',\n            '&#x1F60F',\n            '&#x1F612',\n            '&#x1F61E',\n            '&#x1F614',\n            '&#x1F61F',\n            '&#x1F615',\n            '&#x1F641',\n            '&#x1F623',\n            '&#x1F616',\n            '&#x1F62B',\n            '&#x1F629',\n            '&#x1F97A',\n            '&#x1F622',\n            '&#x1F62D',\n            '&#x1F624',\n            '&#x1F62E',\n            '&#x1F620',\n            '&#x1F621',\n            '&#x1F92C',\n            '&#x1F92F',\n            '&#x1F633',\n            '&#x1F636',\n            '&#x1F975',\n            '&#x1F976',\n            '&#x1F631',\n            '&#x1F628',\n            '&#x1F630',\n            '&#x1F625',\n            '&#x1F613',\n            '&#x1F917',\n            '&#x1F914',\n            '&#x1F92D',\n            '&#x1F971',\n            '&#x1F92B',\n            '&#x1F925',\n            '&#x1F610',\n            '&#x1F611',\n            '&#x1F62C',\n            '&#x1F644',\n            '&#x1F62F',\n            '&#x1F626',\n            '&#x1F627',\n            '&#x1F632',\n            '&#x1F634',\n            '&#x1F924',\n            '&#x1F62A',\n            '&#x1F635',\n            '&#x1F910',\n            '&#x1F974',\n            '&#x1F922',\n            '&#x1F92E',\n            '&#x1F927',\n            '&#x1F637',\n            '&#x1F912',\n            '&#x1F915',\n            '&#x1F911',\n            '&#x1F920',\n            '&#x1F978',\n            '&#x1F608',\n            '&#x1F47F',\n            '&#x1F479',\n            '&#x1F47A',\n            '&#x1F921',\n            '&#x1F4A9',\n            '&#x1F47B',\n            '&#x1F480',\n            '&#x1F47D',\n            '&#x1F47E',\n            '&#x1F916',\n            '&#x1F383',\n            '&#x1F63A',\n            '&#x1F638',\n            '&#x1F639',\n            '&#x1F63B',\n            '&#x1F63C',\n            '&#x1F63D',\n            '&#x1F640',\n            '&#x1F63F',\n            '&#x1F63E',\n            '&#x1F932',\n            '&#x1F450',\n            '&#x1F64C',\n            '&#x1F44F',\n            '&#x1F91D',\n            '&#x1F44D',\n            '&#x1F44E',\n            '&#x1F44A',\n            '&#x270A',\n            '&#x1F91B',\n            '&#x1F91C',\n            '&#x1F91E',\n            '&#x270C',\n            '&#x1F91F',\n            '&#x1F918',\n            '&#x1F44C',\n            '&#x1F90F',\n            '&#x1F90C',\n            '&#x1F448',\n            '&#x1F449',\n            '&#x1F446',\n            '&#x1F447',\n            '&#x261D',\n            '&#x270B',\n            '&#x1F91A',\n            '&#x1F590',\n            '&#x1F596',\n            '&#x1F44B',\n            '&#x1F919',\n            '&#x1F4AA',\n            '&#x1F9BE',\n            '&#x1F595',\n            '&#x270D',\n            '&#x1F64F',\n            '&#x1F9B6',\n            '&#x1F9B5',\n            '&#x1F9BF',\n            '&#x1F484',\n            '&#x1F48B',\n            '&#x1F444',\n            '&#x1F9B7',\n            '&#x1F445',\n            '&#x1F442',\n            '&#x1F9BB',\n            '&#x1F443',\n            '&#x1F463',\n            '&#x1F441',\n            '&#x1F440',\n            '&#x1F9E0',\n            '&#x1FAC0',\n            '&#x1FAC1',\n            '&#x1F9B4',\n            '&#x1F5E3',\n            '&#x1F464',\n            '&#x1F465',\n            '&#x1FAC2',\n            '&#x1F476',\n            '&#x1F467',\n            '&#x1F9D2',\n            '&#x1F466',\n            '&#x1F469',\n            '&#x1F9D1',\n            '&#x1F468',\n            '&#x1F471',\n            '&#x1F9D4',\n            '&#x1F475',\n            '&#x1F9D3',\n            '&#x1F474',\n            '&#x1F472',\n            '&#x1F473',\n            '&#x1F9D5',\n            '&#x1F46E',\n            '&#x1F477',\n            '&#x1F482',\n            '&#x1F575',\n            '&#x1F470',\n            '&#x1F935',\n            '&#x1F478',\n            '&#x1F934',\n            '&#x1F9B8',\n            '&#x1F9B9',\n            '&#x1F977',\n            '&#x1F936',\n            '&#x1F385',\n            '&#x1F9D9',\n            '&#x1F9DD',\n            '&#x1F9DB',\n            '&#x1F9DF',\n            '&#x1F9DE',\n            '&#x1F9DC',\n            '&#x1F9DA',\n            '&#x1F47C',\n            '&#x1F930',\n            '&#x1F931',\n            '&#x1F647',\n            '&#x1F481',\n            '&#x1F645',\n            '&#x1F646',\n            '&#x1F64B',\n            '&#x1F9CF',\n            '&#x1F926',\n            '&#x1F937',\n            '&#x1F64E',\n            '&#x1F64D',\n            '&#x1F487',\n            '&#x1F486',\n            '&#x1F9D6',\n            '&#x1F485',\n            '&#x1F933',\n            '&#x1F483',\n            '&#x1F57A',\n            '&#x1F46F',\n            '&#x1F574',\n            '&#x1F6B6',\n            '&#x1F9CE',\n            '&#x1F3C3',\n            '&#x1F9CD',\n            '&#x1F46B',\n            '&#x1F46D',\n            '&#x1F46C',\n            '&#x1F491',\n            '&#x1F48F',\n            '&#x1F46A',\n            '&#x1F9F6',\n            '&#x1F9F5',\n            '&#x1F9E5',\n            '&#x1F97C',\n            '&#x1F9BA',\n            '&#x1F45A',\n            '&#x1F455',\n            '&#x1F456',\n            '&#x1FA72',\n            '&#x1FA73',\n            '&#x1F454',\n            '&#x1F457',\n            '&#x1F459',\n            '&#x1FA71',\n            '&#x1F458',\n            '&#x1F97B',\n            '&#x1F97F',\n            '&#x1F460',\n            '&#x1F461',\n            '&#x1F462',\n            '&#x1F45E',\n            '&#x1F45F',\n            '&#x1F97E',\n            '&#x1FA74',\n            '&#x1F9E6',\n            '&#x1F9E4',\n            '&#x1F9E3',\n            '&#x1F3A9',\n            '&#x1F9E2',\n            '&#x1F452',\n            '&#x1F393',\n            '&#x26D1',\n            '&#x1FA96',\n            '&#x1F451',\n            '&#x1F48D',\n            '&#x1F45D',\n            '&#x1F45B',\n            '&#x1F45C',\n            '&#x1F4BC',\n            '&#x1F392',\n            '&#x1F9F3',\n            '&#x1F453',\n            '&#x1F576',\n            '&#x1F97D',\n            '&#x1F302',\n            '&#x1F9B1',\n            '&#x1F9B0',\n            '&#x1F9B3',\n            '&#x1F9B2',\n            '&#x1F436',\n            '&#x1F431',\n            '&#x1F42D',\n            '&#x1F439',\n            '&#x1F430',\n            '&#x1F98A',\n            '&#x1F43B',\n            '&#x1F43C',\n            '&#x1F428',\n            '&#x1F42F',\n            '&#x1F981',\n            '&#x1F42E',\n            '&#x1F437',\n            '&#x1F43D',\n            '&#x1F438',\n            '&#x1F435',\n            '&#x1F648',\n            '&#x1F649',\n            '&#x1F64A',\n            '&#x1F412',\n            '&#x1F414',\n            '&#x1F427',\n            '&#x1F426',\n            '&#x1F424',\n            '&#x1F423',\n            '&#x1F425',\n            '&#x1F986',\n            '&#x1F9A4',\n            '&#x1F985',\n            '&#x1F989',\n            '&#x1F987',\n            '&#x1F43A',\n            '&#x1F417',\n            '&#x1F434',\n            '&#x1F984',\n            '&#x1F41D',\n            '&#x1F41B',\n            '&#x1F98B',\n            '&#x1F40C',\n            '&#x1FAB1',\n            '&#x1F41E',\n            '&#x1F41C',\n            '&#x1FAB0',\n            '&#x1F99F',\n            '&#x1FAB3',\n            '&#x1FAB2',\n            '&#x1F997',\n            '&#x1F577',\n            '&#x1F578',\n            '&#x1F982',\n            '&#x1F422',\n            '&#x1F40D',\n            '&#x1F98E',\n            '&#x1F996',\n            '&#x1F995',\n            '&#x1F419',\n            '&#x1F991',\n            '&#x1F990',\n            '&#x1F99E',\n            '&#x1F980',\n            '&#x1F421',\n            '&#x1F420',\n            '&#x1F41F',\n            '&#x1F9AD',\n            '&#x1F42C',\n            '&#x1F433',\n            '&#x1F40B',\n            '&#x1F988',\n            '&#x1F40A',\n            '&#x1F405',\n            '&#x1F406',\n            '&#x1F993',\n            '&#x1F98D',\n            '&#x1F9A7',\n            '&#x1F418',\n            '&#x1F9A3',\n            '&#x1F9AC',\n            '&#x1F99B',\n            '&#x1F98F',\n            '&#x1F42A',\n            '&#x1F42B',\n            '&#x1F992',\n            '&#x1F998',\n            '&#x1F403',\n            '&#x1F402',\n            '&#x1F404',\n            '&#x1F40E',\n            '&#x1F416',\n            '&#x1F40F',\n            '&#x1F411',\n            '&#x1F999',\n            '&#x1F410',\n            '&#x1F98C',\n            '&#x1F415',\n            '&#x1F429',\n            '&#x1F9AE',\n            '&#x1F408',\n            '&#x1F413',\n            '&#x1F983',\n            '&#x1F99A',\n            '&#x1F99C',\n            '&#x1F9A2',\n            '&#x1F9A9',\n            '&#x1F54A',\n            '&#x1F407',\n            '&#x1F99D',\n            '&#x1F9A8',\n            '&#x1F9A1',\n            '&#x1F9AB',\n            '&#x1F9A6',\n            '&#x1F9A5',\n            '&#x1F401',\n            '&#x1F400',\n            '&#x1F43F',\n            '&#x1F994',\n            '&#x1F43E',\n            '&#x1F409',\n            '&#x1F432',\n            '&#x1F335',\n            '&#x1F384',\n            '&#x1F332',\n            '&#x1F333',\n            '&#x1F334',\n            '&#x1F331',\n            '&#x1F33F',\n            '&#x1F340',\n            '&#x1F38D',\n            '&#x1F38B',\n            '&#x1F343',\n            '&#x1F342',\n            '&#x1F341',\n            '&#x1FAB6',\n            '&#x1F344',\n            '&#x1F41A',\n            '&#x1FAA8',\n            '&#x1FAB5',\n            '&#x1F33E',\n            '&#x1FAB4',\n            '&#x1F490',\n            '&#x1F337',\n            '&#x1F339',\n            '&#x1F940',\n            '&#x1F33A',\n            '&#x1F338',\n            '&#x1F33C',\n            '&#x1F33B',\n            '&#x1F31E',\n            '&#x1F31D',\n            '&#x1F31B',\n            '&#x1F31C',\n            '&#x1F31A',\n            '&#x1F315',\n            '&#x1F316',\n            '&#x1F317',\n            '&#x1F318',\n            '&#x1F311',\n            '&#x1F312',\n            '&#x1F313',\n            '&#x1F314',\n            '&#x1F319',\n            '&#x1F30E',\n            '&#x1F30D',\n            '&#x1F30F',\n            '&#x1FA90',\n            '&#x1F4AB',\n            '&#x2B50',\n            '&#x1F31F',\n            '&#x26A1',\n            '&#x1F4A5',\n            '&#x1F525',\n            '&#x1F32A',\n            '&#x1F308',\n            '&#x1F324',\n            '&#x26C5',\n            '&#x1F325',\n            '&#x1F326',\n            '&#x1F327',\n            '&#x26C8',\n            '&#x1F329',\n            '&#x1F328',\n            '&#x26C4',\n            '&#x1F32C',\n            '&#x1F4A8',\n            '&#x1F4A7',\n            '&#x1F4A6',\n            '&#x1F30A',\n            '&#x1F32B',\n            '&#x1F34F',\n            '&#x1F34E',\n            '&#x1F350',\n            '&#x1F34A',\n            '&#x1F34B',\n            '&#x1F34C',\n            '&#x1F349',\n            '&#x1F347',\n            '&#x1FAD0',\n            '&#x1F353',\n            '&#x1F348',\n            '&#x1F352',\n            '&#x1F351',\n            '&#x1F96D',\n            '&#x1F34D',\n            '&#x1F965',\n            '&#x1F95D',\n            '&#x1F345',\n            '&#x1F346',\n            '&#x1F951',\n            '&#x1FAD2',\n            '&#x1F966',\n            '&#x1F96C',\n            '&#x1FAD1',\n            '&#x1F952',\n            '&#x1F336',\n            '&#x1F33D',\n            '&#x1F955',\n            '&#x1F9C4',\n            '&#x1F9C5',\n            '&#x1F954',\n            '&#x1F360',\n            '&#x1F950',\n            '&#x1F96F',\n            '&#x1F35E',\n            '&#x1F956',\n            '&#x1FAD3',\n            '&#x1F968',\n            '&#x1F9C0',\n            '&#x1F95A',\n            '&#x1F373',\n            '&#x1F9C8',\n            '&#x1F95E',\n            '&#x1F9C7',\n            '&#x1F953',\n            '&#x1F969',\n            '&#x1F357',\n            '&#x1F356',\n            '&#x1F32D',\n            '&#x1F354',\n            '&#x1F35F',\n            '&#x1F355',\n            '&#x1F96A',\n            '&#x1F959',\n            '&#x1F9C6',\n            '&#x1F32E',\n            '&#x1F32F',\n            '&#x1FAD4',\n            '&#x1F957',\n            '&#x1F958',\n            '&#x1FAD5',\n            '&#x1F96B',\n            '&#x1F35D',\n            '&#x1F35C',\n            '&#x1F372',\n            '&#x1F35B',\n            '&#x1F363',\n            '&#x1F371',\n            '&#x1F95F',\n            '&#x1F9AA',\n            '&#x1F364',\n            '&#x1F359',\n            '&#x1F35A',\n            '&#x1F358',\n            '&#x1F365',\n            '&#x1F960',\n            '&#x1F96E',\n            '&#x1F362',\n            '&#x1F361',\n            '&#x1F367',\n            '&#x1F368',\n            '&#x1F366',\n            '&#x1F967',\n            '&#x1F9C1',\n            '&#x1F370',\n            '&#x1F382',\n            '&#x1F36E',\n            '&#x1F36D',\n            '&#x1F36C',\n            '&#x1F36B',\n            '&#x1F37F',\n            '&#x1F369',\n            '&#x1F36A',\n            '&#x1F330',\n            '&#x1F95C',\n            '&#x1F36F',\n            '&#x1F95B',\n            '&#x1F37C',\n            '&#x1F375',\n            '&#x1FAD6',\n            '&#x1F9C9',\n            '&#x1F9CB',\n            '&#x1F9C3',\n            '&#x1F964',\n            '&#x1F376',\n            '&#x1F37A',\n            '&#x1F37B',\n            '&#x1F942',\n            '&#x1F377',\n            '&#x1F943',\n            '&#x1F378',\n            '&#x1F379',\n            '&#x1F37E',\n            '&#x1F9CA',\n            '&#x1F944',\n            '&#x1F374',\n            '&#x1F37D',\n            '&#x1F963',\n            '&#x1F961',\n            '&#x1F962',\n            '&#x1F9C2',\n            '&#x26BD',\n            '&#x1F3C0',\n            '&#x1F3C8',\n            '&#x26BE',\n            '&#x1F94E',\n            '&#x1F3BE',\n            '&#x1F3D0',\n            '&#x1F3C9',\n            '&#x1F94F',\n            '&#x1FA83',\n            '&#x1F3B1',\n            '&#x1FA80',\n            '&#x1F3D3',\n            '&#x1F3F8',\n            '&#x1F3D2',\n            '&#x1F3D1',\n            '&#x1F94D',\n            '&#x1F3CF',\n            '&#x1F945',\n            '&#x26F3',\n            '&#x1FA81',\n            '&#x1F3F9',\n            '&#x1F3A3',\n            '&#x1F93F',\n            '&#x1F94A',\n            '&#x1F94B',\n            '&#x1F3BD',\n            '&#x1F6F9',\n            '&#x1F6FC',\n            '&#x1F6F7',\n            '&#x26F8',\n            '&#x1F94C',\n            '&#x1F3BF',\n            '&#x26F7',\n            '&#x1F3C2',\n            '&#x1FA82',\n            '&#x1F3CB',\n            '&#x1F93C',\n            '&#x1F938',\n            '&#x26F9',\n            '&#x1F93A',\n            '&#x1F93E',\n            '&#x1F3CC',\n            '&#x1F3C7',\n            '&#x1F9D8',\n            '&#x1F3C4',\n            '&#x1F3CA',\n            '&#x1F93D',\n            '&#x1F6A3',\n            '&#x1F9D7',\n            '&#x1F6B5',\n            '&#x1F6B4',\n            '&#x1F3C6',\n            '&#x1F947',\n            '&#x1F948',\n            '&#x1F949',\n            '&#x1F3C5',\n            '&#x1F396',\n            '&#x1F3F5',\n            '&#x1F397',\n            '&#x1F3AB',\n            '&#x1F39F',\n            '&#x1F3AA',\n            '&#x1F939',\n            '&#x1F3AD',\n            '&#x1FA70',\n            '&#x1F3A8',\n            '&#x1F3AC',\n            '&#x1F3A4',\n            '&#x1F3A7',\n            '&#x1F3BC',\n            '&#x1F3B9',\n            '&#x1F941',\n            '&#x1FA98',\n            '&#x1F3B7',\n            '&#x1F3BA',\n            '&#x1F3B8',\n            '&#x1FA95',\n            '&#x1F3BB',\n            '&#x1FA97',\n            '&#x1F3B2',\n            '&#x265F',\n            '&#x1F3AF',\n            '&#x1F3B3',\n            '&#x1F3AE',\n            '&#x1F3B0',\n            '&#x1F9E9',\n            '&#x1F697',\n            '&#x1F695',\n            '&#x1F699',\n            '&#x1F6FB',\n            '&#x1F68C',\n            '&#x1F68E',\n            '&#x1F3CE',\n            '&#x1F693',\n            '&#x1F691',\n            '&#x1F692',\n            '&#x1F690',\n            '&#x1F69A',\n            '&#x1F69B',\n            '&#x1F69C',\n            '&#x1F9AF',\n            '&#x1F9BD',\n            '&#x1F9BC',\n            '&#x1F6F4',\n            '&#x1F6B2',\n            '&#x1F6F5',\n            '&#x1F3CD',\n            '&#x1F6FA',\n            '&#x1F6A8',\n            '&#x1F694',\n            '&#x1F68D',\n            '&#x1F698',\n            '&#x1F696',\n            '&#x1F6A1',\n            '&#x1F6A0',\n            '&#x1F69F',\n            '&#x1F683',\n            '&#x1F68B',\n            '&#x1F69E',\n            '&#x1F69D',\n            '&#x1F684',\n            '&#x1F685',\n            '&#x1F688',\n            '&#x1F682',\n            '&#x1F686',\n            '&#x1F687',\n            '&#x1F68A',\n            '&#x1F689',\n            '&#x1F6EB',\n            '&#x1F6EC',\n            '&#x1F6E9',\n            '&#x1F4BA',\n            '&#x1F6F0',\n            '&#x1F680',\n            '&#x1F6F8',\n            '&#x1F681',\n            '&#x1F6F6',\n            '&#x26F5',\n            '&#x1F6A4',\n            '&#x1F6E5',\n            '&#x1F6F3',\n            '&#x26F4',\n            '&#x1F6A2',\n            '&#x26FD',\n            '&#x1F6A7',\n            '&#x1F6A6',\n            '&#x1F6A5',\n            '&#x1F68F',\n            '&#x1F5FA',\n            '&#x1F5FF',\n            '&#x1F5FD',\n            '&#x1F5FC',\n            '&#x1F3F0',\n            '&#x1F3EF',\n            '&#x1F3DF',\n            '&#x1F3A1',\n            '&#x1F3A2',\n            '&#x1F3A0',\n            '&#x26F2',\n            '&#x26F1',\n            '&#x1F3D6',\n            '&#x1F3DD',\n            '&#x1F3DC',\n            '&#x1F30B',\n            '&#x26F0',\n            '&#x1F3D4',\n            '&#x1F5FB',\n            '&#x1F3D5',\n            '&#x26FA',\n            '&#x1F3E0',\n            '&#x1F3E1',\n            '&#x1F3D8',\n            '&#x1F3DA',\n            '&#x1F6D6',\n            '&#x1F3D7',\n            '&#x1F3ED',\n            '&#x1F3E2',\n            '&#x1F3EC',\n            '&#x1F3E3',\n            '&#x1F3E4',\n            '&#x1F3E5',\n            '&#x1F3E6',\n            '&#x1F3E8',\n            '&#x1F3EA',\n            '&#x1F3EB',\n            '&#x1F3E9',\n            '&#x1F492',\n            '&#x1F3DB',\n            '&#x26EA',\n            '&#x1F54C',\n            '&#x1F54D',\n            '&#x1F6D5',\n            '&#x1F54B',\n            '&#x26E9',\n            '&#x1F6E4',\n            '&#x1F6E3',\n            '&#x1F5FE',\n            '&#x1F391',\n            '&#x1F3DE',\n            '&#x1F305',\n            '&#x1F304',\n            '&#x1F320',\n            '&#x1F387',\n            '&#x1F386',\n            '&#x1F307',\n            '&#x1F306',\n            '&#x1F3D9',\n            '&#x1F303',\n            '&#x1F30C',\n            '&#x1F309',\n            '&#x1F301',\n            '&#x231A',\n            '&#x1F4F1',\n            '&#x1F4F2',\n            '&#x1F4BB',\n            '&#x1F5A5',\n            '&#x1F5A8',\n            '&#x1F5B1',\n            '&#x1F5B2',\n            '&#x1F579',\n            '&#x1F5DC',\n            '&#x1F4BD',\n            '&#x1F4BE',\n            '&#x1F4BF',\n            '&#x1F4C0',\n            '&#x1F4FC',\n            '&#x1F4F7',\n            '&#x1F4F8',\n            '&#x1F4F9',\n            '&#x1F3A5',\n            '&#x1F4FD',\n            '&#x1F39E',\n            '&#x1F4DE',\n            '&#x260E',\n            '&#x1F4DF',\n            '&#x1F4E0',\n            '&#x1F4FA',\n            '&#x1F4FB',\n            '&#x1F399',\n            '&#x1F39A',\n            '&#x1F39B',\n            '&#x1F9ED',\n            '&#x23F1',\n            '&#x23F2',\n            '&#x23F0',\n            '&#x1F570',\n            '&#x231B',\n            '&#x23F3',\n            '&#x1F4E1',\n            '&#x1F50B',\n            '&#x1F50C',\n            '&#x1F4A1',\n            '&#x1F526',\n            '&#x1F56F',\n            '&#x1FA94',\n            '&#x1F9EF',\n            '&#x1F6E2',\n            '&#x1F4B8',\n            '&#x1F4B5',\n            '&#x1F4B4',\n            '&#x1F4B6',\n            '&#x1F4B7',\n            '&#x1FA99',\n            '&#x1F4B0',\n            '&#x1F4B3',\n            '&#x1F48E',\n            '&#x1FA9C',\n            '&#x1F9F0',\n            '&#x1FA9B',\n            '&#x1F527',\n            '&#x1F528',\n            '&#x1F6E0',\n            '&#x26CF',\n            '&#x1F529',\n            '&#x1F9F1',\n            '&#x26D3',\n            '&#x1FA9D',\n            '&#x1FAA2',\n            '&#x1F9F2',\n            '&#x1F52B',\n            '&#x1F4A3',\n            '&#x1F9E8',\n            '&#x1FA93',\n            '&#x1FA9A',\n            '&#x1F52A',\n            '&#x1F5E1',\n            '&#x1F6E1',\n            '&#x1F6AC',\n            '&#x26B0',\n            '&#x1FAA6',\n            '&#x26B1',\n            '&#x1F3FA',\n            '&#x1FA84',\n            '&#x1F52E',\n            '&#x1F4FF',\n            '&#x1F9FF',\n            '&#x1F488',\n            '&#x1F52D',\n            '&#x1F52C',\n            '&#x1F573',\n            '&#x1FA9F',\n            '&#x1FA79',\n            '&#x1FA7A',\n            '&#x1F48A',\n            '&#x1F489',\n            '&#x1FA78',\n            '&#x1F9EC',\n            '&#x1F9A0',\n            '&#x1F9EB',\n            '&#x1F9EA',\n            '&#x1F321',\n            '&#x1FAA4',\n            '&#x1F9F9',\n            '&#x1F9FA',\n            '&#x1FAA1',\n            '&#x1F9FB',\n            '&#x1F6BD',\n            '&#x1FAA0',\n            '&#x1FAA3',\n            '&#x1F6B0',\n            '&#x1F6BF',\n            '&#x1F6C1',\n            '&#x1F6C0',\n            '&#x1FAA5',\n            '&#x1F9FC',\n            '&#x1FA92',\n            '&#x1F9FD',\n            '&#x1F9F4',\n            '&#x1F6CE',\n            '&#x1F511',\n            '&#x1F5DD',\n            '&#x1F6AA',\n            '&#x1FA91',\n            '&#x1FA9E',\n            '&#x1F6CB',\n            '&#x1F6CF',\n            '&#x1F6CC',\n            '&#x1F9F8',\n            '&#x1F5BC',\n            '&#x1F6CD',\n            '&#x1F6D2',\n            '&#x1F381',\n            '&#x1F388',\n            '&#x1F38F',\n            '&#x1F380',\n            '&#x1F38A',\n            '&#x1F389',\n            '&#x1FA85',\n            '&#x1FA86',\n            '&#x1F38E',\n            '&#x1F3EE',\n            '&#x1F390',\n            '&#x1F9E7',\n            '&#x1F4E9',\n            '&#x1F4E8',\n            '&#x1F4E7',\n            '&#x1F48C',\n            '&#x1F4E5',\n            '&#x1F4E4',\n            '&#x1F4E6',\n            '&#x1F3F7',\n            '&#x1F4EA',\n            '&#x1F4EB',\n            '&#x1F4EC',\n            '&#x1F4ED',\n            '&#x1F4EE',\n            '&#x1F4EF',\n            '&#x1FAA7',\n            '&#x1F4DC',\n            '&#x1F4C3',\n            '&#x1F4C4',\n            '&#x1F4D1',\n            '&#x1F9FE',\n            '&#x1F4CA',\n            '&#x1F4C8',\n            '&#x1F4C9',\n            '&#x1F5D2',\n            '&#x1F5D3',\n            '&#x1F4C6',\n            '&#x1F4C5',\n            '&#x1F5D1',\n            '&#x1F4C7',\n            '&#x1F5C3',\n            '&#x1F5F3',\n            '&#x1F5C4',\n            '&#x1F4CB',\n            '&#x1F4C1',\n            '&#x1F4C2',\n            '&#x1F5C2',\n            '&#x1F5DE',\n            '&#x1F4F0',\n            '&#x1F4D3',\n            '&#x1F4D4',\n            '&#x1F4D2',\n            '&#x1F4D5',\n            '&#x1F4D7',\n            '&#x1F4D8',\n            '&#x1F4D9',\n            '&#x1F4DA',\n            '&#x1F4D6',\n            '&#x1F516',\n            '&#x1F9F7',\n            '&#x1F517',\n            '&#x1F4CE',\n            '&#x1F587',\n            '&#x1F4D0',\n            '&#x1F4CF',\n            '&#x1F9EE',\n            '&#x1F4CC',\n            '&#x1F4CD',\n            '&#x1F58A',\n            '&#x1F58B',\n            '&#x1F58C',\n            '&#x1F58D',\n            '&#x1F4DD',\n            '&#x270F',\n            '&#x1F50D',\n            '&#x1F50E',\n            '&#x1F50F',\n            '&#x1F510',\n            '&#x1F512',\n            '&#x1F513',\n            '&#x1F9E1',\n            '&#x1F49B',\n            '&#x1F49A',\n            '&#x1F499',\n            '&#x1F49C',\n            '&#x1F5A4',\n            '&#x1F90E',\n            '&#x1F90D',\n            '&#x1F494',\n            '&#x1F495',\n            '&#x1F49E',\n            '&#x1F493',\n            '&#x1F497',\n            '&#x1F496',\n            '&#x1F498',\n            '&#x1F49D',\n            '&#x1F49F',\n            '&#x262E',\n            '&#x271D',\n            '&#x262A',\n            '&#x1F549',\n            '&#x1F52F',\n            '&#x1F54E',\n            '&#x262F',\n            '&#x1F6D0',\n            '&#x26CE',\n            '&#x264A',\n            '&#x264B',\n            '&#x264C',\n            '&#x264D',\n            '&#x264E',\n            '&#x264F',\n            '&#x1F194',\n            '&#x269B',\n            '&#x1F251',\n            '&#x1F4F4',\n            '&#x1F4F3',\n            '&#x1F236',\n            '&#x1F21A',\n            '&#x1F238',\n            '&#x1F23A',\n            '&#x1F237',\n            '&#x1F19A',\n            '&#x1F4AE',\n            '&#x1F250',\n            '&#x1F234',\n            '&#x1F235',\n            '&#x1F239',\n            '&#x1F232',\n            '&#x1F170',\n            '&#x1F171',\n            '&#x1F18E',\n            '&#x1F191',\n            '&#x1F17E',\n            '&#x1F198',\n            '&#x274C',\n            '&#x2B55',\n            '&#x1F6D1',\n            '&#x26D4',\n            '&#x1F4DB',\n            '&#x1F6AB',\n            '&#x1F4AF',\n            '&#x1F4A2',\n            '&#x1F6B7',\n            '&#x1F6AF',\n            '&#x1F6B3',\n            '&#x1F6B1',\n            '&#x1F51E',\n            '&#x1F4F5',\n            '&#x1F6AD',\n            '&#x203C',\n            '&#x1F505',\n            '&#x1F506',\n            '&#x303D',\n            '&#x26A0',\n            '&#x1F6B8',\n            '&#x1F531',\n            '&#x269C',\n            '&#x1F530',\n            '&#x267B',\n            '&#x1F22F',\n            '&#x1F4B9',\n            '&#x274E',\n            '&#x1F310',\n            '&#x1F4A0',\n            '&#x24C2',\n            '&#x1F300',\n            '&#x1F4A4',\n            '&#x1F3E7',\n            '&#x1F6BE',\n            '&#x267F',\n            '&#x1F17F',\n            '&#x1F233',\n            '&#x1F202',\n            '&#x1F6C2',\n            '&#x1F6C3',\n            '&#x1F6C4',\n            '&#x1F6C5',\n            '&#x1F6D7',\n            '&#x1F6B9',\n            '&#x1F6BA',\n            '&#x1F6BC',\n            '&#x1F6BB',\n            '&#x1F6AE',\n            '&#x1F3A6',\n            '&#x1F4F6',\n            '&#x1F201',\n            '&#x1F523',\n            '&#x1F524',\n            '&#x1F521',\n            '&#x1F520',\n            '&#x1F196',\n            '&#x1F197',\n            '&#x1F199',\n            '&#x1F192',\n            '&#x1F195',\n            '&#x1F193',\n            '&#x0030',\n            '&#x0031',\n            '&#x0032',\n            '&#x0033',\n            '&#x0034',\n            '&#x0035',\n            '&#x0036',\n            '&#x0037',\n            '&#x0038',\n            '&#x0039',\n            '&#x1F51F',\n            '&#x1F522',\n            '&#x0023',\n            '&#x002A',\n            '&#x23CF',\n            '&#x25B6',\n            '&#x23F8',\n            '&#x23EF',\n            '&#x23F9',\n            '&#x23FA',\n            '&#x23ED',\n            '&#x23EE',\n            '&#x23E9',\n            '&#x23EA',\n            '&#x23EB',\n            '&#x23EC',\n            '&#x25C0',\n            '&#x1F53C',\n            '&#x1F53D',\n            '&#x27A1',\n            '&#x2B05',\n            '&#x2B06',\n            '&#x2B07',\n            '&#x21AA',\n            '&#x21A9',\n            '&#x1F500',\n            '&#x1F501',\n            '&#x1F502',\n            '&#x1F504',\n            '&#x1F503',\n            '&#x1F3B5',\n            '&#x1F3B6',\n            '&#x267E',\n            '&#x1F4B2',\n            '&#x1F4B1',\n            '&#x00A9',\n            '&#x00AE',\n            '&#x27B0',\n            '&#x27BF',\n            '&#x1F51A',\n            '&#x1F519',\n            '&#x1F51B',\n            '&#x1F51D',\n            '&#x1F51C',\n            '&#x1F518',\n            '&#x26AA',\n            '&#x26AB',\n            '&#x1F534',\n            '&#x1F535',\n            '&#x1F7E4',\n            '&#x1F7E3',\n            '&#x1F7E2',\n            '&#x1F7E1',\n            '&#x1F7E0',\n            '&#x1F53A',\n            '&#x1F53B',\n            '&#x1F538',\n            '&#x1F539',\n            '&#x1F536',\n            '&#x1F537',\n            '&#x1F533',\n            '&#x1F532',\n            '&#x25AA',\n            '&#x25AB',\n            '&#x25FE',\n            '&#x25FD',\n            '&#x25FC',\n            '&#x25FB',\n            '&#x2B1B',\n            '&#x2B1C',\n            '&#x1F7E7',\n            '&#x1F7E6',\n            '&#x1F7E5',\n            '&#x1F7EB',\n            '&#x1F7EA',\n            '&#x1F7E9',\n            '&#x1F7E8',\n            '&#x1F508',\n            '&#x1F507',\n            '&#x1F509',\n            '&#x1F50A',\n            '&#x1F514',\n            '&#x1F515',\n            '&#x1F4E3',\n            '&#x1F4E2',\n            '&#x1F5E8',\n            '&#x1F4AC',\n            '&#x1F4AD',\n            '&#x1F5EF',\n            '&#x1F0CF',\n            '&#x1F3B4',\n            '&#x1F004',\n            '&#x1F550',\n            '&#x1F551',\n            '&#x1F552',\n            '&#x1F553',\n            '&#x1F554',\n            '&#x1F555',\n            '&#x1F556',\n            '&#x1F557',\n            '&#x1F558',\n            '&#x1F559',\n            '&#x1F55A',\n            '&#x1F55B',\n            '&#x1F55C',\n            '&#x1F55D',\n            '&#x1F55E',\n            '&#x1F55F',\n            '&#x1F560',\n            '&#x1F561',\n            '&#x1F562',\n            '&#x1F563',\n            '&#x1F564',\n            '&#x1F565',\n            '&#x1F566',\n            '&#x1F567',\n            '&#x26A7',\n            '&#x1F3F3',\n            '&#x1F3F4',\n            '&#x1F3C1',\n            '&#x1F6A9',\n            '&#x1F1E6',\n            '&#x1F1E9',\n            '&#x1F1E7',\n            '&#x1F1EE',\n            '&#x1F1FB',\n            '&#x1F1F0',\n            '&#x1F1E8',\n            '&#x1F1F9',\n            '&#x1F1ED',\n            '&#x1F1EA',\n            '&#x1F1F8',\n            '&#x1F1EC',\n            '&#x1F1EB',\n            '&#x1F1F5',\n            '&#x1F1EF',\n            '&#x1F38C',\n            '&#x1F1FD',\n            '&#x1F1F1',\n            '&#x1F1F2',\n            '&#x1F1FE',\n            '&#x1F1F3',\n            '&#x1F1F4',\n            '&#x1F1F6',\n            '&#x1F1F7',\n            '&#x1F1FC',\n            '&#x1F1FF',\n            '&#x1F1FA',\n            '&#x1F3FB',\n            '&#x1F3FC',\n            '&#x1F3FD',\n            '&#x1F3FE',\n            '&#x1F3FF'\n        ]\n    };\n\n    // Add all emoji in a dropdown\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                emoji: 'Add an emoji'\n            },\n            az: {\n                emoji: 'Emoji yerləşdir'\n            },\n            ca: {\n                emoji: 'Afegir una emoticona'\n            },\n            da: {\n                emoji: 'Tilføj et humørikon'\n            },\n            de: {\n                emoji: 'Emoticon einfügen'\n            },\n            es: {\n                emoji: 'Añadir un emoticono'\n            },\n            et: {\n                emoji: 'Lisa emotikon'\n            },\n            fr: {\n                emoji: 'Ajouter un emoji'\n            },\n            hu: {\n                emoji: 'Emoji beszúrás'\n            },\n            ja: {\n                emoji: '絵文字の挿入'\n            },\n            ko: {\n                emoji: '이모지 넣기'\n            },\n            ru: {\n                emoji: 'Вставить emoji'\n            },\n            sl: {\n                emoji: 'Vstavi emotikon'\n            },\n            tr: {\n                emoji: 'Emoji ekle'\n            },\n            zh_cn: {\n                emoji: '添加表情'\n            },\n        },\n        // jshint camelcase:true\n        plugins: {\n            emoji: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.emoji = trumbowyg.o.plugins.emoji || defaultOptions;\n                    var emojiBtnDef = {\n                        dropdown: buildDropdown(trumbowyg)\n                    };\n                    trumbowyg.addBtnDef('emoji', emojiBtnDef);\n                }\n            }\n        }\n    });\n\n    function buildDropdown(trumbowyg) {\n        var dropdown = [];\n\n        $.each(trumbowyg.o.plugins.emoji.emojiList, function (i, emoji) {\n            if (Array.isArray(emoji)) { // Custom emoji behaviour\n                var emojiCode = emoji[0],\n                    emojiUrl = emoji[1],\n                    emojiHtml = '<img src=\"' + emojiUrl + '\" alt=\"' + emojiCode + '\">',\n                    customEmojiBtnName = 'emoji-' + emojiCode.replace(/:/g, ''),\n                    customEmojiBtnDef = {\n                        hasIcon: false,\n                        text: emojiHtml,\n                        fn: function () {\n                            trumbowyg.execCmd('insertImage', emojiUrl, false, true);\n                            return true;\n                        }\n                    };\n\n                trumbowyg.addBtnDef(customEmojiBtnName, customEmojiBtnDef);\n                dropdown.push(customEmojiBtnName);\n            } else { // Default behaviour\n                var btn = emoji.replace(/:/g, ''),\n                    defaultEmojiBtnName = 'emoji-' + btn,\n                    defaultEmojiBtnDef = {\n                        text: emoji,\n                        fn: function () {\n                            var encodedEmoji = String.fromCodePoint(emoji.replace('&#', '0'));\n                            trumbowyg.execCmd('insertText', encodedEmoji);\n                            return true;\n                        }\n                    };\n\n                trumbowyg.addBtnDef(defaultEmojiBtnName, defaultEmojiBtnDef);\n                dropdown.push(defaultEmojiBtnName);\n            }\n        });\n\n        return dropdown;\n    }\n})(jQuery);\n"
  },
  {
    "path": "plugins/emoji/ui/sass/trumbowyg.emoji.scss",
    "content": ".trumbowyg-dropdown-emoji {\n    width: 265px;\n    padding: 7px 0 7px 5px;\n}\n\n.trumbowyg-dropdown-emoji svg {\n    display: none !important;\n}\n\n.trumbowyg-dropdown-emoji button {\n    display: block;\n    position: relative;\n    float: left;\n    height: 26px;\n    width: 26px;\n    padding: 0;\n    margin: 2px;\n    line-height: 24px;\n    text-align: center;\n\n    &:hover,\n    &:focus {\n        &::after {\n            display: block;\n            position: absolute;\n            top: -5px;\n            left: -5px;\n            height: 27px;\n            width: 27px;\n            background: inherit;\n            box-shadow: #000 0 0 2px;\n            z-index: 10;\n            background-color: transparent;\n        }\n    }\n}\n\n.trumbowyg .emoji {\n    width: 22px;\n    height: 22px;\n    display: inline-block;\n}\n"
  },
  {
    "path": "plugins/fontfamily/trumbowyg.fontfamily.js",
    "content": "(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                fontFamily: 'Font'\n            },\n            az: {\n                fontFamily: 'Şrift'\n            },\n            by: {\n                fontFamily: 'Шрыфт'\n            },\n            ca: {\n                fontFamily: 'Font'\n            },\n            da: {\n                fontFamily: 'Skrifttype'\n            },\n            de: {\n                fontFamily: 'Schriftart'\n            },\n            es: {\n                fontFamily: 'Fuente'\n            },\n            et: {\n                fontFamily: 'Font'\n            },\n            fr: {\n                fontFamily: 'Police'\n            },\n            hu: {\n                fontFamily: 'Betűtípus'\n            },\n            ko: {\n                fontFamily: '글꼴'\n            },\n            nl: {\n                fontFamily: 'Lettertype'\n            },\n            pt_br: {\n                fontFamily: 'Fonte'\n            },\n            ru: {\n                fontFamily: 'Шрифт'\n            },\n            sl: {\n                fontFamily: 'Pisava'\n            },\n            tr: {\n                fontFamily: 'Yazı tipi'\n            },\n            zh_tw: {\n                fontFamily: '字體'\n            }\n        }\n    });\n    // jshint camelcase:true\n\n    var defaultOptions = {\n        fontList: [\n            {name: 'Arial', family: 'Arial, Helvetica, sans-serif'},\n            {name: 'Arial Black', family: 'Arial Black, Gadget, sans-serif'},\n            {name: 'Comic Sans', family: 'Comic Sans MS, Textile, cursive, sans-serif'},\n            {name: 'Courier New', family: 'Courier New, Courier, monospace'},\n            {name: 'Georgia', family: 'Georgia, serif'},\n            {name: 'Impact', family: 'Impact, Charcoal, sans-serif'},\n            {name: 'Lucida Console', family: 'Lucida Console, Monaco, monospace'},\n            {name: 'Lucida Sans', family: 'Lucida Sans Uncide, Lucida Grande, sans-serif'},\n            {name: 'Palatino', family: 'Palatino Linotype, Book Antiqua, Palatino, serif'},\n            {name: 'Tahoma', family: 'Tahoma, Geneva, sans-serif'},\n            {name: 'Times New Roman', family: 'Times New Roman, Times, serif'},\n            {name: 'Trebuchet', family: 'Trebuchet MS, Helvetica, sans-serif'},\n            {name: 'Verdana', family: 'Verdana, Geneva, sans-serif'}\n        ]\n    };\n\n    // Add dropdown with web safe fonts\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            fontfamily: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.fontfamily = $.extend({},\n                        defaultOptions,\n                        trumbowyg.o.plugins.fontfamily || {}\n                    );\n\n                    trumbowyg.addBtnDef('fontfamily', {\n                        dropdown: buildDropdown(trumbowyg),\n                        hasIcon: false,\n                        text: trumbowyg.lang.fontFamily\n                    });\n                }\n            }\n        }\n    });\n\n    function buildDropdown(trumbowyg) {\n        var dropdown = [];\n\n        $.each(trumbowyg.o.plugins.fontfamily.fontList, function (index, font) {\n            trumbowyg.addBtnDef('fontfamily_' + index, {\n                title: '<span style=\"font-family: ' + font.family + ';\">' + font.name + '</span>',\n                hasIcon: false,\n                fn: function () {\n                    trumbowyg.execCmd('fontName', font.family, true);\n                }\n            });\n            dropdown.push('fontfamily_' + index);\n        });\n\n        return dropdown;\n    }\n})(jQuery);\n"
  },
  {
    "path": "plugins/fontsize/trumbowyg.fontsize.js",
    "content": "(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                fontsize: 'Font size',\n                fontsizes: {\n                    'x-small': 'Extra small',\n                    'small': 'Small',\n                    'medium': 'Regular',\n                    'large': 'Large',\n                    'x-large': 'Extra large',\n                    'custom': 'Custom'\n                },\n                fontCustomSize: {\n                    title: 'Custom Font Size',\n                    label: 'Font Size',\n                    value: '48px'\n                }\n            },\n            az: {\n                fontsize: 'Şrift həcmi',\n                fontsizes: {\n                    'x-small': 'Daha kiçik',\n                    'small': 'Kiçik',\n                    'medium': 'Normal',\n                    'large': 'Böyük',\n                    'x-large': 'Daha böyük',\n                    'custom': 'Fərdi həcm'\n                },\n                fontCustomSize: {\n                    title: 'Fərdi şrift həcmi',\n                    label: 'Şrift həcmi',\n                    value: '48px'\n                }\n            },\n            by: {\n                fontsize: 'Памер шрыфта',\n                fontsizes: {\n                    'x-small': 'Вельмі маленькі',\n                    'small': 'Маленькі',\n                    'medium': 'Звычайны',\n                    'large': 'Вялікі',\n                    'x-large': 'Вельмі вялікі',\n                    'custom': 'Карыстальніцкі'\n                },\n                fontCustomSize: {\n                    title: 'Карыстальніцкі Памер Шрыфта',\n                    label: 'Памер Шрыфта',\n                    value: '48px'\n                }\n            },\n            ca: {\n                fontsize: 'Mida de la lletra',\n                fontsizes: {\n                    'x-small': 'Molt petita',\n                    'small': 'Petita',\n                    'medium': 'Normal',\n                    'large': 'Gran',\n                    'x-large': 'Molt Gran',\n                    'custom': 'Personalitzada'\n                },\n                fontCustomSize: {\n                    title: 'Mida de lletra personalitzada',\n                    label: 'Mida de lletra',\n                    value: '48px'\n                }\n            },\n            da: {\n                fontsize: 'Skriftstørrelse',\n                fontsizes: {\n                    'x-small': 'Ekstra lille',\n                    'small': 'Lille',\n                    'medium': 'Normal',\n                    'large': 'Stor',\n                    'x-large': 'Ekstra stor',\n                    'custom': 'Brugerdefineret'\n                }\n            },\n            de: {\n                fontsize: 'Schriftgröße',\n                fontsizes: {\n                    'x-small': 'Sehr klein',\n                    'small': 'Klein',\n                    'medium': 'Normal',\n                    'large': 'Groß',\n                    'x-large': 'Sehr groß',\n                    'custom': 'Benutzerdefiniert'\n                },\n                fontCustomSize: {\n                    title: 'Benutzerdefinierte Schriftgröße',\n                    label: 'Schriftgröße',\n                    value: '48px'\n                }\n            },\n            es: {\n                fontsize: 'Tamaño de Fuente',\n                fontsizes: {\n                    'x-small': 'Extra pequeña',\n                    'small': 'Pegueña',\n                    'medium': 'Regular',\n                    'large': 'Grande',\n                    'x-large': 'Extra Grande',\n                    'custom': 'Customizada'\n                },\n                fontCustomSize: {\n                    title: 'Tamaño de Fuente Customizada',\n                    label: 'Tamaño de Fuente',\n                    value: '48px'\n                }\n            },\n            et: {\n                fontsize: 'Teksti suurus',\n                fontsizes: {\n                    'x-small': 'Väga väike',\n                    'small': 'Väike',\n                    'medium': 'Tavaline',\n                    'large': 'Suur',\n                    'x-large': 'Väga suur',\n                    'custom': 'Määra ise'\n                },\n                fontCustomSize: {\n                    title: 'Kohandatud teksti suurus',\n                    label: 'Teksti suurus',\n                    value: '48px'\n                }\n            },\n            fr: {\n                fontsize: 'Taille de la police',\n                fontsizes: {\n                    'x-small': 'Très petit',\n                    'small': 'Petit',\n                    'medium': 'Normal',\n                    'large': 'Grand',\n                    'x-large': 'Très grand',\n                    'custom': 'Taille personnalisée'\n                },\n                fontCustomSize: {\n                    title: 'Taille de police personnalisée',\n                    label: 'Taille de la police',\n                    value: '48px'\n                }\n            },\n            hu: {\n                fontsize: 'Betű méret',\n                fontsizes: {\n                    'x-small': 'Extra kicsi',\n                    'small': 'Kicsi',\n                    'medium': 'Normális',\n                    'large': 'Nagy',\n                    'x-large': 'Extra nagy',\n                    'custom': 'Egyedi'\n                },\n                fontCustomSize: {\n                    title: 'Egyedi betű méret',\n                    label: 'Betű méret',\n                    value: '48px'\n                }\n            },\n            it: {\n                fontsize: 'Dimensioni del testo',\n                fontsizes: {\n                    'x-small': 'Molto piccolo',\n                    'small': 'piccolo',\n                    'regular': 'normale',\n                    'large': 'grande',\n                    'x-large': 'Molto grande',\n                    'custom': 'Personalizzato'\n                },\n                fontCustomSize: {\n                    title: 'Dimensioni del testo personalizzato',\n                    label: 'Dimensioni del testo',\n                    value: '48px'\n                }\n            },\n            ko: {\n                fontsize: '글꼴 크기',\n                fontsizes: {\n                    'x-small': '아주 작게',\n                    'small': '작게',\n                    'medium': '보통',\n                    'large': '크게',\n                    'x-large': '아주 크게',\n                    'custom': '사용자 지정'\n                },\n                fontCustomSize: {\n                    title: '사용자 지정 글꼴 크기',\n                    label: '글꼴 크기',\n                    value: '48px'\n                }\n            },\n            nl: {\n                fontsize: 'Lettergrootte',\n                fontsizes: {\n                    'x-small': 'Extra klein',\n                    'small': 'Klein',\n                    'medium': 'Normaal',\n                    'large': 'Groot',\n                    'x-large': 'Extra groot',\n                    'custom': 'Handmatig'\n                },\n                fontCustomSize: {\n                    title: 'Handmatige lettergrootte',\n                    label: 'Lettergrootte',\n                    value: '48px'\n                }\n            },\n            pt_br: {\n                fontsize: 'Tamanho da fonte',\n                fontsizes: {\n                    'x-small': 'Extra pequeno',\n                    'small': 'Pequeno',\n                    'regular': 'Médio',\n                    'large': 'Grande',\n                    'x-large': 'Extra grande',\n                    'custom': 'Personalizado'\n                },\n                fontCustomSize: {\n                    title: 'Tamanho de Fonte Personalizado',\n                    label: 'Tamanho de Fonte',\n                    value: '48px'\n                }\n            },\n            ru: {\n                fontsize: 'Размер шрифта',\n                fontsizes: {\n                    'x-small': 'Очень маленький',\n                    'small': 'Маленький',\n                    'medium': 'Обычный',\n                    'large': 'Большой',\n                    'x-large': 'Очень большой',\n                    'custom': 'Пользовательский'\n                },\n                fontCustomSize: {\n                    title: 'Пользовательский Размер Шрифта',\n                    label: 'Размер Шрифта',\n                    value: '48px'\n                }\n            },\n            sl: {\n                fontsize: 'Velikost pisave',\n                fontsizes: {\n                    'x-small': 'Ekstra majhna',\n                    'small': 'Majhna',\n                    'medium': 'Navadno',\n                    'large': 'Velika',\n                    'x-large': 'Ekstra velika',\n                    'custom': 'Poljubna'\n                },\n                fontCustomSize: {\n                    title: 'Poljubna velikost pisave',\n                    label: 'Velikost pisave',\n                    value: '48px'\n                }\n            },\n            tr: {\n                fontsize: 'Yazı boyutu',\n                fontsizes: {\n                    'x-small': 'Çok küçük',\n                    'small': 'Küçük',\n                    'medium': 'Normal',\n                    'large': 'Büyük',\n                    'x-large': 'Çok büyük',\n                    'custom': 'Özel'\n                },\n                fontCustomSize: {\n                    title: 'Özel Yazı Boyutu',\n                    label: 'Yazı Boyutu',\n                    value: '48px'\n                }\n            },\n            zh_tw: {\n                fontsize: '字體大小',\n                fontsizes: {\n                    'x-small': '最小',\n                    'small': '小',\n                    'medium': '中',\n                    'large': '大',\n                    'x-large': '最大',\n                    'custom': '自訂大小'\n                },\n                fontCustomSize: {\n                    title: '自訂義字體大小',\n                    label: '字體大小',\n                    value: '48px'\n                }\n            }\n        }\n    });\n    // jshint camelcase:true\n\n    var defaultOptions = {\n        sizeList: [\n            'x-small',\n            'small',\n            'medium',\n            'large',\n            'x-large'\n        ],\n        allowCustomSize: true\n    };\n\n    // Add dropdown with font sizes\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            fontsize: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.fontsize = $.extend({},\n                        defaultOptions,\n                        trumbowyg.o.plugins.fontsize || {}\n                    );\n\n                    trumbowyg.addBtnDef('fontsize', {\n                        dropdown: buildDropdown(trumbowyg)\n                    });\n                }\n            }\n        }\n    });\n\n    function setFontSize(trumbowyg, size) {\n        trumbowyg.$ed.focus();\n        trumbowyg.saveRange();\n\n        // Temporary size\n        trumbowyg.execCmd('fontSize', '1');\n\n        var fontElements = trumbowyg.$ed.find('font[size=\"1\"]');\n\n        // Remove previous font-size span tags. Needed to prevent Firefox from\n        // nesting multiple spans on font-size changes.\n        // (see https://github.com/Alex-D/Trumbowyg/issues/1252)\n        fontElements.find('span[style*=\"font-size\"]').contents().unwrap();\n\n        // Find <font> elements that were added and change to <span> with chosen size\n        fontElements.replaceWith(function () {\n            return $('<span/>', {\n                css: {'font-size': size},\n                html: this.innerHTML\n            });\n        });\n\n        // Remove and leftover <span> elements\n        $(trumbowyg.range.startContainer.parentElement).find('span[style=\"\"]').contents().unwrap();\n\n        trumbowyg.restoreRange();\n        trumbowyg.syncCode();\n        trumbowyg.$c.trigger('tbwchange');\n    }\n\n    function buildDropdown(trumbowyg) {\n        var dropdown = [];\n\n        $.each(trumbowyg.o.plugins.fontsize.sizeList, function (index, size) {\n            trumbowyg.addBtnDef('fontsize_' + size, {\n                text: '<span style=\"font-size: ' + size + ';\">' + (trumbowyg.lang.fontsizes[size] || size) + '</span>',\n                hasIcon: false,\n                fn: function () {\n                    setFontSize(trumbowyg, size);\n                }\n            });\n            dropdown.push('fontsize_' + size);\n        });\n\n        if (trumbowyg.o.plugins.fontsize.allowCustomSize) {\n            var customSizeButtonName = 'fontsize_custom';\n            var customSizeBtnDef = {\n                fn: function () {\n                    trumbowyg.openModalInsert(trumbowyg.lang.fontCustomSize.title,\n                        {\n                            size: {\n                                label: trumbowyg.lang.fontCustomSize.label,\n                                value: trumbowyg.lang.fontCustomSize.value\n                            }\n                        },\n                        function (form) {\n                            setFontSize(trumbowyg, form.size);\n                            return true;\n                        }\n                    );\n                },\n                text: '<span style=\"font-size: medium;\">' + trumbowyg.lang.fontsizes.custom + '</span>',\n                hasIcon: false\n            };\n            trumbowyg.addBtnDef(customSizeButtonName, customSizeBtnDef);\n            dropdown.push(customSizeButtonName);\n        }\n\n        return dropdown;\n    }\n})(jQuery);\n"
  },
  {
    "path": "plugins/giphy/trumbowyg.giphy.js",
    "content": "/* global AbortController: true */\n(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                giphy: 'Insert GIF'\n            },\n            az: {\n                giphy: 'GIF yerləşdir'\n            },\n            by: {\n                giphy: 'Уставіць GIF'\n            },\n            de: {\n                giphy: 'GIF einfügen'\n            },\n            et: {\n                giphy: 'Sisesta GIF'\n            },\n            fr: {\n                giphy: 'Insérer un GIF'\n            },\n            hu: {\n                giphy: 'GIF beszúrás'\n            },\n            ru: {\n                giphy: 'Вставить GIF'\n            },\n            sl: {\n                giphy: 'Vstavi GIF'\n            },\n            tr: {\n                giphy: 'GIF ekle'\n            }\n            // jshint camelcase:true\n        }\n    });\n\n    var giphyLogo = '<svg viewBox=\"0 0 231 53\" xmlns=\"http://www.w3.org/2000/svg\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" stroke-linejoin=\"round\" stroke-miterlimit=\"2\"><path d=\"M48.32 22.386c0-1.388-.252-1.892-1.767-1.85-3.448.126-6.855.042-10.303.042H25.443c-.927 0-1.346.211-1.305 1.22.085 2.86.085 5.72.043 8.58 0 .883.252 1.169 1.169 1.135 2.018-.084 3.995-.042 6.014 0 1.64 0 4.164-.546 4.752.252.841 1.169.421 3.364.337 5.089-.043.547-.547 1.304-1.094 1.598-2.692 1.556-5.678 2.018-8.747 1.892-5.342-.21-9.336-2.439-11.481-7.527-1.388-3.364-1.725-6.855-1.01-10.43 1.01-4.963 3.407-8.747 8.58-10.051 5.215-1.305 10.136-.547 14.467 2.817 1.219.967 1.798.715 2.691-.294 1.514-1.724 3.154-3.322 4.753-4.963 1.892-1.933 1.892-1.892-.169-3.7C38.429.813 31.238-.617 23.5.224 12.818 1.393 5.248 6.658 1.59 17.045-.177 22.008-.428 27.097.623 32.227c1.682 7.914 5.551 14.12 13.289 17.368 6.898 2.901 14.046 3.448 21.321 1.598 4.331-1.093 8.411-2.608 11.354-6.223 1.136-1.388 1.725-2.902 1.682-4.71l.043-17.873.008-.001zm125.153 3.784l.042-23.046c0-1.136-.168-1.598-1.472-1.556a238.02 238.02 0 0 1-11.017 0c-1.136-.042-1.439.337-1.439 1.439v15.645c0 1.345-.421 1.556-1.641 1.556a422.563 422.563 0 0 0-14.593 0c-1.262.042-1.472-.421-1.439-1.556l.043-15.813c0-.926-.169-1.304-1.17-1.262h-11.513c-.927 0-1.304.169-1.304 1.22v46.764c0 .967.252 1.262 1.219 1.262h11.512c1.169.042 1.262-.462 1.262-1.388l-.042-15.644c0-1.053.251-1.346 1.304-1.346h15.14c1.22 0 1.388.421 1.388 1.472l-.042 15.477c0 1.093.21 1.472 1.388 1.439 3.615-.085 7.233-.085 10.807 0 1.304.042 1.598-.337 1.598-1.598l-.042-23.047.011-.018zM106.565 1.654c-8.369-.211-16.728-.126-25.065-.211-1.346 0-1.767.337-1.767 1.724l.043 23.004v23.215c0 1.009.168 1.439 1.304 1.387a271.22 271.22 0 0 1 11.691 0c1.094 0 1.346-.336 1.346-1.345l-.042-10.64c0-1.052.294-1.345 1.345-1.345 3.322.042 6.645.085 9.967-.085 4.407-.21 8.621-1.219 12.111-4.12 5.551-4.584 7.613-12.701 5.131-20.061-2.313-6.561-8.747-11.354-16.064-11.522v-.001zm-3.028 24.013c-2.818.042-5.594-.043-8.411.042-1.169.042-1.439-.378-1.345-1.439.084-1.556 0-3.069 0-4.626v-5.131c-.043-.841.251-1.094 1.052-1.052 2.986.042 5.929-.085 8.915.042 3.616.126 5.887 2.692 5.846 6.266-.126 3.658-2.313 5.846-6.055 5.887l-.002.011zM229.699 1.569c-4.458 0-8.915-.042-13.415.043-.629 0-1.472.503-1.85 1.052a505.695 505.695 0 0 0-8.957 14.214c-.884 1.472-1.22 1.169-1.977-.084l-8.496-14.089c-.503-.841-1.052-1.136-2.018-1.136l-13.078.043c-.462 0-.967.125-1.439.21.21.378.378.799.629 1.169l17.412 27.167c.462.715.715 1.682.757 2.524v16.653c0 1.052.168 1.514 1.388 1.472 3.784-.084 7.57-.084 11.354 0 1.136.043 1.304-.377 1.304-1.387l-.042-8.58c0-2.734-.084-5.51.042-8.243.043-.926.337-1.933.841-2.649l18.167-27.041c.252-.337.337-.758.547-1.17a3.636 3.636 0 0 0-1.169-.168zM70.104 2.661c0-1.009-.294-1.219-1.262-1.219H57.69c-1.262-.043-1.472.377-1.472 1.513l.042 23.004v23.34c0 1.053.126 1.514 1.346 1.473 3.7-.085 7.444-.043 11.152 0 .966 0 1.387-.085 1.387-1.262l-.042-46.857.001.008z\" fill=\"currentColor\" fill-rule=\"nonzero\"/></svg>'; // jshint ignore:line\n\n    var CANCEL_EVENT = 'tbwcancel';\n\n    // Throttle helper\n    function trumbowygThrottle(callback, delay) {\n        var last;\n        var timer;\n\n        return function () {\n            var context = this;\n            var now = new Date().getTime();\n            var args = arguments;\n\n            if (last && now < last + delay) {\n                clearTimeout(timer);\n                timer = setTimeout(function () {\n                    last = now;\n                    callback.apply(context, args);\n                }, delay);\n            } else {\n                last = now;\n                callback.apply(context, args);\n            }\n        };\n    }\n\n    // Fills modal with response gifs\n    function renderGifs(response, $giphyModal, trumbowyg, mustEmpty) {\n        var width = ($giphyModal.width() - 20) / 3;\n\n        var html = response.data\n            .filter(function (gifData) {\n                var image = gifData.images[GIPHY_OPTIONS.pickerRendition];\n                return !!image[GIPHY_OPTIONS.pickerRenditionUrlAttribute];\n            })\n            .map(function (gifData) {\n                var image = gifData.images[GIPHY_OPTIONS.pickerRendition];\n                var selectionImage = gifData.images[GIPHY_OPTIONS.selectionRendition];\n                var imageRatio = image.height / image.width,\n                    altText = gifData.title;\n\n                var url = image[GIPHY_OPTIONS.pickerRenditionUrlAttribute];\n                var selectionUrl = selectionImage[GIPHY_OPTIONS.selectionRenditionUrlAttribute];\n                var imgHtml = '<img src=' + url + ' width=\"' + width + '\" height=\"' + imageRatio * width + '\" alt=\"' + altText + '\" data-selection-url=\"' + selectionUrl + '\" loading=\"lazy\" />';\n                return '<div class=\"img-container\">' + imgHtml + '</div>';\n            })\n            .join('')\n        ;\n\n        if (mustEmpty === true) {\n            if (html.length === 0) {\n                if ($('.' + trumbowyg.o.prefix + 'giphy-no-result', $giphyModal).length > 0) {\n                    return;\n                }\n\n                html = '<img class=\"' + trumbowyg.o.prefix + 'giphy-no-result\" src=\"' + trumbowyg.o.plugins.giphy.noResultGifUrl + '\"/>';\n            }\n\n            $giphyModal.empty();\n        }\n        $giphyModal.append(html);\n\n        // Remove gray overlay on image load\n        // moved here from inline callback definition due to CSP issue\n        // Note: this is being done post-factum because load event doesn't bubble up and so can't be delegated\n        var addLoadedClass = function (img) {\n            img.classList.add('tbw-loaded');\n        };\n        $('img', $giphyModal).each(function () {\n            var img = this;\n            if (img.complete) { // images load instantly when cached and esp. when loaded in previous modal open\n                addLoadedClass(img);\n            } else {\n                img.addEventListener('load', function () {\n                    addLoadedClass(this);\n                });\n            }\n        });\n\n        $('img', $giphyModal).on('click', function () {\n            var src = $(this).data('selection-url'),\n                alt = $(this).attr('alt');\n            trumbowyg.restoreRange();\n            trumbowyg.execCmd('insertImage', src, false, true);\n\n            // relay alt tag into inserted image\n            if (alt) {\n                var $img = $('img[src=\"' + src + '\"]:not([alt])', trumbowyg.$box);\n                $img.attr('alt', alt);\n                // Note: This seems to fire relatively early and could be wrapped in a setTimeout if needed\n                trumbowyg.syncCode();\n            }\n            $('img', $giphyModal).off();\n            trumbowyg.closeModal();\n        });\n    }\n\n    // see: https://developers.giphy.com/explorer/\n    var defaultOptions = {\n        rating: 'g',\n        apiKey: null,\n        throttleDelay: 300,\n        limit: 50,\n        noResultGifUrl: 'https://media.giphy.com/media/2Faz9FbRzmwxY0pZS/giphy.gif'\n    };\n\n    const GIPHY_OPTIONS = {\n        bundle: 'low_bandwidth',\n        pickerRendition: 'fixed_width_small', // see: https://developers.giphy.com/docs/optional-settings/#renditions-on-demand\n        pickerRenditionUrlAttribute: 'webp', // can be 'url' or 'mp4' or 'webp'\n        selectionRendition: 'original',\n        selectionRenditionUrlAttribute: 'url'\n    };\n\n    // Add dropdown with font sizes\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            giphy: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.giphy = $.extend({},\n                        defaultOptions,\n                        trumbowyg.o.plugins.giphy || {}\n                    );\n\n                    trumbowyg.addBtnDef('giphy', {\n                        fn: function () {\n                            if (trumbowyg.o.plugins.giphy.apiKey === null) {\n                                throw new Error('You must set a Giphy API Key');\n                            }\n\n                            var BASE_URL = [\n                                'https://api.giphy.com/v1/gifs/search?api_key=',\n                                trumbowyg.o.plugins.giphy.apiKey,\n                                '&rating=',\n                                trumbowyg.o.plugins.giphy.rating,\n                                '&limit=',\n                                trumbowyg.o.plugins.giphy.limit,\n                                '&bundle=',\n                                GIPHY_OPTIONS.bundle,\n                            ].join('');\n                            const DEFAULT_URL = BASE_URL.replace('/search', '/trending');\n                            var prefix = trumbowyg.o.prefix;\n                            var abortController = new AbortController();\n\n                            // Create and open the modal\n                            var searchInput = '<input name=\"\" class=\"' + prefix + 'giphy-search\" placeholder=\"Search a GIF\" autofocus=\"autofocus\">',\n                                closeButton = '<button class=\"' + prefix + 'giphy-close\" title=\"' + trumbowyg.lang.close + '\"><svg><use xlink:href=\"' + trumbowyg.svgPath + '#' + prefix + 'close\"/></svg></button>',\n                                poweredByGiphy = '<div class=\"' + prefix + 'powered-by-giphy\"><span>Powered by</span>' + giphyLogo + '</div>',\n                                giphyModalHtml = searchInput + closeButton + poweredByGiphy + '<div class=\"' + prefix + 'giphy-modal-scroll\"><div class=\"' + prefix + 'giphy-modal\"></div></div>';\n\n                            trumbowyg\n                                .openModal(null, giphyModalHtml, false)\n                                .one(CANCEL_EVENT, function () {\n                                    try {\n                                        abortController.abort();\n                                        abortController = new AbortController();\n                                    } catch (e) {\n                                    }\n\n                                    trumbowyg.closeModal();\n                                });\n\n                            var $giphyInput = $('.' + prefix + 'giphy-search'),\n                                $giphyClose = $('.' + prefix + 'giphy-close'),\n                                $giphyModal = $('.' + prefix + 'giphy-modal');\n\n                            var onError = function () {\n                                if (navigator.onLine || $('.' + prefix + 'giphy-offline', $giphyModal).length) {\n                                    return;\n                                }\n\n                                $giphyModal.empty();\n                                $giphyModal.append('<p class=\"' + prefix + 'giphy-offline\">You are offline</p>');\n                            };\n\n                            // Load trending gifs as default\n                            fetch(DEFAULT_URL, {\n                                method: 'GET',\n                                cache: 'no-cache',\n                                signal: abortController.signal\n                            }).then((response) => {\n                                response.json().then((responseJson) => {\n                                    renderGifs(responseJson, $giphyModal, trumbowyg, true);\n                                });\n                            }).catch(() => {\n                                onError();\n                            });\n\n                            var searchGifsOnInput = function () {\n                                var query = $giphyInput.val();\n\n                                if (query.length === 0) {\n                                    return;\n                                }\n\n                                try {\n                                    abortController.abort();\n                                    abortController = new AbortController();\n                                } catch (e) {\n                                }\n\n                                fetch(BASE_URL + '&q=' + encodeURIComponent(query), {\n                                    method: 'GET',\n                                    cache: 'no-cache',\n                                    signal: abortController.signal\n                                }).then((response) => {\n                                    response.json().then((responseJson) => {\n                                        renderGifs(responseJson, $giphyModal, trumbowyg, true);\n                                    });\n                                }).catch(() => {\n                                    onError();\n                                });\n                            };\n                            var throttledInputRequest = trumbowygThrottle(searchGifsOnInput, trumbowyg.o.plugins.giphy.throttleDelay);\n\n                            $giphyInput.on('input', throttledInputRequest);\n                            $giphyInput.focus();\n\n                            $giphyClose.one('click', function () {\n                                $giphyModal.trigger(CANCEL_EVENT);\n                            });\n                        }\n                    });\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/giphy/ui/sass/trumbowyg.giphy.scss",
    "content": ".trumbowyg-giphy-button svg {\n    transform: scale(1.22);\n}\n\n.trumbowyg-giphy-search {\n    display: block;\n    width: 80%;\n    margin: 5%;\n    padding-left: 10px;\n    padding-right: 150px;\n}\n\n.trumbowyg-giphy-close {\n    position: absolute;\n    top: calc(5% + 8px);\n    right: calc(5% - 2px);\n    width: 30px;\n    height: 30px;\n    background: none;\n    border: 1px solid transparent;\n\n    &:hover,\n    &:focus {\n        outline: none;\n        background: #ecf0f1;\n    }\n\n    &:focus {\n        border-color: rgba(0, 0, 0, 0.3);\n    }\n}\n\n.trumbowyg-powered-by-giphy {\n    position: absolute;\n    top: calc(5% + 12px);\n    right: calc(15% + 10px);\n    pointer-events: none;\n    user-select: none;\n\n    span {\n        text-transform: uppercase;\n        font-weight: bold;\n        font-size: 10px;\n        opacity: 0.6;\n    }\n\n    svg {\n        width: 66px;\n        height: 15px;\n        vertical-align: middle;\n        margin-left: 6px;\n        opacity: 0.45;\n    }\n}\n\n.trumbowyg-giphy-modal-scroll {\n    overflow: auto;\n    overflow-x: hidden;\n    height: 240px;\n}\n\n.trumbowyg-giphy-modal {\n    padding: 0 5%;\n    columns: 3;\n    column-gap: 10px;\n\n    .trumbowyg-giphy-no-result {\n        width: 250%;\n        margin: 13% 0 0 29%;\n    }\n\n    .trumbowyg-giphy-offline {\n        font-size: 18px;\n        width: 305%;\n        height: 600px;\n        margin-top: 95px;\n        text-align: center;\n    }\n}\n\n.trumbowyg-giphy-modal .img-container {\n    width: 100%;\n    margin-bottom: 10px;\n    background-color: #ecf0f1;\n\n    img {\n        width: 100%;\n        cursor: pointer;\n        opacity: 0;\n        transition: opacity 150ms;\n\n        &:hover,\n        &:focus {\n            border: #2ecc71 solid 3px;\n        }\n    }\n\n    img.tbw-loaded {\n        opacity: 1;\n    }\n}\n"
  },
  {
    "path": "plugins/highlight/trumbowyg.highlight.js",
    "content": "/* globals Prism */\n(function ($, Prism) {\n    'use strict';\n\n    // My plugin default options\n    var defaultOptions = {\n        enableLineHighlight: true,\n        languageNames: {\n            // For updated list of languages\n            // see https://github.com/PrismJS/prism/blob/master/plugins/show-language/prism-show-language.js\n            'html': 'HTML',\n            'xml': 'XML',\n            'svg': 'SVG',\n            'mathml': 'MathML',\n            'ssml': 'SSML',\n            'css': 'CSS',\n            'clike': 'C-like',\n            'js': 'JavaScript',\n            'abap': 'ABAP',\n            'abnf': 'Augmented Backus–Naur form',\n            'al': 'AL',\n            'antlr4': 'ANTLR4',\n            'g4': 'ANTLR4',\n            'apacheconf': 'Apache Configuration',\n            'apl': 'APL',\n            'aql': 'AQL',\n            'arff': 'ARFF',\n            'asciidoc': 'AsciiDoc',\n            'adoc': 'AsciiDoc',\n            'asm6502': '6502 Assembly',\n            'aspnet': 'ASP.NET (C#)',\n            'autohotkey': 'AutoHotkey',\n            'autoit': 'AutoIt',\n            'basic': 'BASIC',\n            'bbcode': 'BBcode',\n            'bnf': 'Backus–Naur form',\n            'rbnf': 'Routing Backus–Naur form',\n            'conc': 'Concurnas',\n            'csharp': 'C#',\n            'cs': 'C#',\n            'dotnet': 'C#',\n            'cpp': 'C++',\n            'cil': 'CIL',\n            'coffee': 'CoffeeScript',\n            'cmake': 'CMake',\n            'csp': 'Content-Security-Policy',\n            'css-extras': 'CSS Extras',\n            'dax': 'DAX',\n            'django': 'Django/Jinja2',\n            'jinja2': 'Django/Jinja2',\n            'dns-zone-file': 'DNS zone file',\n            'dns-zone': 'DNS zone file',\n            'dockerfile': 'Docker',\n            'ebnf': 'Extended Backus–Naur form',\n            'ejs': 'EJS',\n            'etlua': 'Embedded Lua templating',\n            'erb': 'ERB',\n            'excel-formula': 'Excel Formula',\n            'xlsx': 'Excel Formula',\n            'xls': 'Excel Formula',\n            'fsharp': 'F#',\n            'firestore-security-rules': 'Firestore security rules',\n            'ftl': 'FreeMarker Template Language',\n            'gcode': 'G-code',\n            'gdscript': 'GDScript',\n            'gedcom': 'GEDCOM',\n            'glsl': 'GLSL',\n            'gml': 'GameMaker Language',\n            'gamemakerlanguage': 'GameMaker Language',\n            'graphql': 'GraphQL',\n            'hs': 'Haskell',\n            'hcl': 'HCL',\n            'hlsl': 'HLSL',\n            'http': 'HTTP',\n            'hpkp': 'HTTP Public-Key-Pins',\n            'hsts': 'HTTP Strict-Transport-Security',\n            'ichigojam': 'IchigoJam',\n            'iecst': 'Structured Text (IEC 61131-3)',\n            'inform7': 'Inform 7',\n            'javadoc': 'JavaDoc',\n            'javadoclike': 'JavaDoc-like',\n            'javastacktrace': 'Java stack trace',\n            'jq': 'JQ',\n            'jsdoc': 'JSDoc',\n            'js-extras': 'JS Extras',\n            'js-templates': 'JS Templates',\n            'json': 'JSON',\n            'jsonp': 'JSONP',\n            'json5': 'JSON5',\n            'latex': 'LaTeX',\n            'tex': 'TeX',\n            'context': 'ConTeXt',\n            'lilypond': 'LilyPond',\n            'ly': 'LilyPond',\n            'emacs': 'Lisp',\n            'elisp': 'Lisp',\n            'emacs-lisp': 'Lisp',\n            'llvm': 'LLVM IR',\n            'lolcode': 'LOLCODE',\n            'md': 'Markdown',\n            'markup-templating': 'Markup templating',\n            'matlab': 'MATLAB',\n            'mel': 'MEL',\n            'moon': 'MoonScript',\n            'n1ql': 'N1QL',\n            'n4js': 'N4JS',\n            'n4jsd': 'N4JS',\n            'nand2tetris-hdl': 'Nand To Tetris HDL',\n            'nasm': 'NASM',\n            'neon': 'NEON',\n            'nginx': 'nginx',\n            'nsis': 'NSIS',\n            'objectivec': 'Objective-C',\n            'objc': 'Objective-C',\n            'ocaml': 'OCaml',\n            'opencl': 'OpenCL',\n            'parigp': 'PARI/GP',\n            'objectpascal': 'Object Pascal',\n            'pcaxis': 'PC-Axis',\n            'px': 'PC-Axis',\n            'peoplecode': 'PeopleCode',\n            'pcode': 'PeopleCode',\n            'php': 'PHP',\n            'phpdoc': 'PHPDoc',\n            'php-extras': 'PHP Extras',\n            'plsql': 'PL/SQL',\n            'powerquery': 'PowerQuery',\n            'pq': 'PowerQuery',\n            'mscript': 'PowerQuery',\n            'powershell': 'PowerShell',\n            'properties': '.properties',\n            'protobuf': 'Protocol Buffers',\n            'py': 'Python',\n            'q': 'Q (kdb+ database)',\n            'qml': 'QML',\n            'rkt': 'Racket',\n            'jsx': 'React JSX',\n            'tsx': 'React TSX',\n            'renpy': 'Ren\\'py',\n            'rest': 'reST (reStructuredText)',\n            'robotframework': 'Robot Framework',\n            'robot': 'Robot Framework',\n            'rb': 'Ruby',\n            'sas': 'SAS',\n            'sass': 'Sass (Sass)',\n            'scss': 'Sass (Scss)',\n            'shell-session': 'Shell session',\n            'solidity': 'Solidity (Ethereum)',\n            'solution-file': 'Solution file',\n            'sln': 'Solution file',\n            'soy': 'Soy (Closure Template)',\n            'sparql': 'SPARQL',\n            'rq': 'SPARQL',\n            'splunk-spl': 'Splunk SPL',\n            'sqf': 'SQF: Status Quo Function (Arma 3)',\n            'sql': 'SQL',\n            'tap': 'TAP',\n            'toml': 'TOML',\n            'tt2': 'Template Toolkit 2',\n            'trig': 'TriG',\n            'ts': 'TypeScript',\n            't4-cs': 'T4 Text Templates (C#)',\n            't4': 'T4 Text Templates (C#)',\n            't4-vb': 'T4 Text Templates (VB)',\n            't4-templating': 'T4 templating',\n            'uscript': 'UnrealScript',\n            'uc': 'UnrealScript',\n            'vbnet': 'VB.Net',\n            'vhdl': 'VHDL',\n            'vim': 'vim',\n            'visual-basic': 'Visual Basic',\n            'vb': 'Visual Basic',\n            'wasm': 'WebAssembly',\n            'wiki': 'Wiki markup',\n            'xeoracube': 'XeoraCube',\n            'xojo': 'Xojo (REALbasic)',\n            'xquery': 'XQuery',\n            'yaml': 'YAML',\n            'yml': 'YAML'\n        }\n    };\n\n    function highlightIt(text, language, lineHighlight) {\n        return [\n            '<pre class=\"language-' + language + '\" ' + (lineHighlight ? 'data-line=\"' + lineHighlight + '\"' : '') + '>',\n            '<code class=\"language-' + language + '\">' + Prism.highlight(text, Prism.languages[language]) + '</code>',\n            '</pre>'\n        ].join('');\n    }\n\n    function escapeHtml(html) {\n        return $('<div/>').text(html).html();\n    }\n\n    function buildHighlightOptions(trumbowyg) {\n        var languageNames = trumbowyg.o.plugins.highlight.languageNames;\n        var languageNameKeys = Object.keys(languageNames);\n        var prismLanguageKeys = Object.keys(Prism.languages);\n\n        var options = prismLanguageKeys.filter(function (languageKey) {\n            return languageNameKeys.indexOf(languageKey) >= 0;\n        }).map(function (languageKey) {\n            return {\n                id: languageKey,\n                name: languageNames[languageKey]\n            };\n        }).sort(function (a, b) {\n            // Sort languages by name\n            return a.name.localeCompare(b.name);\n        }).map(function (language) {\n            // Generate a list of options\n            return '<option value=\"' + escapeHtml(language.id) + '\">' + escapeHtml(language.name) + '</option>';\n        }).join('');\n\n        return options;\n    }\n\n    function buildLineHighlightFieldIfEnabled(trumbowyg) {\n        if (trumbowyg.o.plugins.highlight.enableLineHighlight === false) {\n            return '';\n        }\n\n        return '<div class=\"' + trumbowyg.o.prefix + 'highlight-form-group\">' +\n            '   <input placeholder=\"' + trumbowyg.lang.highlightLine +\n            '\" class=\"' + trumbowyg.o.prefix + 'highlight-form-control trumbowyg-line-highlight\"/>' +\n            '</div>';\n    }\n\n    // If my plugin is a button\n    function buildButtonDef(trumbowyg) {\n        return {\n            fn: function () {\n                var $modal = trumbowyg.openModal('Code', [\n                    '<div class=\"' + trumbowyg.o.prefix + 'highlight-form-group\">',\n                    '   <select class=\"' + trumbowyg.o.prefix + 'highlight-form-control language\" autofocus>',\n                    buildHighlightOptions(trumbowyg),\n                    '   </select>',\n                    '</div>',\n                    '<div class=\"' + trumbowyg.o.prefix + 'highlight-form-group\">',\n                    '   <textarea class=\"' + trumbowyg.o.prefix + 'highlight-form-control code\"></textarea>',\n                    '</div>',\n                    buildLineHighlightFieldIfEnabled(trumbowyg),\n                ].join('\\n')),\n                $language = $modal.find('.language'),\n                $code = $modal.find('.code'),\n                $lineHighlight = $modal.find('.trumbowyg-line-highlight');\n\n                // Listen clicks on modal box buttons\n                $modal.on('tbwconfirm', function () {\n                    trumbowyg.restoreRange();\n                    trumbowyg.execCmd('insertHTML', highlightIt($code.val(), $language.val(), $lineHighlight.val()));\n                    trumbowyg.execCmd('insertHTML', '<p><br></p>');\n\n                    trumbowyg.closeModal();\n                });\n\n                $modal.on('tbwcancel', function () {\n                    trumbowyg.closeModal();\n                });\n            }\n        };\n    }\n\n    $.extend(true, $.trumbowyg, {\n        // Add some translations\n        langs: {\n            // jshint camelcase:false\n            en: {\n                highlight: 'Code syntax highlight',\n                highlightLine: 'Highlight lines, e.g.: 1,3-5'\n            },\n            az: {\n                highlight: 'Kod birləşməsini vurğulamaq',\n                highlightLine: 'Sətirləri vurğulamaq, məsələn: 1,3-5'\n            },\n            by: {\n                highlight: 'Падсветка сінтаксісу кода',\n                highlightLine: 'Падсвятліць радкі, напр.: 1,3-5'\n            },\n            es: {\n                highlight: 'Resaltado de sintaxis de código',\n                highlightLine: 'Resaltar lineas, ej: 1,3-5'\n            },\n            et: {\n                highlight: 'Koodi esiletoomine',\n                highlightLine: 'Koodiread, näiteks: 1,3-5'\n            },\n            hu: {\n                highlight: 'Kód kiemelés'\n            },\n            ko: {\n                highlight: '코드 문법 하이라이트'\n            },\n            pt_br: {\n                highlight: 'Realçar sintaxe de código'\n            },\n            ru: {\n                highlight: 'Подсветка синтаксиса кода',\n                highlightLine: 'Подсветить строки, напр.: 1,3-5'\n            },\n            sl: {\n                highlight: 'Označi sintakso kode',\n                highlightLine: 'Označi številko vrstice, npr.: 1,3-5'\n            },\n            tr: {\n                highlight: 'Kod sözdizimini vurgula',\n                highlightLine: 'Vurgu çizgileri, örneğin: 1,3-5'\n            }\n            // jshint camelcase:true\n        },\n        // Add our plugin to Trumbowyg registered plugins\n        plugins: {\n            highlight: {\n                init: function (trumbowyg) {\n                    // Fill current Trumbowyg instance with my plugin default options\n                    trumbowyg.o.plugins.highlight = $.extend(true, {},\n                        defaultOptions,\n                        trumbowyg.o.plugins.highlight || {}\n                    );\n\n                    // If my plugin is a button\n                    trumbowyg.addBtnDef('highlight', buildButtonDef(trumbowyg));\n                }\n            }\n        }\n    });\n})(jQuery, Prism);\n"
  },
  {
    "path": "plugins/highlight/ui/sass/trumbowyg.highlight.scss",
    "content": ".trumbowyg-highlight-form-group {\n    margin: 15px 10px;\n\n    .trumbowyg-highlight-form-control {\n        width: 100%;\n        border: 1px solid #DEDEDE;\n        font-size: 14px;\n        padding: 7px;\n\n        &.code {\n            height: 200px;\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/history/trumbowyg.history.js",
    "content": "/*/* ===========================================================\n * trumbowyg.history.js v1.0\n * history plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Sven Dunemann [dunemann@forelabs.eu]\n */\n\n(function ($) {\n    'use strict';\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            history: {\n                destroy: function (t) {\n                    t.$c.off('tbwinit.history tbwchange.history');\n                },\n                init: function (t) {\n                    t.o.plugins.history = $.extend(true, {\n                        _stack: [],\n                        _index: -1,\n                        _focusEl: undefined\n                    }, t.o.plugins.history || {});\n\n                    var btnBuildDefRedo = {\n                        title: t.lang.redo,\n                        ico: 'redo',\n                        key: 'Y',\n                        fn: function () {\n                            if (t.o.plugins.history._index < t.o.plugins.history._stack.length - 1) {\n                                t.o.plugins.history._index += 1;\n                                var index = t.o.plugins.history._index;\n                                var newState = t.o.plugins.history._stack[index];\n\n                                t.execCmd('html', newState);\n                                // because of some semantic optimisations we have to save the state back\n                                // to history\n                                t.o.plugins.history._stack[index] = t.$ed.html();\n\n                                carretToEnd();\n                                toggleButtonStates();\n                            }\n                        }\n                    };\n\n                    var btnBuildDefUndo = {\n                        title: t.lang.undo,\n                        ico: 'undo',\n                        key: 'Z',\n                        fn: function () {\n                            if (t.o.plugins.history._index > 0) {\n                                t.o.plugins.history._index -= 1;\n                                var index = t.o.plugins.history._index,\n                                    newState = t.o.plugins.history._stack[index];\n\n                                t.execCmd('html', newState);\n                                // because of some semantic optimisations we have to save the state back\n                                // to history\n                                t.o.plugins.history._stack[index] = t.$ed.html();\n\n                                carretToEnd();\n                                toggleButtonStates();\n                            }\n                        }\n                    };\n\n                    var pushToHistory = function () {\n                        var index = t.o.plugins.history._index,\n                            stack = t.o.plugins.history._stack,\n                            latestState = stack.slice(-1)[0] || '<p></p>',\n                            prevState = stack[index],\n                            newState = t.$ed.html(),\n                            focusEl = t.doc.getSelection().focusNode,\n                            focusElText = '',\n                            latestStateTagsList,\n                            newStateTagsList,\n                            prevFocusEl = t.o.plugins.history._focusEl;\n\n                        latestStateTagsList = $('<div>' + latestState + '</div>').find('*').map(function () {\n                            return this.localName;\n                        });\n                        newStateTagsList = $('<div>' + newState + '</div>').find('*').map(function () {\n                            return this.localName;\n                        });\n                        if (focusEl) {\n                            t.o.plugins.history._focusEl = focusEl;\n                            focusElText = focusEl.outerHTML || focusEl.textContent;\n                        }\n\n                        if (newState !== prevState) {\n                            // a new stack entry is defined when current insert ends on a whitespace character\n                            // or count of node elements has been changed\n                            // or focused element differs from previous one\n                            if (focusElText.slice(-1).match(/\\s/) ||\n                                !arraysAreIdentical(latestStateTagsList, newStateTagsList) ||\n                                t.o.plugins.history._index <= 0 || focusEl !== prevFocusEl)\n                            {\n                                t.o.plugins.history._index += 1;\n                                // remove newer entries in history when something new was added\n                                // because timeline was changes with interaction\n                                t.o.plugins.history._stack = stack.slice(\n                                    0, t.o.plugins.history._index\n                                );\n                                // now add new state to modified history\n                                t.o.plugins.history._stack.push(newState);\n                            } else {\n                                // modify last stack entry\n                                t.o.plugins.history._stack[index] = newState;\n                            }\n\n                            toggleButtonStates();\n                        }\n                    };\n\n                    var toggleButtonStates = function () {\n                        var index = t.o.plugins.history._index,\n                            stackSize = t.o.plugins.history._stack.length,\n                            undoState = (index > 0),\n                            redoState = (stackSize !== 0 && index !== stackSize - 1);\n\n                        toggleButtonState('historyUndo', undoState);\n                        toggleButtonState('historyRedo', redoState);\n                    };\n\n                    var toggleButtonState = function (btn, enable) {\n                        var button = t.$box.find('.trumbowyg-' + btn + '-button');\n\n                        if (enable) {\n                            button.removeClass('trumbowyg-disable');\n                        } else if (!button.hasClass('trumbowyg-disable')) {\n                            button.addClass('trumbowyg-disable');\n                        }\n                    };\n\n                    var arraysAreIdentical = function (a, b) {\n                        if (a === b) {\n                            return true;\n                        }\n                        if (a == null || b == null) {\n                            return false;\n                        }\n                        if (a.length !== b.length) {\n                            return false;\n                        }\n\n                        for (var i = 0; i < a.length; i += 1) {\n                            if (a[i] !== b[i]) {\n                                return false;\n                            }\n                        }\n                        return true;\n                    };\n\n                    var carretToEnd = function () {\n                        var node = t.doc.getSelection().focusNode,\n                            range = t.doc.createRange();\n\n                        if (node.childNodes.length > 0) {\n                            range.setStartAfter(node.childNodes[node.childNodes.length - 1]);\n                            range.setEndAfter(node.childNodes[node.childNodes.length - 1]);\n                            t.doc.getSelection().removeAllRanges();\n                            t.doc.getSelection().addRange(range);\n                        }\n                    };\n\n                    t.$c.on('tbwinit.history tbwchange.history', pushToHistory);\n\n                    t.addBtnDef('historyRedo', btnBuildDefRedo);\n                    t.addBtnDef('historyUndo', btnBuildDefUndo);\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/indent/trumbowyg.indent.js",
    "content": "/* ===========================================================\n * trumbowyg.indent.js v1.0\n * Indent or Outdent plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Fabacks\n *          Website : https://github.com/Fabacks\n */\n\n(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                indent: 'Indent',\n                outdent: 'Outdent'\n            },\n            az: {\n                indent: 'Girinti',\n                outdent: 'Çıxıntı'\n            },\n            by: {\n                indent: 'Водступ',\n                outdent: 'Выступ'\n            },\n            de: {\n                indent: 'Einzug vergrößern',\n                outdent: 'Einzug verkleinern'\n            },\n            et: {\n                indent: 'Taande suurendamine',\n                outdent: 'Taande vähendamine'\n            },\n            fr: {\n                indent: 'Augmenter le retrait',\n                outdent: 'Diminuer le retrait'\n            },\n            pt_br: {\n                indent: 'Aumentar Recuo',\n                outdent: 'Diminuir Recuo'\n            },\n            ru: {\n                indent: 'Отступ',\n                outdent: 'Выступ'\n            },\n            sl: {\n                indent: 'Povečaj zamik',\n                outdent: 'Zmanjšaj zamik'\n            },\n            tr: {\n                indent: 'Girinti',\n                outdent: 'Çıkıntı'\n            }\n            // jshint camelcase:true\n        }\n    });\n\n    // Adds the extra button definition\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            paragraph: {\n                init: function (trumbowyg) {\n                    var indentBtnDef = {\n                        fn: 'indent',\n                        title: trumbowyg.lang.indent,\n                        isSupported: function () {\n                            return !!document.queryCommandSupported && !!document.queryCommandSupported('indent');\n                        },\n                        ico: 'indent'\n                    };\n\n                    var outdentBtnDef = {\n                        fn: 'outdent',\n                        title: trumbowyg.lang.outdent,\n                        isSupported: function () {\n                            return !!document.queryCommandSupported && !!document.queryCommandSupported('outdent');\n                        },\n                        ico: 'outdent'\n                    };\n\n                    trumbowyg.addBtnDef('indent', indentBtnDef);\n                    trumbowyg.addBtnDef('outdent', outdentBtnDef);\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/insertaudio/trumbowyg.insertaudio.js",
    "content": "﻿/*/* ===========================================================\n * trumbowyg.insertaudio.js v1.0\n * InsertAudio plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Adam Hess (AdamHess)\n */\n\n(function ($) {\n    'use strict';\n\n    var insertAudioOptions = {\n        src: {\n            label: 'URL',\n            required: true\n        },\n        autoplay: {\n            label: 'AutoPlay',\n            required: false,\n            type: 'checkbox'\n        },\n        muted: {\n            label: 'Muted',\n            required: false,\n            type: 'checkbox'\n        },\n        preload: {\n            label: 'preload options',\n            required: false\n        }\n    };\n\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                insertAudio: 'Insert Audio'\n            },\n            az: {\n                insertAudio: 'Səs yerləşdir'\n            },\n            by: {\n                insertAudio: 'Уставіць аўдыё'\n            },\n            ca: {\n                insertAudio: 'Inserir Audio'\n            },\n            da: {\n                insertAudio: 'Indsæt lyd'\n            },\n            de: {\n                insertAudio: 'Audio einfügen'\n            },\n            es: {\n                insertAudio: 'Insertar Audio'\n            },\n            et: {\n                insertAudio: 'Lisa helifail'\n            },\n            fr: {\n                insertAudio: 'Insérer un son'\n            },\n            hu: {\n                insertAudio: 'Audio beszúrás'\n            },\n            ja: {\n                insertAudio: '音声の挿入'\n            },\n            ko: {\n                insertAudio: '소리 넣기'\n            },\n            pt_br: {\n                insertAudio: 'Inserir áudio'\n            },\n            ru: {\n                insertAudio: 'Вставить аудио'\n            },\n            sl: {\n                insertAudio: 'Vstavi zvočno datoteko'\n            },\n            tr: {\n                insertAudio: 'Ses Ekle'\n            },\n            // jshint camelcase:true\n        },\n        plugins: {\n            insertAudio: {\n                init: function (trumbowyg) {\n                    var btnDef = {\n                        fn: function () {\n                            var insertAudioCallback = function (v) {\n                                // controls should always be show otherwise the audio will\n                                // be invisible defeating the point of a wysiwyg\n                                var html = '<audio controls';\n                                if (v.src) {\n                                    html += ' src=\\'' + v.src + '\\'';\n                                }\n                                if (v.autoplay) {\n                                    html += ' autoplay';\n                                }\n                                if (v.muted) {\n                                    html += ' muted';\n                                }\n                                if (v.preload) {\n                                    html += ' preload=\\'' + v + '\\'';\n                                }\n                                html += '></audio>';\n                                var node = $(html)[0];\n                                trumbowyg.range.deleteContents();\n                                trumbowyg.range.insertNode(node);\n                                return true;\n                            };\n\n                            trumbowyg.openModalInsert(trumbowyg.lang.insertAudio, insertAudioOptions, insertAudioCallback);\n                        }\n                    };\n\n                    trumbowyg.addBtnDef('insertAudio', btnDef);\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/lineheight/trumbowyg.lineheight.js",
    "content": "(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                lineheight: 'Line height',\n                lineheights: {\n                    '0.9': 'Small',\n                    'normal': 'Regular',\n                    '1.5': 'Large',\n                    '2.0': 'Extra large'\n                }\n            },\n            az: {\n                lineheight: 'Sətir yüksəkliyi',\n                lineheights: {\n                    '0.9': 'Kiçik',\n                    'normal': 'Normal',\n                    '1.5': 'Böyük',\n                    '2.0': 'Daha böyük'\n                }\n            },\n            by: {\n                lineheight: 'Міжрадковы інтэрвал',\n                lineheights: {\n                    '0.9': 'Маленькі',\n                    'normal': 'Звычайны',\n                    '1.5': 'Вялікі',\n                    '2.0': 'Вельмі вялікі'\n                }\n            },\n            da: {\n                lineheight: 'Linjehøjde',\n                lineheights: {\n                    '0.9': 'Lille',\n                    'normal': 'Normal',\n                    '1.5': 'Stor',\n                    '2.0': 'Ekstra stor'\n                }\n            },\n            de: {\n                lineheight: 'Zeilenhöhe',\n                lineheights: {\n                    '0.9': 'Klein',\n                    'normal': 'Normal',\n                    '1.5': 'Groß',\n                    '2.0': 'Sehr groß'\n                }\n            },\n            et: {\n                lineheight: 'Reavahe',\n                lineheights: {\n                    '0.9': 'Väike',\n                    'normal': 'Tavaline',\n                    '1.5': 'Suur',\n                    '2.0': 'Väga suur'\n                }\n            },\n            fr: {\n                lineheight: 'Hauteur de ligne',\n                lineheights: {\n                    '0.9': 'Petite',\n                    'normal': 'Normale',\n                    '1.5': 'Grande',\n                    '2.0': 'Très grande'\n                }\n            },\n            hu: {\n                lineheight: 'Line height',\n                lineheights: {\n                    '0.9': 'Small',\n                    'normal': 'Regular',\n                    '1.5': 'Large',\n                    '2.0': 'Extra large'\n                }\n            },\n            it: {\n                lineheight: 'Altezza linea',\n                lineheights: {\n                    '0.9': 'Bassa',\n                    'normal': 'Normale',\n                    '1.5': 'Alta',\n                    '2.0': 'Molto alta'\n                }\n            },\n            ko: {\n                lineheight: '줄 간격',\n                lineheights: {\n                    '0.9': '좁게',\n                    'normal': '보통',\n                    '1.5': '넓게',\n                    '2.0': '아주 넓게'\n                }\n            },\n            nl: {\n                lineheight: 'Regelhoogte',\n                lineheights: {\n                    '0.9': 'Klein',\n                    'normal': 'Normaal',\n                    '1.5': 'Groot',\n                    '2.0': 'Extra groot'\n                }\n            },\n            pt_br: {\n                lineheight: 'Altura de linha',\n                lineheights: {\n                    '0.9': 'Pequena',\n                    'normal': 'Regular',\n                    '1.5': 'Grande',\n                    '2.0': 'Extra grande'\n                }\n            },\n            ru: {\n                lineheight: 'Межстрочный интервал',\n                lineheights: {\n                    '0.9': 'Маленький',\n                    'normal': 'Обычный',\n                    '1.5': 'Большой',\n                    '2.0': 'Очень большой'\n                }\n            },\n            sl: {\n                lineheight: 'Višina vrstice',\n                lineheights: {\n                    '0.9': 'Majhna',\n                    'normal': 'Navadna',\n                    '1.5': 'Velika',\n                    '2.0': 'Ekstra velika'\n                }\n            },\n            tr: {\n                lineheight: 'Satır yüksekliği',\n                lineheights: {\n                    '0.9': 'Küçük',\n                    'normal': 'Normal',\n                    '1.5': 'Büyük',\n                    '2.0': 'Çok Büyük'\n                }\n            },\n            zh_tw: {\n                lineheight: '文字間距',\n                lineheights: {\n                    '0.9': '小',\n                    'normal': '正常',\n                    '1.5': '大',\n                    '2.0': '特大'\n                }\n            }\n        }\n    });\n    // jshint camelcase:true\n\n    var defaultOptions = {\n        sizeList: [\n            '0.9',\n            'normal',\n            '1.5',\n            '2.0'\n        ]\n    };\n\n    // Add dropdown with font sizes\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            lineheight: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.lineheight = $.extend({},\n                        defaultOptions,\n                        trumbowyg.o.plugins.lineheight || {}\n                    );\n\n                    trumbowyg.addBtnDef('lineheight', {\n                        dropdown: buildDropdown(trumbowyg)\n                    });\n                }\n            }\n        }\n    });\n\n    // Build the dropdown\n    function buildDropdown(trumbowyg) {\n        var dropdown = [];\n\n        $.each(trumbowyg.o.plugins.lineheight.sizeList, function (index, size) {\n            trumbowyg.addBtnDef('lineheight_' + size, {\n                text: trumbowyg.lang.lineheights[size] || size,\n                hasIcon: false,\n                fn: function () {\n                    trumbowyg.saveRange();\n                    var text = trumbowyg.getRangeText();\n                    if (text.replace(/\\s/g, '') !== '') {\n                        try {\n                            var parent = getSelectionParentElement();\n                            $(parent).css('lineHeight', size);\n                        } catch (e) {\n                        }\n                    }\n                }\n            });\n            dropdown.push('lineheight_' + size);\n        });\n\n        return dropdown;\n    }\n\n    // Get the selection's parent\n    function getSelectionParentElement() {\n        var parentEl = null,\n            selection;\n        if (window.getSelection) {\n            selection = window.getSelection();\n            if (selection.rangeCount) {\n                parentEl = selection.getRangeAt(0).commonAncestorContainer;\n                if (parentEl.nodeType !== 1) {\n                    parentEl = parentEl.parentNode;\n                }\n            }\n        } else if ((selection = document.selection) && selection.type !== 'Control') {\n            parentEl = selection.createRange().parentElement();\n        }\n        return parentEl;\n    }\n})(jQuery);\n"
  },
  {
    "path": "plugins/mathml/trumbowyg.mathml.js",
    "content": "/* ===========================================================\n * trumbowyg.mathMl.js v1.0\n * MathML plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : loclamor\n */\n\n/* globals MathJax */\n(function ($) {\n    'use strict';\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                mathml: 'Insert Formulas',\n                formulas: 'Formulas',\n                inline: 'Inline'\n            },\n            az: {\n                mathml: 'Düstur əlavə et',\n                formulas: 'Düsturlar',\n                inline: 'Sətir içi'\n            },\n            by: {\n                mathml: 'Уставіць формулу',\n                formulas: 'Формула',\n                inline: 'Inline-элемент'\n            },\n            ca: {\n                mathml: 'Inserir Fórmula',\n                formulas: 'Fórmula',\n                inline: 'En línia'\n            },\n            da: {\n                mathml: 'Indsæt formler',\n                formulas: 'Formler',\n                inline: 'Inline'\n            },\n            de: {\n                mathml: 'Formel einfügen',\n                formulas: 'Formel',\n                inline: 'Innerhalb der Zeile'\n            },\n            es: {\n                mathml: 'Insertar Fórmula',\n                formulas: 'Fórmula',\n                inline: 'En línea'\n            },\n            et: {\n                mathml: 'Sisesta valem',\n                formulas: 'Valemid',\n                inline: 'Teksti sees'\n            },\n            fr: {\n                mathml: 'Inserer une formule',\n                formulas: 'Formule',\n                inline: 'En ligne'\n            },\n            hu: {\n                mathml: 'Formulák beszúrás',\n                formulas: 'Formulák',\n                inline: 'Inline'\n            },\n            ko: {\n                mathml: '수식 넣기',\n                formulas: '수식',\n                inline: '글 안에 넣기'\n            },\n            pt_br: {\n                mathml: 'Inserir fórmulas',\n                formulas: 'Fórmulas',\n                inline: 'Em linha'\n            },\n            ru: {\n                mathml: 'Вставить формулу',\n                formulas: 'Формула',\n                inline: 'Строчный элемент'\n            },\n            sl: {\n                mathml: 'Vstavi matematični izraz',\n                formulas: 'Formula',\n                inline: 'V vrstici'\n            },\n            tr: {\n                mathml: 'Formül Ekle',\n                formulas: 'Formüller',\n                inline: 'Satır içi'\n            },\n            zh_tw: {\n                mathml: '插入方程式',\n                formulas: '方程式',\n                inline: '內嵌'\n            },\n        },\n        // jshint camelcase:true\n\n        plugins: {\n            mathml: {\n                init: function (trumbowyg) {\n                    var mathMlOptions = {\n                        formulas: {\n                            label: trumbowyg.lang.formulas,\n                            required: true,\n                            value: ''\n                        },\n                        inline: {\n                            label: trumbowyg.lang.inline,\n                            attributes: {\n                                checked: true\n                            },\n                            type: 'checkbox',\n                            required: false,\n                        }\n                    };\n\n                    var mathmlCallback = function (v) {\n                        var delimiter = v.inline ? '$' : '$$';\n                        if (trumbowyg.currentMathNode) {\n                            $(trumbowyg.currentMathNode)\n                                .html(delimiter + ' ' + v.formulas + ' ' + delimiter)\n                                .attr('formulas', v.formulas)\n                                .attr('inline', (v.inline ? 'true' : 'false'));\n                        } else {\n                            var html = '<span contenteditable=\"false\" formulas=\"' + v.formulas + '\" inline=\"' + (v.inline ? 'true' : 'false') + '\" >' + delimiter + ' ' + v.formulas + ' ' + delimiter + '</span>';\n                            var node = $(html)[0];\n                            node.onclick = openModal;\n\n                            trumbowyg.range.deleteContents();\n                            trumbowyg.range.insertNode(node);\n                        }\n\n                        trumbowyg.currentMathNode = false;\n                        MathJax.Hub.Queue(['Typeset', MathJax.Hub]);\n                        return true;\n                    };\n\n                    var openModal = function () {\n                        trumbowyg.currentMathNode = this;\n                        mathMlOptions.formulas.value = $(this).attr('formulas');\n\n                        if ($(this).attr('inline') === 'true') {\n                            mathMlOptions.inline.attributes.checked = true;\n                        } else {\n                            delete mathMlOptions.inline.attributes.checked;\n                        }\n\n                        trumbowyg.openModalInsert(trumbowyg.lang.mathml, mathMlOptions, mathmlCallback);\n                    };\n\n                    var btnDef = {\n                        fn: function () {\n                            trumbowyg.saveRange();\n\n                            mathMlOptions.formulas.value = trumbowyg.getRangeText();\n                            mathMlOptions.inline.attributes.checked = true;\n                            trumbowyg.openModalInsert(trumbowyg.lang.mathml, mathMlOptions, mathmlCallback);\n                        }\n                    };\n\n                    trumbowyg.$ta.on('tbwinit', function () {\n                        var nodes = trumbowyg.$ed.find('[formulas]');\n\n                        nodes.each(function (i, elem) {\n                            elem.onclick = openModal;\n                        });\n                    });\n\n                    trumbowyg.addBtnDef('mathml', btnDef);\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/mathml/ui/sass/trumbowyg.mathml.scss",
    "content": "[formulas] {\n    position: relative;\n    display: inline-block;\n    pointer-events: none;\n\n    &[inline=\"false\"] {\n        display: block;\n        width: 100%;\n    }\n\n    &::after {\n        content: '\\270E';\n        position: absolute;\n        top: 0;\n        right: 0;\n        bottom: 0;\n        left: 0;\n        opacity: 0;\n        background-color: rgba(255, 255, 255, 0.83);\n        box-shadow: 0 0 5px 5px rgba(255, 255, 255, 0.83);\n        cursor: pointer;\n        pointer-events: auto;\n    }\n\n    &:hover {\n        &::after {\n            opacity: 1;\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mention/trumbowyg.mention.js",
    "content": "/* ===========================================================\n * trumbowyg.mention.js v0.1\n * Mention plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Viper\n *          Github: https://github.com/Globulopolis\n *          Website: http://киноархив.com\n */\n\n(function ($) {\n    'use strict';\n\n    var defaultOptions = {\n        source: [],\n        formatDropdownItem: formatDropdownItem,\n        formatResult: formatResult\n    };\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                mention: 'Mention'\n            },\n            az: {\n                mention: 'Bildirmək'\n            },\n            by: {\n                mention: 'Згадаць'\n            },\n            da: {\n                mention: 'Nævn'\n            },\n            de: {\n                mention: 'Erwähnung'\n            },\n            et: {\n                mention: 'Maini'\n            },\n            fr: {\n                mention: 'Mentionner'\n            },\n            hu: {\n                mention: 'Említ'\n            },\n            ko: {\n                mention: '언급'\n            },\n            pt_br: {\n                mention: 'Menção'\n            },\n            ru: {\n                mention: 'Упомянуть'\n            },\n            sl: {\n                mention: 'Omeni'\n            },\n            tr: {\n                mention: 'Bahset'\n            },\n            zh_tw: {\n                mention: '標記'\n            },\n            // jshint camelcase:true\n        },\n\n        plugins: {\n            mention: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.mention = $.extend(true, {}, defaultOptions, trumbowyg.o.plugins.mention || {});\n\n                    var btnDef = {\n                        dropdown: buildDropdown(trumbowyg.o.plugins.mention.source, trumbowyg)\n                    };\n\n                    trumbowyg.addBtnDef('mention', btnDef);\n                }\n            }\n        }\n    });\n\n    /**\n     * Build dropdown list\n     *\n     * @param {Array}   items      Items\n     * @param {object}  trumbowyg  Editor\n     *\n     * @return {Array}\n     */\n    function buildDropdown(items, trumbowyg) {\n        var dropdown = [];\n\n        $.each(items, function (i, item) {\n            var btn = 'mention-' + i,\n                btnDef = {\n                    hasIcon: false,\n                    text: trumbowyg.o.plugins.mention.formatDropdownItem(item),\n                    fn: function () {\n                        trumbowyg.execCmd('insertHTML', trumbowyg.o.plugins.mention.formatResult(item));\n\n                        return true;\n                    }\n                };\n\n            trumbowyg.addBtnDef(btn, btnDef);\n            dropdown.push(btn);\n        });\n\n        return dropdown;\n    }\n\n    /**\n     * Format item in dropdown.\n     *\n     * @param   {object}  item  Item object.\n     *\n     * @return  {string}\n     */\n    function formatDropdownItem(item) {\n        return item.login;\n    }\n\n    /**\n     * Format result pasted in editor.\n     *\n     * @param   {object}  item  Item object.\n     *\n     * @return  {string}\n     */\n    function formatResult(item) {\n        return '@' + item.login + ' ';\n    }\n})(jQuery);\n"
  },
  {
    "path": "plugins/mention/ui/sass/trumbowyg.mention.scss",
    "content": ".trumbowyg-dropdown-mention {\n    button {\n        position: relative;\n        white-space: nowrap;\n\n        &:after {\n            content: \"\";\n            position: absolute;\n            top: 0;\n            right: 0;\n            width: 15%;\n            height: 100%;\n            background-size: 100%;\n            background-image: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, #ffffff 80%, #ffffff 100%);\n            pointer-events: none;\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/noembed/trumbowyg.noembed.js",
    "content": "/* ===========================================================\n * trumbowyg.noembed.js v1.0\n * noEmbed plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Jake Johns (jakejohns)\n */\n\n/* global AbortSignal:true */\n(function ($) {\n    'use strict';\n\n    var defaultOptions = {\n        proxy: 'https://noembed.com/embed?nowrap=on',\n        urlFiled: 'url',\n        data: [],\n        success: undefined,\n        error: undefined\n    };\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                noembed: 'Noembed',\n                noembedError: 'Error'\n            },\n            az: {\n                noembed: 'Noembed',\n                noembedError: 'Xəta'\n            },\n            by: {\n                noembedError: 'Памылка'\n            },\n            cs: {\n                noembedError: 'Chyba'\n            },\n            da: {\n                noembedError: 'Fejl'\n            },\n            de: {\n                noembed: 'Noembed',\n                noembedError: 'Fehler'\n            },\n            et: {\n                noembed: 'Noembed',\n                noembedError: 'Viga'\n            },\n            fr: {\n                noembedError: 'Erreur'\n            },\n            hu: {\n                noembed: 'Noembed',\n                noembedError: 'Hiba'\n            },\n            ja: {\n                noembedError: 'エラー'\n            },\n            ko: {\n                noembed: 'oEmbed 넣기',\n                noembedError: '에러'\n            },\n            pt_br: {\n                noembed: 'Incorporar',\n                noembedError: 'Erro'\n            },\n            ru: {\n                noembedError: 'Ошибка'\n            },\n            sl: {\n                noembed: 'Noembed',\n                noembedError: 'Napaka'\n            },\n            sk: {\n                noembedError: 'Chyba'\n            },\n            tr: {\n                noembedError: 'Hata'\n            },\n            zh_tw: {\n                noembed: '插入影片',\n                noembedError: '錯誤'\n            },\n            // jshint camelcase:true\n        },\n\n        plugins: {\n            noembed: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.noembed = $.extend(true, {}, defaultOptions, trumbowyg.o.plugins.noembed || {});\n\n                    var btnDef = {\n                        fn: function () {\n                            var $modal = trumbowyg.openModalInsert(\n                                // Title\n                                trumbowyg.lang.noembed,\n\n                                // Fields\n                                {\n                                    url: {\n                                        label: 'URL',\n                                        required: true\n                                    }\n                                },\n\n                                // Callback\n                                function (data) {\n                                    // Build request URL\n                                    var requestUrl = new URL(trumbowyg.o.plugins.noembed.proxy);\n                                    Object.keys(data).forEach((key) => {\n                                        requestUrl.searchParams.append(key, data[key].trim());\n                                    });\n\n                                    // Launch async request\n                                    fetch(requestUrl, {\n                                        method: 'GET',\n                                        cache: 'no-cache',\n                                        signal: AbortSignal.timeout(2000)\n                                    }).then((response) => {\n                                        if (trumbowyg.o.plugins.noembed.success) {\n                                            trumbowyg.o.plugins.noembed.success(data, trumbowyg, $modal);\n                                            return;\n                                        }\n\n                                        return response.json().then((json) => {\n                                            if (!json.html) {\n                                                trumbowyg.addErrorOnModalField(\n                                                    $('input[type=text]', $modal),\n                                                    json.error\n                                                );\n                                                return;\n                                            }\n\n                                            trumbowyg.execCmd('insertHTML', json.html);\n                                            setTimeout(function () {\n                                                trumbowyg.closeModal();\n                                            }, 250);\n                                        });\n                                    }).catch((...args) => {\n                                        if (trumbowyg.o.plugins.noembed.error) {\n                                            trumbowyg.o.plugins.noembed.error(...args);\n                                            return;\n                                        }\n\n                                        trumbowyg.addErrorOnModalField(\n                                            $('input[type=text]', $modal),\n                                            trumbowyg.lang.noembedError\n                                        );\n                                    });\n                                }\n                            );\n                        }\n                    };\n\n                    trumbowyg.addBtnDef('noembed', btnDef);\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/pasteembed/trumbowyg.pasteembed.js",
    "content": "/* ===========================================================\n * trumbowyg.pasteembed.js v1.0\n * Url paste to iframe with noembed. Plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Max Seelig\n *          Facebook : https://facebook.com/maxse\n *          Website : https://www.maxmade.nl/\n */\n\n/* global AbortSignal:true */\n(function($) {\n    'use strict';\n\n    var defaultOptions = {\n        enabled: true,\n        endpoint: 'https://noembed.com/embed?nowrap=on'\n    };\n\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            pasteEmbed: {\n                init: function(trumbowyg) {\n                    trumbowyg.o.plugins.pasteEmbed = $.extend(true, {}, defaultOptions, trumbowyg.o.plugins.pasteEmbed || {});\n\n                    // Compatibility layer with older 'endpoints' array options\n                    if (Array.isArray(trumbowyg.o.plugins.pasteEmbed.endpoints)) {\n                        trumbowyg.o.plugins.pasteEmbed.endpoint = trumbowyg.o.plugins.pasteEmbed.endpoints[0];\n                    }\n\n                    if (!trumbowyg.o.plugins.pasteEmbed.enabled) {\n                        return;\n                    }\n\n                    trumbowyg.pasteHandlers.push(function(pasteEvent) {\n                        try {\n                            var clipboardData = (pasteEvent.originalEvent || pasteEvent).clipboardData,\n                                pastedData = clipboardData.getData('Text'),\n                                endpoint = trumbowyg.o.plugins.pasteEmbed.endpoint;\n\n                            if (!pastedData.startsWith('http')) {\n                                return;\n                            }\n\n                            pasteEvent.stopPropagation();\n                            pasteEvent.preventDefault();\n\n                            // Build request URL\n                            var requestUrl = new URL(endpoint);\n                            requestUrl.searchParams.append('url', pastedData.trim());\n\n                            // Launch async request\n                            fetch(requestUrl, {\n                                method: 'GET',\n                                cache: 'no-cache',\n                                signal: AbortSignal.timeout(2000)\n                            }).then((response) => {\n                                return response.json().then((json) => {\n                                    return json.html;\n                                });\n                            }).catch(() => {\n                                return undefined;\n                            }).then((content) => {\n                                if (content === undefined) {\n                                    content = $('<a>', {\n                                        href: pastedData,\n                                        text: pastedData\n                                    })[0].outerHTML;\n                                }\n\n                                trumbowyg.execCmd('insertHTML', content);\n                            });\n                        } catch (c) {}\n                    });\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/pasteimage/trumbowyg.pasteimage.js",
    "content": "/* ===========================================================\n * trumbowyg.pasteimage.js v1.0\n * Basic base64 paste plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Alexandre Demode (Alex-D)\n *          Twitter : @AlexandreDemode\n *          Website : alex-d.fr\n */\n\n(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            pasteImage: {\n                init: function (trumbowyg) {\n                    trumbowyg.pasteHandlers.push(function (pasteEvent) {\n                        try {\n                            var items = (pasteEvent.originalEvent || pasteEvent).clipboardData.items,\n                                mustPreventDefault = false,\n                                reader;\n\n                            for (var i = items.length - 1; i >= 0; i -= 1) {\n                                if (items[i].type.match(/^image\\//)) {\n                                    reader = new FileReader();\n                                    /* jshint -W083 */\n                                    reader.onloadend = function (event) {\n                                        trumbowyg.execCmd('insertImage', event.target.result, false, true);\n                                    };\n                                    /* jshint +W083 */\n                                    reader.readAsDataURL(items[i].getAsFile());\n\n                                    mustPreventDefault = true;\n                                }\n                            }\n\n                            if (mustPreventDefault) {\n                                pasteEvent.stopPropagation();\n                                pasteEvent.preventDefault();\n                            }\n                        } catch (c) {\n                        }\n                    });\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/preformatted/trumbowyg.preformatted.js",
    "content": "/* ===========================================================\n * trumbowyg.preformatted.js v1.0\n * Preformatted plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Casella Edoardo (Civile)\n */\n\n\n(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                preformatted: 'Code sample <pre>'\n            },\n            az: {\n                preformatted: 'Kod nümunəsi <pre>'\n            },\n            by: {\n                preformatted: 'Прыклад кода <pre>'\n            },\n            da: {\n                preformatted: 'Præformateret <pre>'\n            },\n            de: {\n                preformatted: 'Code-Beispiel <pre>'\n            },\n            et: {\n                preformatted: 'Eelvormindatud tekst <pre>'\n            },\n            fr: {\n                preformatted: 'Exemple de code <pre>'\n            },\n            hu: {\n                preformatted: 'Kód minta <pre>'\n            },\n            it: {\n                preformatted: 'Codice <pre>'\n            },\n            ja: {\n                preformatted: 'コードサンプル <pre>'\n            },\n            ko: {\n                preformatted: '코드 예제 <pre>'\n            },\n            pt_br: {\n                preformatted: 'Exemple de código <pre>'\n            },\n            ru: {\n                preformatted: 'Пример кода <pre>'\n            },\n            sl: {\n                preformatted: 'Vstavi neformatiran tekst <pre>'\n            },\n            tr: {\n                preformatted: 'Kod örneği <pre>'\n            },\n            zh_cn: {\n                preformatted: '代码示例 <pre>'\n            },\n            zh_tw: {\n                preformatted: '代碼範例 <pre>'\n            },\n        },\n        // jshint camelcase:true\n\n        plugins: {\n            preformatted: {\n                init: function (trumbowyg) {\n                    var btnDef = {\n                        fn: function () {\n                            trumbowyg.saveRange();\n                            var text = trumbowyg.getRangeText();\n                            if (text.replace(/\\s/g, '') !== '') {\n                                try {\n                                    var curtag = getSelectionParentElement().tagName.toLowerCase();\n                                    if (curtag === 'code' || curtag === 'pre') {\n                                        return unwrapCode();\n                                    }\n                                    else {\n                                        trumbowyg.execCmd('insertHTML', '<pre><code>' + strip(text) + '</code></pre>');\n                                    }\n                                } catch (e) {\n                                }\n                            }\n                        },\n                        tag: 'pre'\n                    };\n\n                    trumbowyg.addBtnDef('preformatted', btnDef);\n                }\n            }\n        }\n    });\n\n    /*\n     * GetSelectionParentElement\n     */\n    function getSelectionParentElement() {\n        var parentEl = null,\n            selection;\n\n        if (window.getSelection) {\n            selection = window.getSelection();\n            if (selection.rangeCount) {\n                parentEl = selection.getRangeAt(0).commonAncestorContainer;\n                if (parentEl.nodeType !== 1) {\n                    parentEl = parentEl.parentNode;\n                }\n            }\n        } else if ((selection = document.selection) && selection.type !== 'Control') {\n            parentEl = selection.createRange().parentElement();\n        }\n\n        return parentEl;\n    }\n\n    /*\n     * Strip\n     * returns a text without HTML tags\n     */\n    function strip(html) {\n        var tmp = document.createElement('DIV');\n        tmp.innerHTML = html;\n        return tmp.textContent || tmp.innerText || '';\n    }\n\n    /*\n     * UnwrapCode\n     * ADD/FIX: to improve, works but can be better\n     * \"paranoic\" solution\n     */\n    function unwrapCode() {\n        var container = null;\n\n        if (document.selection) { //for IE\n            container = document.selection.createRange().parentElement();\n        } else {\n            var select = window.getSelection();\n            if (select.rangeCount > 0) {\n                container = select.getRangeAt(0).startContainer.parentNode;\n            }\n        }\n\n        //'paranoic' unwrap\n        var ispre = $(container).contents().closest('pre').length;\n        var iscode = $(container).contents().closest('code').length;\n\n        if (ispre && iscode) {\n            $(container).contents().unwrap('code').unwrap('pre');\n        } else if (ispre) {\n            $(container).contents().unwrap('pre');\n        } else if (iscode) {\n            $(container).contents().unwrap('code');\n        }\n    }\n})(jQuery);\n"
  },
  {
    "path": "plugins/resizimg/trumbowyg.resizimg.js",
    "content": "; (function ($) {\n    'use strict';\n\n    var defaultOptions = {\n        minSize: 32,\n        step: 4\n    };\n\n    function preventDefault(e) {\n        e.stopPropagation();\n        e.preventDefault();\n    }\n\n    var ResizeWithCanvas = function (trumbowyg) {\n        // variable to create canvas and save img in resize mode\n        this.resizeCanvas = document.createElement('canvas');\n        // to allow canvas to get focus\n        this.resizeCanvas.setAttribute('tabindex', '0');\n        this.resizeCanvas.id = 'trumbowyg-resizimg-' + (+new Date());\n        this.ctx = null;\n        this.resizeImg = null;\n\n        this.pressEscape = function (obj) {\n            obj.reset();\n        };\n        this.pressBackspaceOrDelete = function (obj) {\n            $(obj.resizeCanvas).remove();\n            obj.resizeImg = null;\n            if (trumbowyg !== null){\n                trumbowyg.syncCode();\n                // notify changes\n                trumbowyg.$c.trigger('tbwchange');\n            }\n        };\n\n        // PRIVATE FUNCTION\n        var focusedNow = false;\n        var isCursorSeResize = false;\n\n        // calculate offset to change mouse over square in the canvas\n        var offsetX, offsetY;\n        var reOffset = function (canvas) {\n            var BB = canvas.getBoundingClientRect();\n            offsetX = BB.left;\n            offsetY = BB.top;\n        };\n\n        var updateCanvas = function (canvas, ctx, img, canvasWidth, canvasHeight) {\n            ctx.translate(0.5, 0.5);\n            ctx.lineWidth = 1;\n\n            // image\n            ctx.drawImage(img, 5, 5, canvasWidth - 10, canvasHeight - 10);\n\n            // border\n            ctx.beginPath();\n            ctx.rect(5, 5, canvasWidth - 10, canvasHeight - 10);\n            ctx.stroke();\n\n            // square in the angle\n            ctx.beginPath();\n            ctx.fillStyle = 'rgb(255, 255, 255)';\n            ctx.rect(canvasWidth - 10, canvasHeight - 10, 9, 9);\n            ctx.fill();\n            ctx.stroke();\n\n            // get the offset to change the mouse cursor\n            reOffset(canvas);\n\n            return ctx;\n        };\n\n        // PUBLIC FUNCTION\n        // necessary to correctly print cursor over square. Called once for instance. Useless with trumbowyg.\n        this.init = function () {\n            var _this = this;\n            $(window).on('scroll resize', function () {\n                _this.reCalcOffset();\n            });\n        };\n\n        this.reCalcOffset = function () {\n            reOffset(this.resizeCanvas);\n        };\n\n        this.canvasId = function () {\n            return this.resizeCanvas.id;\n        };\n\n        this.isActive = function () {\n            return this.resizeImg !== null;\n        };\n\n        this.isFocusedNow = function () {\n            return focusedNow;\n        };\n\n        this.blurNow = function () {\n            focusedNow = false;\n        };\n\n        // restore image in the HTML of the editor\n        this.reset = function () {\n            if (this.resizeImg === null) {\n                return;\n            }\n\n            // set style of image to avoid issue on resize because this attribute have priority over width and height attribute\n            this.resizeImg.setAttribute('style', 'width: 100%; max-width: ' + (this.resizeCanvas.clientWidth - 10) + 'px; height: auto; max-height: ' + (this.resizeCanvas.clientHeight - 10) + 'px;');\n\n            $(this.resizeCanvas).replaceWith($(this.resizeImg));\n\n            // reset canvas style\n            this.resizeCanvas.removeAttribute('style');\n            this.resizeImg = null;\n        };\n\n        // setup canvas with points and border to allow the resizing operation\n        this.setup = function (img, resizableOptions) {\n            this.resizeImg = img;\n\n            if (!this.resizeCanvas.getContext) {\n                return false;\n            }\n\n            focusedNow = true;\n\n            // draw canvas\n            this.resizeCanvas.width = $(this.resizeImg).width() + 10;\n            this.resizeCanvas.height = $(this.resizeImg).height() + 10;\n            this.resizeCanvas.style.margin = '-5px';\n            this.ctx = this.resizeCanvas.getContext('2d');\n\n            // replace image with canvas\n            $(this.resizeImg).replaceWith($(this.resizeCanvas));\n\n            updateCanvas(this.resizeCanvas, this.ctx, this.resizeImg, this.resizeCanvas.width, this.resizeCanvas.height);\n\n            // enable resize\n            $(this.resizeCanvas).resizableSafe(resizableOptions)\n                .on('mousedown', preventDefault);\n\n            var _this = this;\n            $(this.resizeCanvas)\n                .on('mousemove', function (e) {\n                    var mouseX = Math.round(e.clientX - offsetX);\n                    var mouseY = Math.round(e.clientY - offsetY);\n\n                    var wasCursorSeResize = isCursorSeResize;\n\n                    _this.ctx.rect(_this.resizeCanvas.width - 10, _this.resizeCanvas.height - 10, 9, 9);\n                    isCursorSeResize = _this.ctx.isPointInPath(mouseX, mouseY);\n                    if (wasCursorSeResize !== isCursorSeResize) {\n                        this.style.cursor = isCursorSeResize ? 'se-resize' : 'default';\n                    }\n                })\n                .on('keydown', function (e) {\n                    if (!_this.isActive()) {\n                        return;\n                    }\n\n                    var x = e.keyCode;\n                    if (x === 27) { // ESC\n                        _this.pressEscape(_this);\n                    } else if (x === 8 || x === 46) { // BACKSPACE or DELETE\n                        _this.pressBackspaceOrDelete(_this);\n                    }\n                })\n                .on('focus', preventDefault)\n                .on('blur', function () {\n                    _this.reset();\n                    // save changes\n                    if (trumbowyg !== null){\n                        trumbowyg.syncCode();\n                        // notify changes\n                        trumbowyg.$c.trigger('tbwchange');\n                    }\n                });\n\n            this.resizeCanvas.focus();\n\n            return true;\n        };\n\n        // update the canvas after the resizing\n        this.refresh = function () {\n            if (!this.resizeCanvas.getContext) {\n                return;\n            }\n\n            this.resizeCanvas.width = this.resizeCanvas.clientWidth;\n            this.resizeCanvas.height = this.resizeCanvas.clientHeight;\n            updateCanvas(this.resizeCanvas, this.ctx, this.resizeImg, this.resizeCanvas.width, this.resizeCanvas.height);\n        };\n    };\n\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            resizimg: {\n                destroyResizable: function () {},\n                init: function (trumbowyg) {\n                    var destroyResizable = this.destroyResizable;\n\n                    // object to interact with canvas\n                    var resizeWithCanvas = new ResizeWithCanvas(trumbowyg);\n\n                    this.destroyResizable = function () {\n                        // clean html code\n                        trumbowyg.$ed.find('canvas.resizable')\n                            .resizableSafe('destroy')\n                            .off('mousedown', preventDefault)\n                            .removeClass('resizable');\n\n                        resizeWithCanvas.reset();\n\n                        trumbowyg.syncCode();\n                    };\n\n                    trumbowyg.o.plugins.resizimg = $.extend(true, {},\n                        defaultOptions,\n                        trumbowyg.o.plugins.resizimg || {},\n                        {\n                            resizable: {\n                                resizeWidth: false,\n                                onDragStart: function (ev, $el) {\n                                    var opt = trumbowyg.o.plugins.resizimg;\n                                    var x = ev.pageX - $el.offset().left;\n                                    var y = ev.pageY - $el.offset().top;\n                                    if (x < $el.width() - opt.minSize || y < $el.height() - opt.minSize) {\n                                        return false;\n                                    }\n                                },\n                                onDrag: function (ev, $el, newWidth, newHeight) {\n                                    var opt = trumbowyg.o.plugins.resizimg;\n                                    if (newHeight < opt.minSize) {\n                                        newHeight = opt.minSize;\n                                    }\n                                    newHeight -= newHeight % opt.step;\n                                    $el.height(newHeight);\n                                    return false;\n                                },\n                                onDragEnd: function () {\n                                    // resize update canvas information\n                                    resizeWithCanvas.refresh();\n                                    trumbowyg.syncCode();\n                                }\n                            }\n                        }\n                    );\n\n                    function initResizable() {\n                        trumbowyg.$ed.find('img')\n                            .off('click')\n                            .on('click', function (e) {\n                                // if I'm already do a resize, reset it\n                                if (resizeWithCanvas.isActive()) {\n                                    resizeWithCanvas.reset();\n                                }\n                                // initialize resize of image\n                                resizeWithCanvas.setup(this, trumbowyg.o.plugins.resizimg.resizable);\n\n                                preventDefault(e);\n                            });\n                    }\n\n                    trumbowyg.$c.on('tbwinit', function () {\n                        initResizable();\n\n                        // disable resize when click on other items\n                        trumbowyg.$ed.on('click', function (e) {\n                            // check if I've clicked out of canvas or image to reset it\n                            if ($(e.target).is('img') || e.target.id === resizeWithCanvas.canvasId()) {\n                                return;\n                            }\n\n                            preventDefault(e);\n                            resizeWithCanvas.reset();\n                            //sync\n                            trumbowyg.syncCode();\n                            // notify changes\n                            trumbowyg.$c.trigger('tbwchange');\n                        });\n\n                        trumbowyg.$ed.on('scroll', function () {\n                            resizeWithCanvas.reCalcOffset();\n                        });\n                    });\n\n                    trumbowyg.$c.on('tbwfocus tbwchange', initResizable);\n                    trumbowyg.$c.on('tbwresize', function () {\n                        resizeWithCanvas.reCalcOffset();\n                    });\n\n                    // Destroy\n                    trumbowyg.$c.on('tbwblur', function () {\n                        // when canvas is created the tbwblur is called\n                        // this code avoid to destroy the canvas that allow the image resizing\n                        if (resizeWithCanvas.isFocusedNow()) {\n                            resizeWithCanvas.blurNow();\n                        } else {\n                            destroyResizable();\n                        }\n                    });\n                },\n                destroy: function () {\n                    this.destroyResizable();\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/ruby/trumbowyg.ruby.js",
    "content": "/* ===========================================================\n * trumbowyg.ruby.js v1.0\n * Ruby text plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author\t: Fathi Anshory (0x00000F5C)\n * Twitter\t: @fscchannl\n * Comment\t: Since I use trumbowyg in my project and required it to insert ruby text, so I thought I can contribute a little. :D\n */\n\n(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                ruby: 'Add ruby text',\n                rubyModal: 'Ruby modal',\n                rubyText: 'Ruby text'\n            },\n            az: {\n                ruby: 'Ruby mətni əlavə et',\n                rubyModal: 'Ruby modal',\n                rubyText: 'Ruby mətni'\n            },\n            by: {\n                ruby: 'Уставіць ruby тэкст',\n                rubyModal: 'Ruby анатацыя',\n                rubyText: 'Ruby тэкст'\n            },\n            da: {\n                ruby: 'Tilføj ruby tekst',\n                rubyModal: 'Ruby modal',\n                rubyText: 'Ruby tekst'\n            },\n            de: {\n                ruby: 'Ruby-Text einfügen',\n                rubyModal: 'Ruby-Modal',\n                rubyText: 'Ruby-Text'\n            },\n            et: {\n                ruby: 'Lisa ruby tekst',\n                rubyModal: 'Ruby modaal',\n                rubyText: 'Ruby tekst'\n            },\n            fr: {\n                ruby: 'Ajouter du texte ruby',\n                rubyModal: 'Modale ruby',\n                rubyText: 'Texte ruby'\n            },\n            hu: {\n                ruby: 'Ruby szöveg hozzáadás',\n                rubyModal: 'Ruby modal',\n                rubyText: 'Ruby szöveg'\n            },\n            id: {\n                ruby: 'Sisipkan teks ruby',\n                rubyModal: 'Modal teks ruby',\n                rubyText: 'Teks ruby'\n            },\n            ko: {\n                ruby: '루비 문자 넣기',\n                rubyModal: '대상 문자',\n                rubyText: '루비 문자'\n            },\n            pt_br: {\n                ruby: 'Adicionar texto ruby',\n                rubyModal: 'Modal ruby',\n                rubyText: 'Texto ruby'\n            },\n            ru: {\n                ruby: 'Вставить ruby текст',\n                rubyModal: 'Ruby аннотация',\n                rubyText: 'Ruby текст'\n            },\n            tr: {\n                ruby: 'Ruby metni ekle',\n                rubyModal: 'Ruby modal',\n                rubyText: 'Ruby metni'\n            },\n            zh_tw: {\n                ruby: '加入 ruby 文字',\n                rubyModal: 'Ruby 彈跳視窗',\n                rubyText: 'Ruby 文字'\n            },\n            // jshint camelcase:true\n        },\n        plugins: {\n            ruby: {\n                init: function (trumbowyg) {\n                    var btnDef = {\n                        fn: function () {\n                            trumbowyg.saveRange();\n                            trumbowyg.openModalInsert(\n                                trumbowyg.lang.ruby,\n                                {\n                                    rubyText: {\n                                        label: trumbowyg.lang.rubyText,\n                                        required: false,\n                                    },\n                                    modal: {\n                                        label: trumbowyg.lang.rubyModal,\n                                        value: trumbowyg.getRangeText(),\n                                        required: true\n                                    }\n                                },\n                                function (v) {\n                                    var node = $('<ruby title=\"' + v.rubyText + '\">' + v.modal + '<rp> (</rp><rt>' + v.rubyText + '</rt><rp>)</rp></ruby>')[0];\n                                    trumbowyg.range.deleteContents();\n                                    trumbowyg.range.insertNode(node);\n                                    trumbowyg.syncCode();\n                                    trumbowyg.$c.trigger('tbwchange');\n                                    return true;\n                                }\n                            );\n                        }\n                    };\n                    trumbowyg.addBtnDef('ruby', btnDef);\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/specialchars/trumbowyg.specialchars.js",
    "content": "/* ===========================================================\n * trumbowyg.specialchars.js v0.99\n * Unicode characters picker plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Renaud Hoyoux (geektortoise)\n*/\n\n(function ($) {\n    'use strict';\n\n    var defaultOptions = {\n        symbolList: [\n            // currencies\n            '0024', '20AC', '00A3', '00A2', '00A5', '00A4', '2030', null,\n            // legal signs\n            '00A9', '00AE', '2122', null,\n            // textual sign\n            '00A7', '00B6', '00C6', '00E6', '0152', '0153', null,\n            '2022', '25CF', '2023', '25B6', '2B29', '25C6', null,\n            //maths\n            '00B1', '00D7', '00F7', '21D2', '21D4', '220F', '2211', '2243', '2264', '2265'\n        ]\n    };\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            en: {\n                specialChars: 'Special characters'\n            },\n            az: {\n                specialChars: 'Xüsusi simvollar'\n            },\n            by: {\n                specialChars: 'Спецыяльныя сімвалы'\n            },\n            de: {\n                specialChars: 'Spezialzeichen'\n            },\n            et: {\n                specialChars: 'Erimärgid'\n            },\n            fr: {\n                specialChars: 'Caractères spéciaux'\n            },\n            hu: {\n                specialChars: 'Speciális karakterek'\n            },\n            ko: {\n                specialChars: '특수문자'\n            },\n            ru: {\n                specialChars: 'Специальные символы'\n            },\n            sl: {\n                specialChars: 'Posebni znaki'\n            },\n            tr: {\n                specialChars: 'Özel karakterler'\n            },\n        },\n        plugins: {\n            specialchars: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.specialchars = trumbowyg.o.plugins.specialchars || defaultOptions;\n                    var specialCharsBtnDef = {\n                        dropdown: buildDropdown(trumbowyg)\n                    };\n\n                    trumbowyg.addBtnDef('specialChars', specialCharsBtnDef);\n                }\n            }\n        }\n    });\n\n    function buildDropdown(trumbowyg) {\n        var dropdown = [];\n        $.each(trumbowyg.o.plugins.specialchars.symbolList, function (i, symbol) {\n            if (symbol === null) {\n                symbol = '&nbsp';\n            } else {\n                symbol = '&#x' + symbol;\n            }\n\n            var btn = symbol.replace(/:/g, ''),\n                defaultSymbolBtnName = 'symbol-' + btn,\n                defaultSymbolBtnDef = {\n                    text: symbol,\n                    hasIcon: false,\n                    fn: function () {\n                        var encodedSymbol = String.fromCodePoint(parseInt(symbol.replace('&#', '0')));\n                        trumbowyg.execCmd('insertText', encodedSymbol);\n                        return true;\n                    }\n                };\n\n            trumbowyg.addBtnDef(defaultSymbolBtnName, defaultSymbolBtnDef);\n            dropdown.push(defaultSymbolBtnName);\n        });\n\n        return dropdown;\n    }\n})(jQuery);\n"
  },
  {
    "path": "plugins/specialchars/ui/sass/trumbowyg.specialchars.scss",
    "content": ".trumbowyg-symbol-\\&nbsp-dropdown-button {\n    display: none !important;\n}\n.trumbowyg-symbol-\\&nbsp-dropdown-button + button {\n    clear: both;\n}\n\n.trumbowyg-dropdown-specialChars {\n    width: 248px;\n    padding: 5px 3px 3px;\n}\n\n.trumbowyg-dropdown-specialChars button {\n    display: block;\n    position: relative;\n    float: left;\n    height: 26px;\n    width: 26px;\n    padding: 0;\n    margin: 2px;\n    line-height: 24px;\n    text-align: center;\n\n    &:hover,\n    &:focus {\n        &::after {\n            display: block;\n            position: absolute;\n            top: -5px;\n            left: -5px;\n            height: 27px;\n            width: 27px;\n            background: inherit;\n            box-shadow: #000 0 0 2px;\n            z-index: 10;\n            background-color: transparent;\n        }\n    }\n}\n\n.trumbowyg .specialChars {\n    width: 22px;\n    height: 22px;\n    display: inline-block;\n}\n"
  },
  {
    "path": "plugins/speechrecognition/trumbowyg.speechrecognition.js",
    "content": "/* ===========================================================\n * trumbowyg.speechrecognition.js v1.0\n * Speech recognition plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Authors :\n *  - Tobias Rohde\n *  - Alexandre Demode (Alex-D)\n * Website : tobiasrohde.de\n */\n(function ($) {\n    'use strict';\n\n    const defaultOptions = {\n        lang: 'en-US'\n    };\n\n    const SpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition;\n\n    function buildButtonDef(trumbowyg) {\n        let btnElement = null;\n        let isRecognizing = false;\n        let $resultTextParagraph = null;\n\n        const recognition = new SpeechRecognition();\n\n        recognition.continuous = true;\n        recognition.interimResults = true;\n        recognition.maxAlternatives = 1; // We only read the first\n\n        recognition.onstart = function () {\n            isRecognizing = true;\n            btnElement.style.color = '#e71d36';\n        };\n\n        recognition.onerror = function () {\n            isRecognizing = false;\n            btnElement.style.removeProperty('color');\n        };\n\n        recognition.onend = function () {\n            isRecognizing = false;\n            btnElement.style.removeProperty('color');\n        };\n\n        recognition.onresult = function (event) {\n            const resultText = [...event.results].map((result) => {\n                return result[0].transcript + (result.isFinal ? '<br>' : '');\n            }).join('');\n            $resultTextParagraph.html(resultText);\n            trumbowyg.range.setEndAfter($resultTextParagraph[0]);\n            trumbowyg.range.collapse();\n            trumbowyg.syncCode();\n        };\n\n        return {\n            isSupported,\n            fn: function () {\n                if (isRecognizing) {\n                    recognition.stop();\n                    return;\n                }\n\n                // Get the actual button to allow to switch his color\n                btnElement = trumbowyg.$btnPane.find('.' + trumbowyg.o.prefix + 'speechrecognition-button svg')[0];\n\n                // Create a container if needed in which we will put the recognized text\n                trumbowyg.$ed.focus();\n                setTimeout(() => {\n                    trumbowyg.saveRange();\n                    if (\n                        trumbowyg.range.startContainer === trumbowyg.range.endContainer &&\n                        trumbowyg.range.startContainer.nodeName === 'P' &&\n                        trumbowyg.range.startContainer.innerText.trim() === ''\n                    ) {\n                        $resultTextParagraph = $(trumbowyg.range.startContainer);\n                    } else {\n                        $resultTextParagraph = $('<p/>');\n                        trumbowyg.range.deleteContents();\n                        trumbowyg.range.insertNode($resultTextParagraph[0]);\n                    }\n\n                    // Set up the recognition\n                    recognition.lang = trumbowyg.o.plugins.speechRecognition.lang;\n                    recognition.start();\n                });\n            }\n        };\n    }\n\n    function isSupported() {\n        return SpeechRecognition !== undefined;\n    }\n\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            az: {\n                speechRecognition: 'Nitqin tanınması'\n            },\n            bg: {\n                speechRecognition: 'Разпознаване на реч'\n            },\n            by: {\n                speechRecognition: 'Распазнаванне маўлення'\n            },\n            ca: {\n                speechRecognition: 'Reconeixement de veu'\n            },\n            cs: {\n                speechRecognition: 'Rozpoznávání řeči'\n            },\n            da: {\n                speechRecognition: 'Talegenkendelse'\n            },\n            de: {\n                speechRecognition: 'Spracherkennung'\n            },\n            el: {\n                speechRecognition: 'Αναγνώριση ομιλίας'\n            },\n            en: {\n                speechRecognition: 'Speech recognition'\n            },\n            es: {\n                speechRecognition: 'Reconocimiento de voz'\n            },\n            et: {\n                speechRecognition: 'Kõnetuvastus'\n            },\n            fi: {\n                speechRecognition: 'Puheentunnistus'\n            },\n            fr: {\n                speechRecognition: 'Reconnaissance vocale'\n            },\n            hr: {\n                speechRecognition: 'Prepoznavanje govora'\n            },\n            hu: {\n                speechRecognition: 'Beszédfelismerés'\n            },\n            it: {\n                speechRecognition: 'Riconoscimento vocale'\n            },\n            lt: {\n                speechRecognition: 'Kalbos atpažinimas'\n            },\n            nb: {\n                speechRecognition: 'Talegjenkjenning'\n            },\n            nl: {\n                speechRecognition: 'Spraakherkenning'\n            },\n            pl: {\n                speechRecognition: 'Rozpoznawanie mowy'\n            },\n            pt: {\n                speechRecognition: 'Reconhecimento de voz'\n            },\n            ro: {\n                speechRecognition: 'Recunoașterea vorbirii'\n            },\n            rs: {\n                speechRecognition: 'Препознавање говора'\n            },\n            ru: {\n                speechRecognition: 'Распознавание речи'\n            },\n            sk: {\n                speechRecognition: 'Rozpoznávanie reči'\n            },\n            sq: {\n                speechRecognition: 'Njohja e të folurit'\n            },\n            sv: {\n                speechRecognition: 'Taligenkänning'\n            },\n            ua: {\n                speechRecognition: 'Розпізнавання мови'\n            }\n        },\n\n        plugins: {\n            speechRecognition: {\n                shouldInit: isSupported,\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.speechRecognition = $.extend(true, {},\n                        defaultOptions,\n                        trumbowyg.o.plugins.speechRecognition || {}\n                    );\n\n                    trumbowyg.addBtnDef('speechrecognition', buildButtonDef(trumbowyg));\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/table/trumbowyg.table.js",
    "content": "/* ===========================================================\n * trumbowyg.table.js v3.0\n * Table plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Alexandre Demode (Alex-D)\n *          Twitter : @AlexandreDemode\n *          Website : alex-d.fr\n * Original Author : Sven Dunemann [dunemann@forelabs.eu]\n */\n\n(function ($) {\n    'use strict';\n\n    // Throttle helper\n    function trumbowygThrottle(callback, delay) {\n        var last;\n        var timer;\n\n        return function () {\n            var context = this;\n            var now = new Date().getTime();\n            var args = arguments;\n\n            if (last && now < last + delay) {\n                clearTimeout(timer);\n                timer = setTimeout(function () {\n                    last = now;\n                    callback.apply(context, args);\n                }, delay);\n                return;\n            }\n\n            last = now;\n            callback.apply(context, args);\n        };\n    }\n\n    var defaultOptions = {\n        rows: 8,\n        columns: 8,\n        allowHorizontalResize: true,\n        colorList: [\n            'ffffff', '000000', 'eeece1', '1f497d', '4f81bd', 'c0504d', '9bbb59', '8064a2', '4bacc6', 'f79646', 'ffff00',\n            'f2f2f2', '7f7f7f', 'ddd9c3', 'c6d9f0', 'dbe5f1', 'f2dcdb', 'ebf1dd', 'e5e0ec', 'dbeef3', 'fdeada', 'fff2ca',\n            'd8d8d8', '595959', 'c4bd97', '8db3e2', 'b8cce4', 'e5b9b7', 'd7e3bc', 'ccc1d9', 'b7dde8', 'fbd5b5', 'ffe694',\n            'bfbfbf', '3f3f3f', '938953', '548dd4', '95b3d7', 'd99694', 'c3d69b', 'b2a2c7', 'b7dde8', 'fac08f', 'f2c314',\n            'a5a5a5', '262626', '494429', '17365d', '366092', '953734', '76923c', '5f497a', '92cddc', 'e36c09', 'c09100',\n            '7f7f7f', '0c0c0c', '1d1b10', '0f243e', '244061', '632423', '4f6128', '3f3151', '31859b', '974806', '7f6000'\n        ],\n        backgroundColorList: null, // fallbacks on colorList\n        allowCustomBackgroundColor: true,\n        displayBackgroundColorsAsList: false,\n        borderColorList: null, // fallbacks on colorList\n        allowCustomBorderColor: true,\n        displayBorderColorsAsList: false,\n        dropdown: [\n            {\n                title: 'tableRows',\n                buttons: [\n                    'tableAddHeaderRow',\n                    'tableAddRowAbove',\n                    'tableAddRow',\n                    'tableDeleteRow',\n                ],\n            },\n            {\n                title: 'tableColumns',\n                buttons: [\n                    'tableAddColumnLeft',\n                    'tableAddColumn',\n                    'tableDeleteColumn',\n                ],\n            },\n            {\n                title: 'tableVerticalAlign',\n                buttons: [\n                    'tableVerticalAlignTop',\n                    'tableVerticalAlignMiddle',\n                    'tableVerticalAlignBottom',\n                ],\n            },\n            {\n                title: 'tableOthers',\n                buttons: [\n                    // Cell merge/split\n                    'tableMergeCells',\n                    'tableUnmergeCells',\n                    'tableDestroy',\n                ]\n            }\n        ],\n    };\n\n    function ucFirst(value) {\n        return value[0].toUpperCase() + value.slice(1);\n    }\n\n    function hex(x) {\n        return ('0' + parseInt(x).toString(16)).slice(-2);\n    }\n\n    function colorToHex(rgb) {\n        if (rgb.search('rgb') === -1) {\n            return rgb.replace('#', '');\n        } else if (rgb === 'rgba(0, 0, 0, 0)') {\n            return 'transparent';\n        } else {\n            rgb = rgb.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d?(.\\d+)))?\\)$/);\n            if (rgb == null) {\n                return 'transparent'; // No match, return transparent as unkown color\n            }\n            return hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);\n        }\n    }\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                table: 'Insert table',\n                tableRows: 'Rows',\n                tableColumns: 'Columns',\n                tableVerticalAlign: 'Vertical align',\n                tableOthers: 'Others',\n                tableAddHeaderRow: 'Insert head row',\n                tableAddRowAbove: 'Insert row above',\n                tableAddRow: 'Insert row below',\n                tableAddColumnLeft: 'Insert column to the left',\n                tableAddColumn: 'Insert column to the right',\n                tableDeleteRow: 'Delete row',\n                tableDeleteColumn: 'Delete column',\n                tableDestroy: 'Delete table',\n                tableMergeCells: 'Merge cells',\n                tableUnmergeCells: 'Unmerge cells',\n                tableVerticalAlignTop: 'Align text to top',\n                tableVerticalAlignMiddle: 'Center text vertically',\n                tableVerticalAlignBottom: 'Align text to bottom',\n                tableCellBackgroundColor: 'Cell background color',\n                tableBorderColor: 'Table border color'\n            },\n            az: {\n                table: 'Cədvəl yerləşdir',\n                tableAddRow: 'Sətir əlavə et',\n                tableAddRowAbove: 'Yuxarı sətir əlavə et',\n                tableAddColumnLeft: 'Sola sütun əlavə et',\n                tableAddColumn: 'Sağa sütun əlavə et',\n                tableDeleteRow: 'Sətri sil',\n                tableDeleteColumn: 'Sütunu sil',\n                tableDestroy: 'Cədvəli sil',\n            },\n            ca: {\n                table: 'Inserir taula',\n                tableAddRow: 'Afegir fila',\n                tableAddRowAbove: 'Afegir fila a dalt',\n                tableAddColumnLeft: 'Afegir columna a l\\'esquerra',\n                tableAddColumn: 'Afegir columna a la dreta',\n                tableDeleteRow: 'Esborrar fila',\n                tableDeleteColumn: 'Esborrar columna',\n                tableDestroy: 'Esborrar taula',\n                error: 'Error'\n            },\n            cs: {\n                table: 'Vytvořit příkaz Table',\n                tableAddRow: 'Přidat řádek',\n                tableAddRowAbove: 'Přidat řádek',\n                tableAddColumnLeft: 'Přidat sloupec',\n                tableAddColumn: 'Přidat sloupec',\n            },\n            da: {\n                table: 'Indsæt tabel',\n                tableAddRow: 'Tilføj række',\n                tableAddRowAbove: 'Tilføj række',\n                tableAddColumnLeft: 'Tilføj kolonne',\n                tableAddColumn: 'Tilføj kolonne',\n                tableDeleteRow: 'Slet række',\n                tableDeleteColumn: 'Slet kolonne',\n                tableDestroy: 'Slet tabel',\n            },\n            de: {\n                table: 'Tabelle einfügen',\n                tableRows: 'Zeilen',\n                tableColumns: 'Spalten',\n                tableVerticalAlign: 'Vertikal ausrichten',\n                tableOthers: 'Andere',\n                tableAddHeaderRow: 'Kopfzeile einfügen',\n                tableAddRowAbove: 'Zeile oberhalb einfügen',\n                tableAddRow: 'Zeile unterhalb einfügen',\n                tableAddColumnLeft: 'Spalte links einfügen',\n                tableAddColumn: 'Spalte rechts einfügen',\n                tableDeleteRow: 'Zeile löschen',\n                tableDeleteColumn: 'Spalte löschen',\n                tableDestroy: 'Tabelle löschen',\n                tableMergeCells: 'Zellen zusammenführen',\n                tableUnmergeCells: 'Zellen trennen',\n                tableVerticalAlignTop: 'Text nach oben ausrichten',\n                tableVerticalAlignMiddle: 'Text vertikal zentrieren',\n                tableVerticalAlignBottom: 'Text nach unten ausrichten',\n                tableCellBackgroundColor: 'Hintergrundfarbe der Zelle',\n                tableBorderColor: 'Farbe des Tabellenrahmens'\n            },\n            et: {\n                table: 'Sisesta tabel',\n                tableAddRow: 'Lisa rida',\n                tableAddRowAbove: 'Lisa rida üles',\n                tableAddColumnLeft: 'Lisa tulp vasakule',\n                tableAddColumn: 'Lisa tulp paremale',\n                tableDeleteRow: 'Kustuta rida',\n                tableDeleteColumn: 'Kustuta tulp',\n                tableDestroy: 'Kustuta tabel',\n            },\n            fr: {\n                table: 'Insérer un tableau',\n                tableRows: 'Lignes',\n                tableColumns: 'Colonnes',\n                tableVerticalAlign: 'Alignement vertical',\n                tableOthers: 'Autres',\n                tableAddHeaderRow: 'Insérer une line d\\'en-tête',\n                tableAddRowAbove: 'Insérer une ligne au dessus',\n                tableAddRow: 'Insérer une ligne en dessous',\n                tableAddColumnLeft: 'Insérer une colonne à gauche',\n                tableAddColumn: 'Insérer une colonne à droite',\n                tableDeleteRow: 'Supprimer la ligne',\n                tableDeleteColumn: 'Supprimer la colonne',\n                tableDestroy: 'Supprimer le tableau',\n                tableMergeCells: 'Fusionner les cellules',\n                tableUnmergeCells: 'Dissocier les cellules',\n                tableVerticalAlignTop: 'Aligner en haut',\n                tableVerticalAlignMiddle: 'Aligner au milieu',\n                tableVerticalAlignBottom: 'Aligner en bas',\n                tableCellBackgroundColor: 'Couleur de fond des cellules',\n                tableBorderColor: 'Couleur de la bordure du tableau'\n            },\n            hu: {\n                table: 'Táblázat beszúrás',\n                tableAddRow: 'Sor hozzáadás',\n                tableAddRowAbove: 'Sor beszúrás fönt',\n                tableAddColumnLeft: 'Sor beszúrás balra',\n                tableAddColumn: 'Sor beszúrás jobbra',\n                tableDeleteRow: 'Sor törlés',\n                tableDeleteColumn: 'Oszlop törlés',\n                tableDestroy: 'Táblázat törlés',\n            },\n            id: {\n                table: 'Sisipkan tabel',\n                tableAddRow: 'Sisipkan baris',\n                tableAddRowAbove: 'Sisipkan baris',\n                tableAddColumnLeft: 'Sisipkan kolom',\n                tableAddColumn: 'Sisipkan kolom',\n                tableDeleteRow: 'Hapus baris',\n                tableDeleteColumn: 'Hapus kolom',\n                tableDestroy: 'Hapus tabel',\n            },\n            ja: {\n                table: '表の挿入',\n                tableAddRow: '行の追加',\n                tableAddRowAbove: '行の追加',\n                tableAddColumnLeft: '列の追加',\n                tableAddColumn: '列の追加',\n            },\n            ko: {\n                table: '표 넣기',\n                tableAddRow: '줄 추가',\n                tableAddRowAbove: '줄 추가',\n                tableAddColumnLeft: '칸 추가',\n                tableAddColumn: '칸 추가',\n                tableDeleteRow: '줄 삭제',\n                tableDeleteColumn: '칸 삭제',\n                tableDestroy: '표 지우기',\n            },\n            pt_br: {\n                table: 'Inserir tabela',\n                tableRows: 'Linhas',\n                tableColumns: 'Colunas',\n                tableVerticalAlign: 'Alinhamento',\n                tableOthers: 'Outros',\n                tableAddHeaderRow: 'Inserir cabeçalho',\n                tableAddRowAbove: 'Inserir linha',\n                tableAddRow: 'Inserir linha',\n                tableAddColumnLeft: 'Inserir coluna',\n                tableAddColumn: 'Inserir coluna',\n                tableDeleteRow: 'Excluir linha',\n                tableDeleteColumn: 'Excluir coluna',\n                tableDestroy: 'Excluir tabela',\n                tableMergeCells: 'Mesclar células',\n                tableUnmergeCells: 'Dividir células',\n                tableVerticalAlignTop: 'Alinhar acima',\n                tableVerticalAlignMiddle: 'Alinhar ao centro',\n                tableVerticalAlignBottom: 'Alinhar abaixo',\n                tableCellBackgroundColor: 'Cor da célula',\n                tableBorderColor: 'Cor da borda da tabela'\n            },\n            ru: {\n                table: 'Вставить таблицу',\n                tableAddRow: 'Добавить строку',\n                tableAddRowAbove: 'Добавить строку',\n                tableAddColumnLeft: 'Добавить столбец',\n                tableAddColumn: 'Добавить столбец',\n                tableDeleteRow: 'Удалить строку',\n                tableDeleteColumn: 'Удалить столбец',\n                tableDestroy: 'Удалить таблицу',\n            },\n            sl: {\n                table: 'Dodaj tabelo',\n                tableAddRow: 'Dodaj vrstico',\n                tableAddRowAbove: 'Vrini vrstico',\n                tableAddColumnLeft: 'Vrini stolpec',\n                tableAddColumn: 'Dodaj stolpec',\n                tableDeleteRow: 'Izbriši vrstico',\n                tableDeleteColumn: 'Izbriši stolpec',\n                tableDestroy: 'Izbriši tabelo',\n            },\n            sk: {\n                table: 'Vytvoriť tabuľky',\n                tableAddRow: 'Pridať riadok',\n                tableAddRowAbove: 'Pridať riadok',\n                tableAddColumnLeft: 'Pridať stĺpec',\n                tableAddColumn: 'Pridať stĺpec',\n            },\n            tr: {\n                table: 'Tablo ekle',\n                tableAddRow: 'Satır ekle',\n                tableAddRowAbove: 'Yukarıya satır ekle',\n                tableAddColumnLeft: 'Sola sütun ekle',\n                tableAddColumn: 'Sağa sütun ekle',\n                tableDeleteRow: 'Satırı sil',\n                tableDeleteColumn: 'Sütunu sil',\n                tableDestroy: 'Tabloyu sil',\n            },\n            zh_tw: {\n                table: '插入表格',\n                tableAddRow: '加入行',\n                tableAddRowAbove: '加入行',\n                tableAddColumnLeft: '加入列',\n                tableAddColumn: '加入列',\n                tableDeleteRow: '刪除行',\n                tableDeleteColumn: '刪除列',\n                tableDestroy: '刪除表格',\n            },\n            es: {\n                table: 'Insertar tabla',\n                tableAddRow: 'Agregar fila',\n                tableAddRowAbove: 'Agregar fila arriba',\n                tableAddColumnLeft: 'Agregar columna a la izquierda',\n                tableAddColumn: 'Agregar columna a la derecha',\n                tableDeleteRow: 'Borrar fila',\n                tableDeleteColumn: 'Borrar columna',\n                tableDestroy: 'Borrar tabla',\n            }// jshint camelcase:true\n        },\n\n        plugins: {\n            table: {\n                // jshint maxstatements:false\n                init: function (t) {\n                    t.o.plugins.table = $.extend(true, {}, defaultOptions, t.o.plugins.table || {});\n\n                    // State\n                    var tableSelectedCells;\n\n                    ////////////////////////////////////////////////////\n                    // Dropdown\n\n                    var buildButtonDef = {\n                        fn: function () {\n                            t.saveRange();\n\n                            var btnName = 'table';\n\n                            var dropdownPrefix = t.o.prefix + 'dropdown',\n                                dropdownOptions = { // the dropdown\n                                    class: dropdownPrefix + '-' + btnName + ' ' + dropdownPrefix + ' ' + t.o.prefix + 'fixed-top'\n                                };\n                            dropdownOptions['data-' + dropdownPrefix] = btnName;\n                            var $dropdown = $('<div/>', dropdownOptions);\n\n                            if (t.$box.find('.' + dropdownPrefix + '-' + btnName).length === 0) {\n                                t.$box.append($dropdown.hide());\n                            } else {\n                                $dropdown = t.$box.find('.' + dropdownPrefix + '-' + btnName);\n                            }\n\n                            // clear dropdown\n                            $dropdown.html('');\n\n                            // when active table show AddRow / AddColumn\n                            if (t.$box.find('.' + t.o.prefix + 'table-button').hasClass(t.o.prefix + 'active-button')) {\n                                var $table = $(t.doc.getSelection().anchorNode).closest('table', t.$ed[0]);\n                                var tableState = getTableState($table);\n                                var hasSelectedCells = tableSelectedCells !== undefined;\n                                $(t.o.plugins.table.dropdown).each(function (_, buttonGroup) {\n                                    $dropdown.append($('<div/>', {\n                                        html: t.lang[buttonGroup.title] ? t.lang[buttonGroup.title] : buttonGroup.title,\n                                        class: t.o.prefix + 'table-dropdown-title'\n                                    })).text();\n                                    var $buttonGroup = $('<div/>', {\n                                        class: t.o.prefix + 'dropdown-button-group'\n                                    });\n\n                                    $(buttonGroup.buttons).each(function (_, buttonName) {\n                                        // Conditional thead button\n                                        if (buttonName === 'tableAddHeaderRow') {\n                                            var hasThead = $('thead', $table).length !== 0;\n                                            if (hasThead) {\n                                                return;\n                                            }\n                                        }\n\n                                        // Conditional merge button\n                                        if (buttonName === 'tableMergeCells' && !hasSelectedCells) {\n                                            return;\n                                        }\n\n                                        // Conditional unmerge button\n                                        if (buttonName === 'tableUnmergeCells') {\n                                            var hasAtLeastOneMergedCell = false;\n                                            foreachSelectedCell(function ($cell) {\n                                                var isMergedCell = $cell.is('[colspan]') || $cell.is('[rowspan]');\n                                                hasAtLeastOneMergedCell = hasAtLeastOneMergedCell || isMergedCell;\n                                            }, tableState);\n                                            if (!hasAtLeastOneMergedCell) {\n                                                return;\n                                            }\n                                        }\n\n                                        $buttonGroup.append(t.buildSubBtn(buttonName));\n                                    });\n\n                                    $dropdown.append($buttonGroup);\n                                });\n                            } else {\n                                var $tableSelect = $('<table/>');\n                                $('<tbody/>').appendTo($tableSelect);\n                                for (var i = 0; i < t.o.plugins.table.rows; i += 1) {\n                                    var row = $('<tr/>').appendTo($tableSelect);\n                                    for (var j = 0; j < t.o.plugins.table.columns; j += 1) {\n                                        $('<td/>').appendTo(row);\n                                    }\n                                }\n                                $tableSelect.find('td').on('mouseover', toggleActiveDropdownCells);\n                                $tableSelect.find('td').on('mousedown', tableBuild);\n\n                                $dropdown.append($tableSelect);\n                                $dropdown.append($('<div class=\"trumbowyg-table-size\">1x1</div>'));\n                            }\n\n                            t.dropdown(btnName);\n                        },\n                        class: t.o.prefix + 'open-dropdown'\n                    };\n\n                    var toggleActiveDropdownCells = function (columnEvent) {\n                        var column = $(columnEvent.target),\n                            table = column.closest('table', t.$ed[0]),\n                            colIndex = this.cellIndex,\n                            rowIndex = this.parentNode.rowIndex;\n\n                        // reset all columns\n                        table.find('td').removeClass('active');\n\n                        for (var i = 0; i <= rowIndex; i += 1) {\n                            for (var j = 0; j <= colIndex; j += 1) {\n                                table.find('tr:nth-of-type(' + (i + 1) + ')').find('td:nth-of-type(' + (j + 1) + ')').addClass('active');\n                            }\n                        }\n\n                        // set label\n                        table.next('.trumbowyg-table-size').html((colIndex + 1) + 'x' + (rowIndex + 1));\n                    };\n\n                    var applyTagClassesToElement = function (element) {\n                        var tagClasses = t.o.tagClasses[element.tagName.toLowerCase()];\n                        if (!tagClasses) {\n                            return;\n                        }\n                        $(element).addClass(tagClasses);\n                    };\n                    var applyTagClasses = function ($table) {\n                        applyTagClassesToElement($table[0]);\n                        $('*', $table).each(function (_, element) {\n                            applyTagClassesToElement(element);\n                        });\n                    };\n                    var tableBuild = function () {\n                        t.saveRange();\n\n                        var $newTable = $('<table/>');\n\n                        // Build thead\n                        var $thead = $('<thead/>');\n                        var $theadTr = $('<tr/>');\n                        $theadTr.appendTo($thead);\n                        for (var th = 0; th <= this.cellIndex; th += 1) {\n                            $('<th/>', {scope: 'col'}).appendTo($theadTr);\n                        }\n                        $thead.appendTo($newTable);\n\n                        // Build tbody\n                        var $tbody = $('<tbody/>');\n\n                        var colIndex = this.cellIndex,\n                            rowIndex = this.parentNode.rowIndex;\n\n                        for (var i = 0; i <= rowIndex; i += 1) {\n                            var row = $('<tr/>').appendTo($tbody);\n                            for (var j = 0; j <= colIndex; j += 1) {\n                                $('<td/>').appendTo(row);\n                            }\n                        }\n\n                        $tbody.appendTo($newTable);\n\n                        // Apply tag classes\n                        applyTagClasses($newTable);\n\n                        // Find first parent element\n                        var rangeNode = t.range.endContainer;\n                        while (rangeNode.nodeType !== Node.ELEMENT_NODE) {\n                            rangeNode = rangeNode.parentNode;\n                        }\n\n                        // Put range after the parent of the selected element\n                        if (rangeNode !== t.$ed[0]) {\n                            t.range.setEndAfter(rangeNode);\n                        }\n\n                        // Insert table after the range\n                        t.range.collapse();\n                        t.range.insertNode($newTable[0]);\n\n                        // Remove empty paragraph\n                        if (rangeNode.nodeName === 'P' && rangeNode.textContent.trim().length === 0) {\n                            rangeNode.remove();\n                        }\n\n                        t.syncCode();\n\n                        rebuildResizeLayers();\n                    };\n\n                    var getTableState = function ($table) {\n                        var $tableRows = $('tr', $table);\n                        var tableState = [];\n                        for (var i = 0; i < $tableRows.length; i += 1) {\n                            tableState.push([]);\n                        }\n\n                        $tableRows.each(function (rowIndex, row) {\n                            var columnIndex = 0;\n                            $('td, th', $(row)).each(function (cellIndex, cell) {\n                                var $cell = $(cell);\n                                var colspanAttr = $cell.attr('colspan');\n                                var rowspanAttr = $cell.attr('rowspan');\n\n                                var colspan = parseInt(colspanAttr > 0 ? colspanAttr : 1, 10);\n                                var rowspan = parseInt(rowspanAttr > 0 ? rowspanAttr : 1, 10);\n\n                                while (tableState[rowIndex][columnIndex] !== undefined) {\n                                    columnIndex += 1;\n                                }\n\n                                tableState[rowIndex][columnIndex] = {\n                                    tag: cell.tagName,\n                                    element: cell,\n                                    colspan: colspan,\n                                    rowspan: rowspan,\n                                };\n\n                                for (var cols = 1; cols < colspan; cols += 1) {\n                                    tableState[rowIndex][columnIndex + cols] = {\n                                        mergedIn: [rowIndex, columnIndex]\n                                    };\n                                }\n\n                                for (var rows = 1; rows < rowspan; rows += 1) {\n                                    tableState[rowIndex + rows][columnIndex] = {\n                                        mergedIn: [rowIndex, columnIndex]\n                                    };\n\n                                    for (var colsInRow = 1; colsInRow < colspan; colsInRow += 1) {\n                                        tableState[rowIndex + rows][columnIndex + colsInRow] = {\n                                            mergedIn: [rowIndex, columnIndex]\n                                        };\n                                    }\n                                }\n\n                                columnIndex += colspan;\n                            });\n                        });\n\n                        return tableState;\n                    };\n\n\n                    ////////////////////////////////////////////////////\n                    // Buttons\n\n                    var tableButtonAction = function (callback) {\n                        return function () {\n                            t.saveRange();\n\n                            var node = t.doc.getSelection().anchorNode;\n                            var $table = $(node).closest('table', t.$ed[0]);\n\n                            if ($table.length === 0) {\n                                return;\n                            }\n\n                            if (node.tagName === 'TR') {\n                                node = $('td, th', node)[0];\n                            }\n                            var $focusedRow = $(node).closest('tr', t.$ed[0]);\n\n                            var tableState = getTableState($table);\n\n                            callback($table, $focusedRow, node, tableState);\n\n                            t.syncCode();\n                        };\n                    };\n\n\n                    ////// Rows\n\n                    var addRowButtonAction = function (isBefore = false) {\n                        return tableButtonAction(function ($table, $focusedRow, node, tableState) {\n                            var $rows = $('tr', $table);\n                            var $newRow = $('<tr/>');\n\n                            // Shift one row before if insert before\n                            var focusedRowIndex = $rows.index($focusedRow);\n                            if (isBefore) {\n                                focusedRowIndex = Math.max(0, focusedRowIndex - 1);\n                                $focusedRow = $($rows[focusedRowIndex]);\n                            } else {\n                                var rawCellRowspan = $(node).closest('td, th', t.$ed[0]).attr('rowspan');\n                                var cellRowspan = parseInt(rawCellRowspan ? rawCellRowspan : 1, 10);\n                                focusedRowIndex += cellRowspan - 1;\n                                $focusedRow = $($rows[focusedRowIndex]);\n                            }\n\n                            // Cannot add line to thead, so move to first tbody row\n                            var $tbodyRows = $('tbody tr', $table);\n                            var isFocusInHead = $focusedRow.closest('thead').length !== 0;\n                            if (isFocusInHead) {\n                                $focusedRow = $tbodyRows.first();\n                            }\n\n                            // add columns according to current columns count\n                            var focusedRowState = tableState[focusedRowIndex];\n                            var nextRowState = tableState[focusedRowIndex + 1];\n                            var columnCount = tableState[0].length;\n                            for (var columnIndex = 0; columnIndex < columnCount; columnIndex += 1) {\n                                if (nextRowState !== undefined) {\n                                    var originCellState = focusedRowState[columnIndex];\n                                    var originCellMergedInState = getCellState(tableState, originCellState.mergedIn);\n                                    var nextCellState = nextRowState[columnIndex];\n                                    var nextCellMergedInState = getCellState(tableState, nextCellState.mergedIn);\n\n                                    var realOriginCellState = originCellState.element ? originCellState : originCellMergedInState;\n                                    var originCellElement = realOriginCellState.element;\n                                    var nextCellElement = nextCellState.element ? nextCellState.element : nextCellMergedInState.element;\n\n                                    if (originCellElement === nextCellElement) {\n                                        originCellElement.setAttribute('rowspan', realOriginCellState.rowspan + 1);\n\n                                        continue;\n                                    }\n                                }\n\n                                $('<td/>').appendTo($newRow);\n                            }\n\n                            // add row to table\n                            if (focusedRowIndex === 0 && (isBefore || isFocusInHead)) {\n                                $focusedRow.before($newRow);\n                            } else {\n                                $focusedRow.after($newRow);\n                            }\n\n                            applyTagClasses($table);\n                            rebuildResizeLayers();\n                        });\n                    };\n\n                    var addRowAbove = {\n                        title: t.lang.tableAddRowAbove,\n                        text: t.lang.tableAddRowAbove,\n                        ico: 'row-above',\n\n                        fn: addRowButtonAction(true),\n                    };\n\n                    var addRowBelow = {\n                        title: t.lang.tableAddRow,\n                        text: t.lang.tableAddRow,\n                        ico: 'row-below',\n\n                        fn: addRowButtonAction(false),\n                    };\n\n                    var addHeaderRow = {\n                        title: t.lang.tableAddHeaderRow,\n                        text: t.lang.tableAddHeaderRow,\n                        ico: 'header-row',\n\n                        fn: tableButtonAction(function ($table, $focusedRow, node, tableState) {\n                            var hasThead = $('thead', $table).length !== 0;\n                            if (hasThead) {\n                                return false;\n                            }\n\n                            var columnCount = tableState[0].length;\n\n                            var $thead = $('<thead/>');\n                            var $theadRow = $('<tr/>').appendTo($thead);\n\n                            // add columns according to current columns count\n                            for (var columnIndex = 0; columnIndex < columnCount; columnIndex += 1) {\n                                $('<th/>').appendTo($theadRow);\n                            }\n\n                            // add thead to table\n                            $table.prepend($thead);\n\n                            applyTagClasses($table);\n                            rebuildResizeLayers();\n                        }),\n                    };\n\n\n                    ////// Columns\n\n                    var addColumnButtonAction = function (isBefore = false) {\n                        return tableButtonAction(function ($table, $focusedRow, node, tableState) {\n                            var $rows = $('tr', $table);\n                            var focusedRowIndex = $rows.index($focusedRow);\n                            var focusedRowState = tableState[focusedRowIndex];\n                            var $focusedCell = $(node).closest('td, th');\n\n                            // Shift one column before if insert before\n                            var cellIndex = getCellIndex($focusedCell[0], focusedRowState);\n                            if (isBefore) {\n                                cellIndex = Math.max(0, cellIndex - 1);\n                            } else {\n                                var rawCellColspan = $focusedCell.attr('colspan');\n                                var cellColspan = parseInt(rawCellColspan ? rawCellColspan : 1, 10);\n                                cellIndex += cellColspan - 1;\n                            }\n\n                            // add a cell to each row\n                            var rowCount = tableState.length;\n                            var mustInsertBefore = isBefore && cellIndex === 0;\n                            for (var rowIndex = 0; rowIndex < rowCount; rowIndex += 1) {\n                                var rowState = tableState[rowIndex];\n                                var nextCellState = mustInsertBefore ? undefined : rowState[cellIndex + 1];\n                                if (nextCellState !== undefined) {\n                                    var originCellState = rowState[cellIndex];\n                                    var originCellMergedInState = getCellState(tableState, originCellState.mergedIn);\n                                    var nextCellMergedInState = getCellState(tableState, nextCellState.mergedIn);\n\n                                    var realOriginCellState = originCellState.element ? originCellState : originCellMergedInState;\n                                    var originCellElement = realOriginCellState.element;\n                                    var nextCellElement = nextCellState.element ? nextCellState.element : nextCellMergedInState.element;\n\n                                    if (originCellElement === nextCellElement) {\n                                        originCellElement.setAttribute('colspan', realOriginCellState.colspan + 1);\n\n                                        continue;\n                                    }\n                                }\n\n                                // Get previous real cell state\n                                var previousRealCellState;\n                                var previousColumnShift = 0;\n                                do {\n                                    var newIndex = cellIndex - previousColumnShift;\n                                    if (newIndex < 0) {\n                                        break;\n                                    }\n\n                                    previousRealCellState = rowState[newIndex];\n                                    previousColumnShift += 1;\n                                } while (previousRealCellState.mergedIn !== undefined);\n\n                                // Create and append the cell next to the previous\n                                var $previousCell = previousRealCellState.element;\n                                var newCellElement = t.doc.createElement($previousCell.tagName);\n                                if (cellIndex === 0 && isBefore) {\n                                    $previousCell.before(newCellElement);\n                                } else {\n                                    $previousCell.after(newCellElement);\n                                }\n                            }\n\n                            applyTagClasses($table);\n                            rebuildResizeLayers();\n                        });\n                    };\n\n                    var addColumnLeft = {\n                        title: t.lang.tableAddColumnLeft,\n                        text: t.lang.tableAddColumnLeft,\n                        ico: 'col-left',\n\n                        fn: addColumnButtonAction(true)\n                    };\n\n                    var addColumnRight = {\n                        title: t.lang.tableAddColumn,\n                        text: t.lang.tableAddColumn,\n                        ico: 'col-right',\n\n                        fn: addColumnButtonAction(false)\n                    };\n\n\n                    ////// Delete\n\n                    var destroy = {\n                        title: t.lang.tableDestroy,\n                        text: t.lang.tableDestroy,\n                        ico: 'table-delete',\n\n                        fn: tableButtonAction(function ($table) {\n                            $table.remove();\n                        })\n                    };\n\n                    var deleteRow = {\n                        title: t.lang.tableDeleteRow,\n                        text: t.lang.tableDeleteRow,\n                        ico: 'row-delete',\n\n                        fn: tableButtonAction(function ($table, $focusedRow, node, tableState) {\n                            // Only one row is remaining in the table, remove the table\n                            if ($('tbody tr', $table).length === 1) {\n                                $table.remove();\n                                return;\n                            }\n\n                            // Pick element to remove\n                            var $elementToRemove = $focusedRow;\n                            var $focusedRowParent = $focusedRow.parent();\n                            if ($focusedRowParent.is('thead')) {\n                                $elementToRemove = $focusedRowParent;\n                            }\n\n                            // Manage merged cells\n                            var $rows = $('tr', $table);\n                            var rowIndex = $rows.index($(node).closest('tr'));\n                            for (var y = 0; y < tableState[0].length; y += 1) {\n                                var cellState = getCellState(tableState, [rowIndex, y], false);\n\n                                if (cellState.rowspan === 1) {\n                                    continue;\n                                }\n\n                                var originCellState = getCellState(tableState, [rowIndex, y]);\n                                originCellState.element.setAttribute('rowspan', originCellState.rowspan - 1);\n\n                                // If origin cell is not in this row, continue\n                                if (cellState.mergedIn !== undefined) {\n                                    continue;\n                                }\n\n                                // If origin cell is in this row, move it to the next row\n                                var originCellIndex = getCellIndex(cellState.element, tableState[rowIndex]);\n                                if (originCellIndex === 0) {\n                                    $($rows[rowIndex + 1]).prepend(originCellState.element);\n                                    continue;\n                                }\n                                var nextRowPreviousColumnCellState = getCellState(tableState, [\n                                    rowIndex + 1,\n                                    originCellIndex - 1\n                                ]);\n                                $(nextRowPreviousColumnCellState.element).after(originCellState.element);\n                            }\n\n                            $elementToRemove.remove();\n                            simplifyCells($table);\n                            redrawResizeLayers();\n                        }),\n                    };\n\n                    var deleteColumn = {\n                        title: t.lang.tableDeleteColumn,\n                        text: t.lang.tableDeleteColumn,\n                        ico: 'col-delete',\n\n                        fn: tableButtonAction(function ($table, $focusedRow, node, tableState) {\n                            var $rows = $('tr', $table);\n                            var rowIndex = $rows.index($(node).closest('tr'));\n                            var columnIndex = getCellIndex($(node).closest('td, th')[0], tableState[rowIndex]);\n\n                            for (var x = 0; x < tableState.length; x += 1) {\n                                var cellState = getCellState(tableState, [x, columnIndex], false);\n\n                                // Reduce cell colspan by 1\n                                if (cellState.colspan > 1) {\n                                    var originCellState = getCellState(tableState, [x, columnIndex]);\n                                    originCellState.element.setAttribute('colspan', originCellState.colspan - 1);\n                                    continue;\n                                }\n\n                                // Delete cell if not merged\n                                cellState.element.remove();\n                            }\n\n                            simplifyCells();\n                            redrawResizeLayers();\n                        })\n                    };\n\n\n                    ////// Cell merging\n\n                    var getCellState = function (tableState, cellCoordinates, mustGetDeep = true) {\n                        if (cellCoordinates === undefined) {\n                            return undefined;\n                        }\n\n                        var cellState = tableState[cellCoordinates[0]][cellCoordinates[1]];\n\n                        if (mustGetDeep && cellState.mergedIn !== undefined) {\n                            cellState = tableState[cellState.mergedIn[0]][cellState.mergedIn[1]];\n                        }\n\n                        return cellState;\n                    };\n\n                    var canMergeSelectedCells = function (tableState) {\n                        if (tableSelectedCells.length === 0) {\n                            return false;\n                        }\n\n                        // Check that all tags are the same\n                        var firstCellStateCoordinates = tableSelectedCells[0];\n                        var firstSelectedCellTag = getCellState(tableState, firstCellStateCoordinates).tag;\n                        var allTagsAreTheSame = tableSelectedCells.every(function (cellCoordinates) {\n                            var cellState = getCellState(tableState, cellCoordinates);\n\n                            return cellState.tag === firstSelectedCellTag;\n                        });\n\n                        if (!allTagsAreTheSame) {\n                            return false;\n                        }\n\n                        // Check that all selected cells make a rectangle\n                        var minByRow = [];\n                        var maxByRow = [];\n                        $(tableSelectedCells).each(function (_, tableSelectedCell) {\n                            var y = tableSelectedCell[0];\n                            var x = tableSelectedCell[1];\n                            var cellState = tableState[y][x];\n\n                            var cellRowspan = cellState.rowspan;\n                            var maxRow = y + cellRowspan;\n\n                            for (; y < maxRow; y += 1) {\n                                if (minByRow[y] === undefined) {\n                                    minByRow[y] = tableState[0].length;\n                                }\n\n                                if (maxByRow[y] === undefined) {\n                                    maxByRow[y] = 0;\n                                }\n\n                                minByRow[y] = Math.min(minByRow[y], x);\n                                maxByRow[y] = Math.max(maxByRow[y], x + cellState.colspan);\n                            }\n                        });\n\n                        if (minByRow.length === 0 || maxByRow.length === 0) {\n                            return false;\n                        }\n\n                        var allMinAreTheSame = minByRow.every(function (value) {\n                            return value === minByRow[minByRow.length - 1];\n                        });\n\n                        var allMaxAreTheSame = maxByRow.every(function (value) {\n                            return value === maxByRow[maxByRow.length - 1];\n                        });\n\n                        return allMinAreTheSame && allMaxAreTheSame;\n                    };\n\n                    var findTopLeftCellInSelection = function () {\n                        var MAX_VALUE = 999999;\n                        var topLeftY = MAX_VALUE;\n                        var topLeftX = MAX_VALUE;\n\n                        $(tableSelectedCells).each(function (_, cell) {\n                            topLeftY = Math.min(cell[0], topLeftY);\n                            topLeftX = Math.min(cell[1], topLeftX);\n                        });\n\n                        if (topLeftX === MAX_VALUE || topLeftY === MAX_VALUE) {\n                            return undefined;\n                        }\n\n                        return [topLeftY, topLeftX];\n                    };\n\n                    var simplifyCells = function ($table) {\n                        var tableState = getTableState($table);\n\n                        // Remove rowspan if a row is empty\n                        var $rows = $('tr', $table);\n                        $(tableState).each(function (rowIndex, rowState) {\n                            var isRowEmpty = rowState.every(function (cellState) {\n                                return cellState.mergedIn !== undefined;\n                            });\n\n                            if (!isRowEmpty) {\n                                return;\n                            }\n\n                            // Reduce by 1 the rowspan on each cell in previous row\n                            $(tableState[rowIndex - 1]).each(function (_, cellState) {\n                                if (cellState.mergedIn !== undefined) {\n                                    cellState = getCellState(tableState, cellState.mergedIn);\n                                }\n                                cellState.rowspan -= 1;\n\n                                if (cellState.rowspan <= 1) {\n                                    cellState.element.removeAttribute('rowspan');\n                                    return;\n                                }\n\n                                cellState.element.setAttribute('rowspan', cellState.rowspan);\n                            });\n\n                            // Remove empty tr\n                            $rows[rowIndex].remove();\n                        });\n\n                        // Remove empty attributes\n                        $('[class=\"\"]', $table).removeAttr('class');\n                        $('[style=\"\"]', $table).removeAttr('style');\n                    };\n\n                    var mergeCells = {\n                        title: t.lang.tableMergeCells,\n                        text: t.lang.tableMergeCells,\n                        ico: 'table-merge',\n\n                        fn: tableButtonAction(function ($table, $focusedRow, node, tableState) {\n                            if (!canMergeSelectedCells(tableState)) {\n                                return;\n                            }\n\n                            var topLeftCellCoordinates = findTopLeftCellInSelection();\n                            if (topLeftCellCoordinates === undefined) {\n                                return;\n                            }\n\n                            var topLeftCellState = getCellState(tableState, topLeftCellCoordinates);\n                            var $topLeftCell = $(topLeftCellState.element);\n                            var minY = 999999;\n                            var maxY = 0;\n                            var minX = 999999;\n                            var maxX = 0;\n                            $(tableSelectedCells).each(function (_, selectedCell) {\n                                var y = selectedCell[0];\n                                var x = selectedCell[1];\n                                var cellState = tableState[y][x];\n\n                                minY = Math.min(minY, y);\n                                maxY = Math.max(maxY, y + cellState.rowspan - 1);\n                                minX = Math.min(minX, x);\n                                maxX = Math.max(maxX, x + cellState.colspan - 1);\n\n                                if (cellState.element === $topLeftCell[0]) {\n                                    return;\n                                }\n\n                                cellState.element.remove();\n                            });\n\n                            var cellHeight = maxY - minY + 1;\n                            var cellWidth = maxX - minX + 1;\n\n                            if (cellHeight > 1) {\n                                $topLeftCell.attr('rowspan', cellHeight);\n                            }\n                            if (cellWidth > 1) {\n                                $topLeftCell.attr('colspan', cellWidth);\n                            }\n\n                            simplifyCells($table);\n\n                            rebuildResizeLayers();\n                        }),\n                    };\n\n                    var unmergeCells = {\n                        title: t.lang.tableUnmergeCells,\n                        text: t.lang.tableUnmergeCells,\n                        ico: 'table-unmerge',\n\n                        fn: tableButtonAction(function ($table, $focusedRow, node, tableState) {\n                            foreachSelectedCell(function ($cell) {\n                                $cell.removeAttr('colspan').removeAttr('rowspan');\n                                var $rows = $('tr', $table);\n\n                                var cellRowIndex = $rows.index($cell.closest('tr'));\n                                var cellColumnIndex = getCellIndex($cell[0], tableState[cellRowIndex]);\n                                var cellState = tableState[cellRowIndex][cellColumnIndex];\n\n                                for (var rowIndex = 0; rowIndex < cellState.rowspan; rowIndex += 1) {\n                                    var colIndex = (rowIndex === 0) ? 1 : 0;\n                                    var previousCellState = getCellState(tableState, [\n                                        cellRowIndex + rowIndex,\n                                        cellColumnIndex + colIndex - 1\n                                    ]);\n                                    var previousCellElement = previousCellState.element;\n                                    for (; colIndex < cellState.colspan; colIndex += 1) {\n                                        var newCellElement = t.doc.createElement(previousCellElement.tagName);\n                                        $(previousCellElement).after(newCellElement);\n                                    }\n                                }\n                            }, tableState);\n\n                            applyTagClasses($table);\n                            rebuildResizeLayers();\n                        }),\n                    };\n\n\n                    ////// Cell selection\n\n                    var getCellIndex = function (cellElement, rowState) {\n                        return rowState.findIndex(function (rowStateCell) {\n                            if (rowStateCell.element === undefined) {\n                                return false;\n                            }\n\n                            return rowStateCell.element === cellElement;\n                        });\n                    };\n\n                    var resetTableMouseHacks = function () {\n                        $('table', t.$ed).off('mousedown.tbwTable');\n                        $('table', t.$ed).on('mousedown.tbwTable', function (e) {\n                            // Cells drag and drop while changing cell selection\n                            t.doc.getSelection().removeAllRanges();\n\n                            // Prevent Ctrl+Click on Firefox\n                            if (!e.ctrlKey) {\n                                return;\n                            }\n\n                            e.preventDefault();\n                        });\n                    };\n\n                    var tableCellSelectionModeClass = t.o.prefix + 'table-cell-selection-mode';\n                    var tableCellSelectedClass = t.o.prefix + 'table-cell-selected';\n                    setTimeout(function () { // Wait for init\n                        resetTableMouseHacks();\n                        t.$c.on('tbwchange.tbwTable', function () {\n                            resetTableMouseHacks();\n                            rebuildResizeLayers();\n                        });\n\n                        rebuildResizeLayers();\n\n                        $(t.doc).on('selectionchange.tbwTable', function () {\n                            tableSelectedCells = undefined;\n\n                            var selection = t.doc.getSelection();\n                            var rangeCount = selection.rangeCount;\n\n                            var anchorNode = selection.anchorNode;\n                            var focusNode = selection.focusNode;\n\n                            // Firefox create one range by cell\n                            if (rangeCount > 1) {\n                                var firstRange = selection.getRangeAt(0);\n                                var lastRange = selection.getRangeAt(rangeCount - 1);\n\n                                anchorNode = firstRange.startContainer.childNodes[firstRange.startOffset];\n                                focusNode = lastRange.startContainer.childNodes[lastRange.startOffset];\n                            }\n\n                            var $anchorSelectedCell = $(anchorNode).closest('td, th');\n                            var $focusSelectedCell = $(focusNode).closest('td, th');\n\n                            var $tableAnchor = $anchorSelectedCell.closest('table');\n                            var $tableFocus = $focusSelectedCell.closest('table');\n\n                            $('[class=\"' + tableCellSelectedClass + '\"]', t.$ed).removeAttr('class');\n                            $('.' + tableCellSelectedClass, t.$ed).removeClass(tableCellSelectedClass);\n\n                            if (($tableAnchor.length === 0 && $tableFocus.length === 0) ||\n                                $tableAnchor[0] !== $tableFocus[0] ||\n                                $anchorSelectedCell[0] === $focusSelectedCell[0]\n                            ) {\n                                $('.' + tableCellSelectionModeClass, t.$ed).removeClass(tableCellSelectionModeClass);\n                                return;\n                            }\n\n                            // Toggle table to selection mode\n                            $tableAnchor.addClass(tableCellSelectionModeClass);\n\n                            // Get table state\n                            var tableState = getTableState($tableAnchor);\n\n                            // Find cells to set as selected\n                            var $allRows = $('tr', $tableAnchor);\n\n                            var $anchorSelectedRow = $anchorSelectedCell.closest('tr');\n                            var anchorSelectedRowIndex = $allRows.index($anchorSelectedRow);\n                            var $focusSelectedRow = $focusSelectedCell.closest('tr');\n                            var focusSelectedRowIndex = $allRows.index($focusSelectedRow);\n\n                            var anchorSelectedCellIndex = getCellIndex($anchorSelectedCell[0], tableState[anchorSelectedRowIndex]);\n                            var focusSelectedCellIndex = getCellIndex($focusSelectedCell[0], tableState[focusSelectedRowIndex]);\n\n                            var firstSelectedRowIndex = Math.min(anchorSelectedRowIndex, focusSelectedRowIndex);\n                            var lastSelectedRowIndex = Math.max(anchorSelectedRowIndex, focusSelectedRowIndex);\n                            var firstSelectedCellIndex = Math.min(anchorSelectedCellIndex, focusSelectedCellIndex);\n                            var lastSelectedCellIndex = Math.max(anchorSelectedCellIndex, focusSelectedCellIndex);\n\n                            // Set cells as selected\n                            var selectedCellsCoordinates = [];\n                            $allRows.each(function (rowIndex, rowElement) {\n                                if (rowIndex < firstSelectedRowIndex || rowIndex > lastSelectedRowIndex) {\n                                    return;\n                                }\n\n                                $('td, th', rowElement).each(function (_, cellElement) {\n                                    var cellIndex = getCellIndex(cellElement, tableState[rowIndex]);\n                                    if (cellIndex < firstSelectedCellIndex || cellIndex > lastSelectedCellIndex) {\n                                        return;\n                                    }\n\n                                    selectedCellsCoordinates.push([rowIndex, cellIndex]);\n                                    $(cellElement).addClass(tableCellSelectedClass);\n                                });\n                            });\n\n                            tableSelectedCells = selectedCellsCoordinates;\n                        });\n                    });\n\n                    var foreachSelectedCell = function (callback, tableState) {\n                        if (tableSelectedCells === undefined) {\n                            var $cell = $(t.doc.getSelection().anchorNode).closest('td, th');\n                            if ($cell.length === 0) {\n                                return;\n                            }\n\n                            callback($cell);\n                            return;\n                        }\n\n                        $(tableSelectedCells).each(function (_, cellCoordinates) {\n                            var cellState = getCellState(tableState, cellCoordinates, false);\n                            if (cellState.mergedIn !== undefined) {\n                                return;\n                            }\n\n                            callback($(cellState.element));\n                        });\n                    };\n\n\n                    ////// Cell resize\n\n                    var TRUMBOWYG_TABLE_HANDLE_FOR = 'trumbowyg-table-handle-for';\n                    var $targetTable;\n                    var targetTableState;\n                    var targetColumnIndex;\n                    var rebuildResizeLayers = trumbowygThrottle(function () {\n                        if (!t.o.plugins.table.allowHorizontalResize) {\n                            return;\n                        }\n\n                        var $resizeLayers = $('.' + t.o.prefix + 'table-resize-layers', t.$edBox);\n                        var hasResizeLayers = $resizeLayers.length > 0;\n                        if (!hasResizeLayers) {\n                            $resizeLayers = $('<div/>', {\n                                class: t.o.prefix + 'table-resize-layers',\n                            }).appendTo(t.$edBox);\n                        }\n\n                        // Reset and remove old handles\n                        $('.' + t.o.prefix + 'table-resize-vertical-handle', $resizeLayers).each(function (_, handle) {\n                            $(handle)\n                                .off()\n                                .remove();\n                        });\n\n                        $('td, th', t.$ed).each(function (_cellIndex, cell) {\n                            // Vertical handles\n                            $('<div/>', {\n                                class: t.o.prefix + 'table-resize-vertical-handle',\n                            })\n                                .prop(TRUMBOWYG_TABLE_HANDLE_FOR, cell)\n                                .on('mousedown.tbwTable', function (e) {\n                                    e.preventDefault();\n                                    e.stopPropagation();\n                                    var targetCell = $(e.target).prop(TRUMBOWYG_TABLE_HANDLE_FOR);\n                                    $targetTable = $(targetCell).closest('table');\n                                    targetTableState = getTableState($targetTable);\n                                    var $allRows = $('tr', $targetTable);\n                                    var $row = $(targetCell).closest('tr');\n                                    var rowIndex = $allRows.index($row);\n                                    var rowState = targetTableState[rowIndex];\n                                    var columnIndex = getCellIndex(targetCell, rowState);\n                                    var targetCellState = targetTableState[rowIndex][columnIndex];\n                                    if (targetCellState.mergedIn !== undefined) {\n                                        targetCellState = targetTableState[targetCellState.mergedIn[0]][targetCellState.mergedIn[1]];\n                                    }\n\n                                    targetColumnIndex = columnIndex + targetCellState.colspan - 1;\n\n                                    ensureColgroupExists($targetTable, targetTableState);\n                                    setColWidthInPixels($targetTable, targetTableState);\n                                    redrawResizeLayers();\n\n                                    $targetTable.css({\n                                        maxWidth: '',\n                                    });\n                                })\n                                .appendTo($resizeLayers);\n                        });\n                        redrawResizeLayers();\n\n                        // If resize layer was here\n                        // We do not need to add following events\n                        if (hasResizeLayers) {\n                            return;\n                        }\n\n                        $(t.doc)\n                            .on('mousemove.tbwTable', function (e) {\n                                if (targetColumnIndex === undefined) {\n                                    return;\n                                }\n                                e.preventDefault();\n                                e.stopPropagation();\n\n                                var tableRect = $targetTable[0].getBoundingClientRect();\n                                var tableLeftInPixels = e.pageX - tableRect.left;\n\n                                var cellState = findFirstCellAtIndex(targetTableState, targetColumnIndex);\n\n                                var cellElement = cellState.element;\n                                var cellRect = cellElement.getBoundingClientRect();\n                                var cellLeftInPixels = cellRect.left - tableRect.left;\n\n                                var cellWidthInPixels = tableLeftInPixels - cellLeftInPixels;\n\n                                var colElement = $('col', $targetTable)[targetColumnIndex];\n                                $(colElement).css({\n                                    width: cellWidthInPixels,\n                                });\n\n                                redrawResizeLayers();\n                            })\n                            .on('mouseup.tbwTable', function (e) {\n                                if (targetColumnIndex === undefined) {\n                                    return;\n                                }\n                                e.preventDefault();\n                                e.stopPropagation();\n\n                                // Fix width\n                                ensureColgroupExists($targetTable, targetTableState);\n                                setColWidthInPercents($targetTable, targetTableState);\n\n                                // Reset resize state\n                                $targetTable = undefined;\n                                targetTableState = undefined;\n                                targetColumnIndex = undefined;\n\n                                // Update HTML\n                                t.syncCode();\n                                redrawResizeLayers();\n                            });\n\n                        $(window)\n                            .on('resize.tbwTable', function () {\n                                redrawResizeLayers();\n                            });\n                    }, 100);\n\n                    var ensureColgroupExists = function ($table, tableState) {\n                        var $colgroup = $('colgroup', $table);\n                        if ($colgroup.length === 0) {\n                            $colgroup = $('<colgroup/>').prependTo($table);\n                        }\n\n                        var columnCount = tableState[0].length;\n                        var currentColCount = $('col', $colgroup).length;\n                        for (; currentColCount < columnCount; currentColCount += 1) {\n                            $('<col/>').appendTo($colgroup);\n                        }\n                    };\n\n                    var findFirstCellAtIndex = function (tableState, cellIndex) {\n                        var cellState;\n                        var rowIndex = 0;\n                        do {\n                            cellState = tableState[rowIndex][cellIndex];\n                            rowIndex += 1;\n                        } while (cellState.element === undefined || cellState.colspan !== 1);\n\n                        return cellState;\n                    };\n\n                    var setColWidths = function ($table, tableState, isUnitPercent = false) {\n                        var $colgroup = $('colgroup', $table);\n                        var $cols = $('col', $colgroup);\n                        var tableWidth = Math.ceil($table[0].getBoundingClientRect().width);\n                        $table.css({\n                            maxWidth: tableWidth,\n                        });\n\n                        var columnCount = tableState[0].length;\n                        var colWidths = [];\n                        for (var columnIndex = 0; columnIndex < columnCount; columnIndex += 1) {\n                            var cellElement = findFirstCellAtIndex(tableState, columnIndex).element;\n                            var cellWidth = cellElement.getBoundingClientRect().width;\n\n                            if (isUnitPercent) {\n                                cellWidth = ((cellWidth / tableWidth) * 100) + '%';\n                            }\n\n                            colWidths[columnIndex] = cellWidth;\n                        }\n\n                        for (var colIndex = 0; colIndex < columnCount; colIndex += 1) {\n                            $($cols[colIndex]).css({\n                                width: colWidths[colIndex],\n                            });\n                        }\n                    };\n\n                    var setColWidthInPixels = function ($table, tableState) {\n                        setColWidths($table, tableState, false);\n                    };\n\n                    var setColWidthInPercents = function ($table, tableState) {\n                        setColWidths($table, tableState, true);\n                    };\n\n                    var redrawResizeLayers = trumbowygThrottle(function () {\n                        var $resizeLayers = $('.' + t.o.prefix + 'table-resize-layers', t.$edBox);\n\n                        var resizeLayersBoundingClientRect = $resizeLayers[0].getBoundingClientRect();\n                        var resizeLayersTop = resizeLayersBoundingClientRect.top;\n                        var resizeLayersLeft = resizeLayersBoundingClientRect.left;\n\n                        $('.' + t.o.prefix + 'table-resize-vertical-handle', $resizeLayers).each(function (_, cellHandle) {\n                            var $cellHandle = $(cellHandle);\n                            var cell = $cellHandle.prop(TRUMBOWYG_TABLE_HANDLE_FOR);\n                            var cellBoundingClientRect = cell.getBoundingClientRect();\n                            $cellHandle.css({\n                                top: cellBoundingClientRect.top - resizeLayersTop,\n                                left: cellBoundingClientRect.left - resizeLayersLeft + cellBoundingClientRect.width,\n                                height: cellBoundingClientRect.height,\n                            });\n                        });\n                    }, 20);\n\n\n                    ////// Vertical alignment\n\n                    var tableVerticalAlign = function (alignPosition) {\n                        return tableButtonAction(function ($table, $focusedRow, node, tableState) {\n                            foreachSelectedCell(function ($cell) {\n                                $cell.css({\n                                    verticalAlign: alignPosition,\n                                });\n                            }, tableState);\n                        });\n                    };\n\n                    var verticalAlignTop = {\n                        title: t.lang.tableVerticalAlignTop,\n                        text: t.lang.tableVerticalAlignTop,\n                        ico: 'align-top',\n\n                        fn: tableVerticalAlign('top'),\n                    };\n\n                    var verticalAlignMiddle = {\n                        title: t.lang.tableVerticalAlignMiddle,\n                        text: t.lang.tableVerticalAlignMiddle,\n                        ico: 'align-middle',\n\n                        fn: tableVerticalAlign('middle'),\n                    };\n\n                    var verticalAlignBottom = {\n                        title: t.lang.tableVerticalAlignBottom,\n                        text: t.lang.tableVerticalAlignBottom,\n                        ico: 'align-bottom',\n\n                        fn: tableVerticalAlign('bottom'),\n                    };\n\n\n                    ////// Cell Background color\n\n                    var getColorDropdownClass = function (mustDisplayAsList) {\n                        return mustDisplayAsList ? t.o.prefix + 'dropdown--color-list' : '';\n                    };\n\n                    var buildColorDropdown = function (name, colorList, mustDisplayAsList, allowCustomColor, callback) {\n                        var dropdown = [];\n                        var trumbowygTableOptions = t.o.plugins.table;\n\n                        $.each(colorList, function (i, color) {\n                            var btn = name + color;\n                            var btnDef = {\n                                fn: callback('#' + color),\n                                hasIcon: false,\n                                text: t.lang['#' + color] || ('#' + color),\n                                style: 'background-color: #' + color + ';'\n                            };\n\n                            t.addBtnDef(btn, btnDef);\n                            dropdown.push(btn);\n                        });\n\n                        // Remove color\n                        var removeColorButtonName = 'remove' + ucFirst(name),\n                            removeColorBtnDef = {\n                                fn: callback(''),\n                                hasIcon: false,\n                                style: 'background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAG0lEQVQIW2NkQAAfEJMRmwBYhoGBYQtMBYoAADziAp0jtJTgAAAAAElFTkSuQmCC);'\n                            };\n\n                        if (mustDisplayAsList) {\n                            removeColorBtnDef.style = '';\n                        }\n\n                        t.addBtnDef(removeColorButtonName, removeColorBtnDef);\n                        dropdown.push(removeColorButtonName);\n\n                        // Custom color\n                        if (trumbowygTableOptions.allowCustomBackgroundColor) {\n                            var freeColorBtnDef = {\n                                fn: function () {\n                                    t.openModalInsert(t.lang.backgroundColor,\n                                        {\n                                            color: {\n                                                label: 'backgroundColor',\n                                                forceCss: true,\n                                                type: 'color',\n                                                value: '#FFFFFF'\n                                            }\n                                        },\n                                        // callback\n                                        function (values) {\n                                            callback(values.color)();\n                                            return true;\n                                        }\n                                    );\n                                },\n                                hasIcon: false,\n                                text: '#',\n                                // style adjust for displaying the text\n                                style: 'text-indent: 0; line-height: 20px; padding: 0 5px;'\n                            };\n\n                            var freeColorButtonName = 'free' + ucFirst(name);\n                            t.addBtnDef(freeColorButtonName, freeColorBtnDef);\n                            dropdown.push(freeColorButtonName);\n                        }\n\n                        return dropdown;\n                    };\n                    var applyBackgroundColorToSelectedCells = function (color) {\n                        return function () {\n                            var $table = $(t.doc.getSelection().anchorNode).closest('table', t.$ed[0]);\n\n                            if ($table.length === 0) {\n                                return;\n                            }\n\n                            var tableState = getTableState($table);\n                            foreachSelectedCell(function ($cell) {\n                                $cell.css({\n                                    backgroundColor: color,\n                                });\n                            }, tableState);\n\n                            simplifyCells($table);\n                        };\n                    };\n                    var cellBackgroundColorBtnDef = {\n                        dropdown: buildColorDropdown(\n                            'tableCellBackgroundColor',\n                            t.o.plugins.table.backgroundColorList || t.o.plugins.table.colorList,\n                            t.o.plugins.table.displayBackgroundColorsAsList,\n                            t.o.plugins.table.allowCustomBackgroundColor,\n                            applyBackgroundColorToSelectedCells\n                        ),\n                        dropdownClass: getColorDropdownClass(t.o.plugins.table.displayBackgroundColorsAsList),\n                    };\n\n\n                    ////// Table border color\n\n                    var applyBorderColor = function (color) {\n                        return function () {\n                            var $table = $(t.doc.getSelection().anchorNode).closest('table', t.$ed[0]);\n\n                            if ($table.length === 0) {\n                                return;\n                            }\n\n                            var border = {\n                                borderColor: color,\n                            };\n                            if (parseInt($table.css('border-width'), 10) === 0) {\n                                border.borderWidth = '2px';\n                                border.borderStyle = 'solid';\n                            }\n\n                            if (color === '') {\n                                border.borderWidth = '';\n                                border.borderStyle = '';\n                            }\n\n                            $table.css(border);\n                        };\n                    };\n                    var tableBorderColorBtnDef = {\n                        dropdown: buildColorDropdown(\n                            'tableBorderColor',\n                            t.o.plugins.table.borderColorList || t.o.plugins.table.colorList,\n                            t.o.plugins.table.displayBorderColorsAsList,\n                            t.o.plugins.table.allowCustomBorderColor,\n                            applyBorderColor\n                        ),\n                        dropdownClass: getColorDropdownClass(t.o.plugins.table.displayBorderColorsAsList),\n                    };\n\n\n\n                    ////// Register buttons\n\n                    t.addBtnDef('table', buildButtonDef);\n\n                    t.addBtnDef('tableAddHeaderRow', addHeaderRow);\n\n                    t.addBtnDef('tableAddRowAbove', addRowAbove);\n                    t.addBtnDef('tableAddRow', addRowBelow);\n\n                    t.addBtnDef('tableAddColumnLeft', addColumnLeft);\n                    t.addBtnDef('tableAddColumn', addColumnRight);\n\n                    t.addBtnDef('tableMergeCells', mergeCells);\n                    t.addBtnDef('tableUnmergeCells', unmergeCells);\n\n                    t.addBtnDef('tableVerticalAlignTop', verticalAlignTop);\n                    t.addBtnDef('tableVerticalAlignMiddle', verticalAlignMiddle);\n                    t.addBtnDef('tableVerticalAlignBottom', verticalAlignBottom);\n\n                    t.addBtnDef('tableCellBackgroundColor', cellBackgroundColorBtnDef);\n                    t.addBtnDef('tableBorderColor', tableBorderColorBtnDef);\n\n                    t.addBtnDef('tableDeleteRow', deleteRow);\n                    t.addBtnDef('tableDeleteColumn', deleteColumn);\n                    t.addBtnDef('tableDestroy', destroy);\n                },\n                destroy: function (t) {\n                    $(window)\n                        .off('resize.tbwTable');\n\n                    $(t.doc)\n                        .off('selectionchange.tbwTable')\n                        .off('mousemove.tbwTable')\n                        .off('mouseup.tbwTable');\n\n                    t.$c\n                        .off('tbwchange.tbwTable');\n\n                    $('table', t.$ed)\n                        .off('mousedown.tbwTable');\n                },\n                tagHandler: function (element, t) {\n                    var tags = [];\n\n                    if (element.tagName === 'TABLE') {\n                        tags.push('table');\n\n                        var elementBorderColor = element.style.borderColor;\n                        if (elementBorderColor !== '') {\n                            var borderColor = colorToHex(elementBorderColor);\n                            if (t.o.plugins.table.colorList.indexOf(borderColor) >= 0) {\n                                tags.push('tableBorderColor' + borderColor);\n                            } else {\n                                tags.push('freeTableBorderColor');\n                            }\n                        }\n                    }\n\n                    if (!element.style) {\n                        return tags;\n                    }\n\n                    var elementVerticalAlign = element.style.verticalAlign;\n                    if (elementVerticalAlign !== '') {\n                        tags.push('tableVerticalAlign' + ucFirst(elementVerticalAlign));\n                    }\n\n                    var elementBackgroundColor = element.style.backgroundColor;\n                    if ((element.tagName === 'TH' || element.tagName === 'TD') && elementBackgroundColor !== '') {\n                        var backgroundColor = colorToHex(elementBackgroundColor);\n                        if (t.o.plugins.table.colorList.indexOf(backgroundColor) >= 0) {\n                            tags.push('tableCellBackgroundColor' + backgroundColor);\n                        } else {\n                            tags.push('freeTableCellBackgroundColor');\n                        }\n                    }\n\n                    return tags;\n                },\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/table/ui/sass/trumbowyg.table.scss",
    "content": ".trumbowyg-dropdown-table {\n    max-height: unset;\n\n    table {\n        all: unset;\n        display: inline-block;\n        margin: 10px;\n        border-collapse: collapse;\n    }\n\n    table td {\n        all: unset;\n        position: relative;\n        display: table-cell;\n        height: 20px;\n        width: 20px;\n        cursor: pointer;\n        background: #fff;\n\n        &::after {\n            content: '';\n            display: block;\n            position: absolute;\n            $padding: 1px;\n            top: $padding;\n            right: $padding;\n            bottom: $padding;\n            left: $padding;\n            border: 1px solid #cecece;\n            pointer-events: none;\n        }\n\n        &.active::after {\n            background-color: #000;\n            border-color: #000;\n        }\n    }\n\n    .trumbowyg-table-size {\n        text-align: center;\n    }\n}\n\n.trumbowyg-table-dropdown-title {\n    padding: 8px 10px;\n    font-size: 12px;\n    text-transform: uppercase;\n    letter-spacing: 2px;\n    font-weight: bold;\n}\n\n.trumbowyg-dropdown-button-group + .trumbowyg-table-dropdown-title {\n    margin-top: 24px;\n}\n\n.trumbowyg-table-cell-selection-mode ::selection {\n    color: inherit;\n    background-color: transparent;\n}\n\n.trumbowyg-table-cell-selected {\n    background-color: #b4d3fe !important;\n}\n\n\n// Resize\n\n.trumbowyg-table-resize-layers {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 0;\n    height: 0;\n}\n\n.trumbowyg-table-resize-vertical-handle {\n    position: absolute;\n    width: 5px;\n    margin-left: -3px;\n    cursor: col-resize;\n}\n\n.trumbowyg-table-resize-vertical-handle::after {\n    content: '';\n    position: absolute;\n    top: 0;\n    left: 1px;\n    width: 3px;\n    height: 100%;\n    background: #0073ff;\n    border-radius: 3px;\n    pointer-events: none;\n    opacity: 0;\n}\n.trumbowyg-table-resize-vertical-handle:hover::after {\n    opacity: 1;\n}\n\n\n// Background/Border color\n\n.trumbowyg-dropdown-tableCellBackgroundColor:not(.trumbowyg-dropdown--color-list),\n.trumbowyg-dropdown-tableBorderColor:not(.trumbowyg-dropdown--color-list) {\n    max-width: 276px;\n    padding: 7px 5px;\n    overflow: initial;\n\n    button {\n        display: block;\n        position: relative;\n        float: left;\n        text-indent: -9999px;\n        height: 20px;\n        width: 20px;\n        border: 1px solid #333;\n        padding: 0;\n        margin: 2px;\n\n        &:hover,\n        &:focus {\n            &::after {\n                content: \" \";\n                display: block;\n                position: absolute;\n                top: -5px;\n                left: -5px;\n                width: 27px;\n                height: 27px;\n                background: inherit;\n                border: 1px solid #fff;\n                box-shadow: #000 0 0 2px;\n                z-index: 10;\n            }\n        }\n    }\n}\n\n.trumbowyg-dropdown-tableCellBackgroundColor.trumbowyg-dropdown--color-list,\n.trumbowyg-dropdown-tableBorderColor.trumbowyg-dropdown--color-list {\n    button:not(.trumbowyg-removeTableCellBackgroundColor-dropdown-button):not(.trumbowyg-removeTableBorderColor-dropdown-button) {\n        position: relative;\n        color: #fff !important;\n\n        &:hover,\n        &:focus {\n            &::after {\n                content: \" \";\n                display: block;\n                position: absolute;\n                top: 13px;\n                left: 0;\n                width: 0;\n                height: 0;\n                border: 5px solid transparent;\n                border-left-color: #fff;\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "plugins/template/trumbowyg.template.js",
    "content": "(function ($) {\n    'use strict';\n\n    // Adds the language variables\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                template: 'Template'\n            },\n            az: {\n                template: 'Şablon'\n            },\n            by: {\n                template: 'Шаблон'\n            },\n            da: {\n                template: 'Skabelon'\n            },\n            de: {\n                template: 'Vorlage'\n            },\n            et: {\n                template: 'Mall'\n            },\n            fr: {\n                template: 'Patron'\n            },\n            hu: {\n                template: 'Sablon'\n            },\n            ja: {\n                template: 'テンプレート'\n            },\n            ko: {\n                template: '서식'\n            },\n            nl: {\n                template: 'Sjabloon'\n            },\n            pt_br: {\n                template: 'Modelo'\n            },\n            ru: {\n                template: 'Шаблон'\n            },\n            sl: {\n                template: 'Predloga'\n            },\n            tr: {\n                template: 'Şablon'\n            },\n            zh_tw: {\n                template: '模板',\n            },\n            // jshint camelcase:true\n        }\n    });\n\n    // Adds the extra button definition\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            template: {\n                shouldInit: function (trumbowyg) {\n                    return trumbowyg.o.plugins.hasOwnProperty('templates');\n                },\n                init: function (trumbowyg) {\n                    trumbowyg.addBtnDef('template', {\n                        dropdown: templateSelector(trumbowyg),\n                        hasIcon: false,\n                        text: trumbowyg.lang.template\n                    });\n                }\n            }\n        }\n    });\n\n    // Creates the template-selector dropdown.\n    function templateSelector(trumbowyg) {\n        var available = trumbowyg.o.plugins.templates;\n        var templates = [];\n\n        $.each(available, function (index, template) {\n            trumbowyg.addBtnDef('template_' + index, {\n                fn: function () {\n                    trumbowyg.html(template.html);\n                },\n                hasIcon: false,\n                title: template.name\n            });\n            templates.push('template_' + index);\n        });\n\n        return templates;\n    }\n})(jQuery);\n"
  },
  {
    "path": "plugins/tenor/trumbowyg.tenor.js",
    "content": "// adapted from giphy plugin\n/* global AbortController: true */\n(function ($) {\n    'use strict';\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                tenor: 'Insert GIF'\n            },\n            az: {\n                tenor: 'GIF yerləşdir'\n            },\n            by: {\n                tenor: 'Уставіць GIF'\n            },\n            de: {\n                tenor: 'GIF einfügen'\n            },\n            et: {\n                tenor: 'Sisesta GIF'\n            },\n            fr: {\n                tenor: 'Insérer un GIF'\n            },\n            hu: {\n                tenor: 'GIF beszúrás'\n            },\n            ru: {\n                tenor: 'Вставить GIF'\n            },\n            sl: {\n                tenor: 'Vstavi GIF'\n            },\n            tr: {\n                tenor: 'GIF ekle'\n            }\n            // jshint camelcase:true\n        }\n    });\n\n    var tenorLogo = '<svg viewBox=\"0 0 1584 447\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"evenodd\"><path d=\"M314.8 295.7c2.4 18 7.6 34.1 16.8 48.6 21.6 34.1 53 50.3 93.2 50 33-.2 61.3-12.2 85.7-34.2 12.8-11.6 30.8-9.4 39.8 4.5 6.5 10 5.2 22.1-3.8 31.1-27.3 27.3-59.8 44.3-98.3 49-25.2 3.1-50.3 2.5-74.8-5.1-55.8-17.3-92.9-54.3-109.4-109.9-19.3-65.3-9-126 36.5-178.2 30.9-35.3 70.9-52.1 118-51.3 40.6.7 76 14.5 104.5 44 23.7 24.5 36.8 54.4 42.8 87.6 2.3 12.6 3.3 25.4 3.9 38.2.7 14.1-10.3 25.1-24.4 25.8-2 .1-4 0-6 0H321.9c-2-.1-4.1-.1-7.1-.1zM510 245.4c-1.5-13-5.2-25-10.1-36.7-29.2-68.7-105.1-70.5-144.1-37-20.5 17.6-32.6 40.1-38.6 66.1-.6 2.4-.8 4.8-1.3 7.6H510zM970.4 271.3c.1-88.4 68.6-171.5 173.4-171.3 97.7.1 172.6 75.8 172.4 174.2-.2 96.7-76.6 172.1-174.5 172.2-94.3 0-171.5-78.8-171.3-175.1zm286.6 4.6c-.5-34.3-10.4-62.9-32.1-87.1-44.3-49.5-125.2-47.6-167.7 3.4-35.4 42.5-37.9 117.5 3.2 163.7 36.6 41.2 102.4 49.7 147.2 17.7 34.1-24.4 48.4-58.9 49.4-97.7zM683.5 148.6c6.3-6 11.4-11.1 16.7-15.9 25.6-23.4 56.2-33 90.3-32.7 26.9.3 52.2 6.3 74.6 21.9 27.8 19.4 42.9 46.9 48.8 79.6 1.9 10.6 2.9 21.5 3 32.3.3 61.2.1 122.3.1 183.5 0 11.7-7.4 22.8-18.3 26.8-11.4 4.2-22.1 2.5-30.9-6.3-6.2-6.1-8.9-13.8-8.9-22.6.1-56.7.3-113.3-.2-170-.1-11.2-1.7-22.7-4.4-33.5-8.5-33.1-32.2-53.2-66.1-57.1-24.1-2.8-47 1-67.1 15.6-26.7 19.4-37.4 47-37.5 79-.2 55.8 0 111.7-.1 167.5 0 21.4-20.8 35.3-40.6 27.2-10.5-4.3-17.6-15.7-17.6-28.5v-286c0-11.3 5.2-19.9 14.8-25.5 9.9-5.8 20.2-5.5 29.9.6 8.3 5.3 13.3 13 13.5 23.2.1 6.6 0 13 0 20.9zM124.9 106.8h78.5c10.8 0 19.6 3.5 25.2 13.2 9.3 16.3-.2 36-18.8 38.8-2.9.4-6 .5-9 .5h-75.9v184.1c0 12 1.9 23.5 10 33.3 6.6 8 15.5 11.4 25.2 12.9 14.5 2.3 28.9 1.1 43-3.3 13.4-4.3 26.6 1.7 31.1 14.2 4.6 12.7-1.9 25.2-14.3 31.2-16.8 8.2-34.4 11.8-53 12.8-48.2 2.4-91.5-32.6-98.8-80.4-1-6.2-1.3-12.6-1.3-18.9-.1-59.5-.1-119-.1-178.5v-6.9c-2.2-.1-4-.3-5.7-.3-11 0-22 .2-33-.1-18-.5-29.6-14-26.9-31 1.9-12 12.8-21 26.5-21.4 10.8-.3 21.7-.1 32.5-.1 6.6 0 6.6 0 6.6-6.9V30.5c0-17 12.3-30 28.7-30.2 16.4-.2 29.3 12.9 29.4 30.1.1 23.3 0 46.7 0 70 .1 1.9.1 3.9.1 6.4zM1432.4 170.1c8.6-9.8 16.2-19.5 25-28.1 20.1-19.6 43.7-33.3 71.5-38.8 8.4-1.7 17.2-2.1 25.8-1.7 16.3.9 28.5 14.5 28.5 30.5 0 15.8-12.4 29.2-28.5 30.7-11.9 1.1-24 1.3-35.7 3.8-32.1 6.9-54.8 26.3-69.4 55.4-12.8 25.4-17.1 52.8-17.2 80.9-.2 37.5 0 75 0 112.5 0 17.4-12.8 30.9-29.3 30.8-16.6-.1-29.1-13-29.1-30.4V128.8c0-13 9.2-24.8 21.6-27.9 13.6-3.4 26.8 2.2 32.7 14.7 2.3 4.8 3.6 10.4 3.8 15.8.6 11.1.2 22.3.2 33.5.1 1.7.1 3.3.1 5.2z\"/></g></svg>'; // jshint ignore:line\n\n    var CANCEL_EVENT = 'tbwcancel';\n    var nextCursor = null;\n\n    // Throttle helper\n    function trumbowygThrottle(callback, delay) {\n        var last;\n        var timer;\n\n        return function () {\n            var context = this;\n            var now = new Date().getTime();\n            var args = arguments;\n\n            if (last && now < last + delay) {\n                clearTimeout(timer);\n                timer = setTimeout(function () {\n                    last = now;\n                    callback.apply(context, args);\n                }, delay);\n            } else {\n                last = now;\n                callback.apply(context, args);\n            }\n        };\n    }\n\n    function registerGifClickEventInModal(trumbowyg, $tenorModal) {\n        $tenorModal.on('click', 'img', function () {\n            var src = $(this).attr('data-full'),\n                alt = $(this).attr('alt');\n            trumbowyg.restoreRange();\n            trumbowyg.execCmd('insertImage', src, false, true);\n\n            // relay alt tag into inserted image\n            if (alt) {\n                var $img = $('img[src=\"' + src + '\"]:not([alt])', trumbowyg.$box);\n                $img.attr('alt', alt);\n                // Note: This seems to fire relatively early and could be wrapped in a setTimeout if needed\n                trumbowyg.syncCode();\n            }\n            $tenorModal.off('click', 'img');\n            trumbowyg.closeModal();\n        });\n    }\n\n    // Fills modal with response gifs\n    function renderGifs(response, $tenorModal, trumbowyg, mustEmpty) {\n        var $tenorLoading = $tenorModal.siblings('.' + trumbowyg.o.prefix + 'tenor-loading');\n        var modalWidth = $tenorModal.width();\n        var gapBetweenImages = 10;\n        var imagesPerRow = 3;\n        var imageWidth = (modalWidth - (gapBetweenImages * (imagesPerRow + 1))) / imagesPerRow;\n\n        nextCursor = response.next;\n        var columnHeights = Array(imagesPerRow).fill(gapBetweenImages);\n\n        if (!mustEmpty) {\n            columnHeights = $tenorModal.data('columnHeights') || columnHeights;\n        }\n\n        var html = response.results\n            .map(function (gifData) {\n                // jshint camelcase:false\n                var image = gifData.media_formats.tinygif,\n                    imageRatio = image.dims[1] / image.dims[0],\n                    altText = gifData.content_description;\n\n                var full_size = gifData.media_formats.gif.url;\n\n                var imgHtml = '<img src=' + image.url + ' width=\"' + imageWidth + '\" height=\"' + imageRatio * imageWidth + '\" alt=\"' + altText + '\" loading=\"lazy\" data-full=\"' + full_size + '\" />';\n\n                var minHeight = Math.min(...columnHeights);\n                var columnIndex = columnHeights.indexOf(minHeight);\n                var top = columnHeights[columnIndex];\n                var left = gapBetweenImages + (columnIndex * (imageWidth + gapBetweenImages));\n\n                columnHeights[columnIndex] += imageRatio * imageWidth + gapBetweenImages;\n\n                var divHtml = '<div class=\"img-container\" style=\"position:absolute; top:' + top + 'px; left:' + left + 'px;\">' + imgHtml + '</div>';\n                return divHtml;\n            })\n            .join('');\n\n        if (mustEmpty === true) {\n            if (html.length === 0) {\n                if ($('.' + trumbowyg.o.prefix + 'tenor-no-result', $tenorModal).length > 0) {\n                    return;\n                }\n\n                html = '<img class=\"' + trumbowyg.o.prefix + 'tenor-no-result\" src=\"' + trumbowyg.o.plugins.tenor.noResultGifUrl + '\"/>';\n            }\n\n            $tenorModal.empty();\n        }\n        $tenorModal.append(html);\n\n        if (!nextCursor || nextCursor.length === 0) {\n            $tenorLoading.hide();\n        } else {\n            $tenorLoading.show();\n        }\n\n        // Remove gray overlay on image load\n        // moved here from inline callback definition due to CSP issue\n        // Note: this is being done post-factum because load event doesn't bubble up and so can't be delegated\n        var addLoadedClass = function (img) {\n            img.classList.add('tbw-loaded');\n        };\n        $('img', $tenorModal).each(function () {\n            var img = this;\n            if (img.complete) { // images load instantly when cached and esp. when loaded in previous modal open\n                addLoadedClass(img);\n                return;\n            }\n\n            img.addEventListener('load', function () {\n                addLoadedClass(this);\n            });\n        });\n\n        $tenorModal.data('columnHeights', columnHeights);\n\n        var maxHeight = Math.max(...columnHeights);\n        $tenorModal.css({\n            position: 'relative',\n            height: maxHeight,\n        });\n    }\n\n    var defaultOptions = {\n        apiKey: null,\n        locale: 'en_US',\n        contentFilter: 'off',\n        throttleDelay: 300,\n        noResultGifUrl: 'https://media1.tenor.com/m/KOZLvzU0o4kAAAAC/no-results.gif'\n    };\n\n    // Add dropdown with font sizes\n    $.extend(true, $.trumbowyg, {\n        plugins: {\n            tenor: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.tenor = $.extend({},\n                        defaultOptions,\n                        trumbowyg.o.plugins.tenor || {}\n                    );\n\n                    trumbowyg.addBtnDef('tenor', {\n                        fn: function () {\n                            if (trumbowyg.o.plugins.tenor.apiKey === null) {\n                                throw new Error('You must set a Tenor API Key');\n                            }\n\n                            var BASE_URL = 'https://g.tenor.com/v2/search?ar_range=all&media_filter=gif,tinygif&limit=10&key=' +\n                                trumbowyg.o.plugins.tenor.apiKey +\n                                '&locale=' + trumbowyg.o.plugins.tenor.locale +\n                                '&contentfilter=' + trumbowyg.o.plugins.tenor.contentFilter;\n\n                            var DEFAULT_URL = BASE_URL.replace('/search', '/featured');\n                            var prefix = trumbowyg.o.prefix;\n                            var abortController = new AbortController();\n\n                            // Create and open the modal\n                            var searchInput = '<input name=\"\" class=\"' + prefix + 'tenor-search\" placeholder=\"Search a GIF\" autofocus=\"autofocus\">',\n                                closeButton = '<button class=\"' + prefix + 'tenor-close\" title=\"' + trumbowyg.lang.close + '\"><svg><use xlink:href=\"' + trumbowyg.svgPath + '#' + prefix + 'close\"/></svg></button>',\n                                poweredByTenor = '<div class=\"' + prefix + 'powered-by-tenor\"><span>Powered by</span>' + tenorLogo + '</div>',\n                                tenorModalHtml = searchInput + closeButton + poweredByTenor + '<div class=\"' + prefix + 'tenor-modal-scroll\"><div class=\"' + prefix + 'tenor-modal\"></div><p class=\"' + prefix + 'tenor-loading\"><img src=\"https://media.tenor.com/YtAOA9y7VG0AAAAM/loading.gif\"> Loading more gifs...</p></div>';\n\n                            trumbowyg\n                                .openModal(null, tenorModalHtml, false)\n                                .one(CANCEL_EVENT, function () {\n                                    try {\n                                        abortController.abort();\n                                        abortController = new AbortController();\n                                    } catch (e) {\n                                    }\n\n                                    trumbowyg.closeModal();\n                                });\n\n                            var $tenorInput = $('.' + prefix + 'tenor-search'),\n                                $tenorClose = $('.' + prefix + 'tenor-close'),\n                                $tenorModal = $('.' + prefix + 'tenor-modal'),\n                                $tenorModalScroll = $('.' + prefix + 'tenor-modal-scroll');\n\n                            var onError = function () {\n                                if (navigator.onLine || $('.' + prefix + 'tenor-offline', $tenorModal).length) {\n                                    return;\n                                }\n\n                                $tenorModal.empty();\n                                $tenorModal.append('<p class=\"' + prefix + 'tenor-offline\">You are offline</p>');\n                            };\n\n                            registerGifClickEventInModal(trumbowyg, $tenorModal);\n\n                            // Load trending gifs as default\n                            fetch(DEFAULT_URL, {\n                                method: 'GET',\n                                cache: 'no-cache',\n                                signal: abortController.signal\n                            }).then((response) => {\n                                response.json().then((responseJson) => {\n                                    renderGifs(responseJson, $tenorModal, trumbowyg, true);\n                                });\n                            }).catch(() => {\n                                onError();\n                            });\n\n                            var searchGifsOnInput = function () {\n                                var query = $tenorInput.val();\n\n                                if (query.length === 0) {\n                                    return;\n                                }\n\n                                try {\n                                    abortController.abort();\n                                    abortController = new AbortController();\n                                } catch (e) {\n                                }\n\n                                $tenorModalScroll.scrollTop(0);\n                                fetch(BASE_URL + '&q=' + encodeURIComponent(query), {\n                                    method: 'GET',\n                                    cache: 'no-cache',\n                                    signal: abortController.signal\n                                }).then((response) => {\n                                    response.json().then((responseJson) => {\n                                        renderGifs(responseJson, $tenorModal, trumbowyg, true);\n                                    });\n                                }).catch(() => {\n                                    onError();\n                                });\n                            };\n                            var throttledInputRequest = trumbowygThrottle(searchGifsOnInput, trumbowyg.o.plugins.tenor.throttleDelay);\n\n                            $tenorInput.on('input', throttledInputRequest);\n                            $tenorInput.focus();\n\n                            $tenorClose.one('click', function () {\n                                $tenorModal.trigger(CANCEL_EVENT);\n                            });\n\n                            var throttledQuery = trumbowygThrottle(function () {\n                                if ($tenorModalScroll.scrollTop() + $tenorModalScroll.innerHeight() >= $tenorModalScroll[0].scrollHeight - 100) {\n                                    if (nextCursor) {\n                                        var query = $tenorInput.val();\n                                        var url = query.length === 0 ? DEFAULT_URL : BASE_URL + '&q=' + encodeURIComponent(query);\n                                        url += '&pos=' + nextCursor;\n\n                                        fetch(url, {\n                                            method: 'GET',\n                                            cache: 'no-cache',\n                                            signal: abortController.signal\n                                        }).then((response) => {\n                                            response.json().then((responseJson) => {\n                                                renderGifs(responseJson, $tenorModal, trumbowyg, false);\n                                            });\n                                        }).catch(() => {\n                                            onError();\n                                        });\n                                    }\n                                }\n                            }, 500);\n\n                            // Infinite scrolling\n                            $tenorModalScroll.on('scroll', throttledQuery);\n                        }\n                    });\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "plugins/tenor/ui/sass/trumbowyg.tenor.scss",
    "content": "// Adapted from giphy plugin\n\n.trumbowyg-tenor-button svg {\n    transform: scale(1.22);\n}\n\n.trumbowyg-tenor-search {\n    display: block;\n    width: 80%;\n    margin: 5%;\n    padding-left: 10px;\n    padding-right: 150px;\n}\n\n.trumbowyg-tenor-close {\n    position: absolute;\n    top: calc(5% + 8px);\n    right: calc(5% - 2px);\n    width: 30px;\n    height: 30px;\n    background: none;\n    border: 1px solid transparent;\n\n    &:hover,\n    &:focus {\n        outline: none;\n        background: #ecf0f1;\n    }\n\n    &:focus {\n        border-color: rgba(0, 0, 0, 0.3);\n    }\n}\n\n.trumbowyg-powered-by-tenor {\n    position: absolute;\n    top: calc(5% + 11px);\n    right: calc(15% + 5px);\n    pointer-events: none;\n    user-select: none;\n\n    span {\n        text-transform: uppercase;\n        font-weight: bold;\n        font-size: 10px;\n        opacity: 0.6;\n    }\n\n    svg {\n        width: 66px;\n        height: 15px;\n        vertical-align: middle;\n        margin-left: 6px;\n        opacity: 0.45;\n    }\n}\n\n.trumbowyg-tenor-modal-scroll {\n    overflow: auto;\n    overflow-x: hidden;\n    height: 240px;\n\n    .trumbowyg-tenor-loading {\n        display: none;\n        padding: 20px;\n\n        img {\n            height: 25px;\n        }\n    }\n}\n\n.trumbowyg-tenor-modal {\n    display: flex;\n    flex-wrap: wrap;\n    justify-content: center;\n    margin: 0 3%;\n\n    .trumbowyg-tenor-no-result {\n        width: 100%;\n        margin: 0 3%;\n    }\n\n    .trumbowyg-tenor-offline {\n        font-size: 18px;\n        width: 305%;\n        height: 600px;\n        margin-top: 95px;\n        text-align: center;\n    }\n}\n\n.trumbowyg-tenor-modal .img-container {\n    margin-bottom: 10px;\n    background-color: #ecf0f1;\n\n    img {\n        width: 100%;\n        cursor: pointer;\n        opacity: 0;\n        transition: opacity 150ms;\n        display: block;\n\n        &:hover,\n        &:focus {\n            border: #2ecc71 solid 3px;\n        }\n    }\n\n    img.tbw-loaded {\n        opacity: 1;\n    }\n}\n"
  },
  {
    "path": "plugins/upload/trumbowyg.upload.js",
    "content": "/* ===========================================================\n * trumbowyg.upload.js v1.2\n * Upload plugin for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Alexandre Demode (Alex-D)\n *          Twitter : @AlexandreDemode\n *          Website : alex-d.fr\n * Mod by : Aleksandr-ru\n *          Twitter : @Aleksandr_ru\n *          Website : aleksandr.ru\n */\n\n(function ($) {\n    'use strict';\n\n    var defaultOptions = {\n        serverPath: '',\n        fileFieldName: 'fileToUpload',\n        data: [],                       // Additional data for ajax [{name: 'key', value: 'value'}]\n        headers: {},                    // Additional headers\n        xhrFields: {},                  // Additional fields\n        urlPropertyName: 'file',        // How to get url from the json response (for instance 'url' for {url: ....})\n        statusPropertyName: 'success',  // How to get status from the json response\n        success: undefined,             // Success callback: function (data, trumbowyg, $modal, values) {}\n        error: undefined,               // Error callback: function () {}\n        imageWidthModalEdit: false      // Add ability to edit image width\n    };\n\n    function getDeep(object, propertyParts) {\n        var mainProperty = propertyParts.shift(),\n            otherProperties = propertyParts;\n\n        if (object !== null) {\n            if (otherProperties.length === 0) {\n                return object[mainProperty];\n            }\n\n            if (typeof object === 'object') {\n                return getDeep(object[mainProperty], otherProperties);\n            }\n        }\n        return object;\n    }\n\n    function runXhrRequest(url, data, options) {\n        var xhrRequest = new XMLHttpRequest();\n        xhrRequest.open(\n            'POST',\n            url,\n            true\n        );\n\n        // Set Headers\n        Object.keys(options.headers).forEach((headerKey) => {\n            xhrRequest.setRequestHeader(headerKey, options.headers[headerKey]);\n        });\n\n        // Set XHR fields\n        Object.keys(options.xhrFields).forEach((xhrFieldKey) => {\n            xhrRequest[xhrFieldKey] = options.headers[xhrFieldKey];\n        });\n\n        // Progress\n        xhrRequest.upload.addEventListener('progress', function (e) {\n            options.progress(e);\n        }, false);\n\n        // Success\n        xhrRequest.onreadystatechange = function() {\n            if (xhrRequest.readyState !== 4) {\n                return;\n            }\n\n            if ((xhrRequest.status < 200 || xhrRequest.status >= 300) && xhrRequest.status !== 304) {\n                options.error();\n                xhrRequest = null;\n                return;\n            }\n\n            var jsonResponse = JSON.parse(xhrRequest.responseText);\n            options.success(jsonResponse);\n\n            xhrRequest = null;\n        };\n\n        xhrRequest.send(data);\n    }\n\n    $.extend(true, $.trumbowyg, {\n        langs: {\n            // jshint camelcase:false\n            en: {\n                upload: 'Upload',\n                file: 'File',\n                uploadError: 'Error'\n            },\n            az: {\n                upload: 'Yüklə',\n                file: 'Fayl',\n                uploadError: 'Xəta'\n            },\n            by: {\n                upload: 'Загрузка',\n                file: 'Файл',\n                uploadError: 'Памылка'\n            },\n            ca: {\n                upload: 'Pujar fitxer',\n                file: 'Fitxer',\n                uploadError: 'Error'\n            },\n            cs: {\n                upload: 'Nahrát obrázek',\n                file: 'Soubor',\n                uploadError: 'Chyba'\n            },\n            da: {\n                upload: 'Upload',\n                file: 'Fil',\n                uploadError: 'Fejl'\n            },\n            de: {\n                upload: 'Hochladen',\n                file: 'Datei',\n                uploadError: 'Fehler'\n            },\n            es: {\n                upload: 'Subir archivo',\n                file: 'Archivo',\n                uploadError: 'Error'\n            },\n            et: {\n                upload: 'Lae üles',\n                file: 'Fail',\n                uploadError: 'Viga'\n            },\n            fr: {\n                upload: 'Envoi',\n                file: 'Fichier',\n                uploadError: 'Erreur'\n            },\n            hu: {\n                upload: 'Feltöltés',\n                file: 'Fájl',\n                uploadError: 'Hiba'\n            },\n            ja: {\n                upload: 'アップロード',\n                file: 'ファイル',\n                uploadError: 'エラー'\n            },\n            ko: {\n                upload: '그림 올리기',\n                file: '파일',\n                uploadError: '에러'\n            },\n            pt_br: {\n                upload: 'Enviar do local',\n                file: 'Arquivo',\n                uploadError: 'Erro'\n            },\n            ru: {\n                upload: 'Загрузка',\n                file: 'Файл',\n                uploadError: 'Ошибка'\n            },\n            sl: {\n                upload: 'Naloži datoteko',\n                file: 'Datoteka',\n                uploadError: 'Napaka'\n            },\n            sk: {\n                upload: 'Nahrať',\n                file: 'Súbor',\n                uploadError: 'Chyba'\n            },\n            tr: {\n                upload: 'Yükle',\n                file: 'Dosya',\n                uploadError: 'Hata'\n            },\n            zh_cn: {\n                upload: '上传',\n                file: '文件',\n                uploadError: '错误'\n            },\n            zh_tw: {\n                upload: '上傳',\n                file: '文件',\n                uploadError: '錯誤'\n            },\n        },\n        // jshint camelcase:true\n\n        plugins: {\n            upload: {\n                init: function (trumbowyg) {\n                    trumbowyg.o.plugins.upload = $.extend(true, {}, defaultOptions, trumbowyg.o.plugins.upload || {});\n                    var btnDef = {\n                        fn: function () {\n                            trumbowyg.saveRange();\n\n                            var file,\n                                prefix = trumbowyg.o.prefix;\n\n                            var fields = {\n                                file: {\n                                    type: 'file',\n                                    required: true,\n                                    attributes: {\n                                        accept: 'image/*'\n                                    }\n                                },\n                                alt: {\n                                    label: 'description',\n                                    value: trumbowyg.getRangeText()\n                                }\n                            };\n\n                            if (trumbowyg.o.plugins.upload.imageWidthModalEdit) {\n                                fields.width = {\n                                    value: ''\n                                };\n                            }\n\n                            // Prevent multiple submissions while uploading\n                            var isUploading = false;\n\n                            var $modal = trumbowyg.openModalInsert(\n                                // Title\n                                trumbowyg.lang.upload,\n\n                                // Fields\n                                fields,\n\n                                // Callback\n                                function (values) {\n                                    const uploadPluginOptions = trumbowyg.o.plugins.upload;\n\n                                    if (isUploading) {\n                                        return;\n                                    }\n                                    isUploading = true;\n\n                                    var data = new FormData();\n                                    data.append(uploadPluginOptions.fileFieldName, file);\n\n                                    uploadPluginOptions.data.map(function (cur) {\n                                        data.append(cur.name, cur.value);\n                                    });\n\n                                    $.map(values, function (curr, key) {\n                                        if (key !== 'file') {\n                                            data.append(key, curr);\n                                        }\n                                    });\n\n                                    if ($('.' + prefix + 'progress', $modal).length === 0) {\n                                        $('.' + prefix + 'modal-title', $modal)\n                                            .after(\n                                                $('<div/>', {\n                                                    'class': prefix + 'progress'\n                                                }).append(\n                                                    $('<div/>', {\n                                                        'class': prefix + 'progress-bar'\n                                                    })\n                                                )\n                                            );\n                                    }\n\n                                    runXhrRequest(\n                                        uploadPluginOptions.serverPath,\n                                        data,\n                                        {\n                                            headers: uploadPluginOptions.headers,\n                                            xhrFields: uploadPluginOptions.xhrFields,\n\n                                            progress: function (e) {\n                                                $('.' + prefix + 'progress-bar').css('width', Math.round(e.loaded * 100 / e.total) + '%');\n                                            },\n\n                                            success: function (data) {\n                                                isUploading = false;\n\n                                                if (uploadPluginOptions.success) {\n                                                    uploadPluginOptions.success(data, trumbowyg, $modal, values);\n                                                    return;\n                                                }\n\n                                                if (!getDeep(data, uploadPluginOptions.statusPropertyName.split('.'))) {\n                                                    trumbowyg.addErrorOnModalField(\n                                                        $('input[type=file]', $modal),\n                                                        trumbowyg.lang[data.message]\n                                                    );\n                                                    trumbowyg.$c.trigger('tbwuploaderror', [trumbowyg, data]);\n                                                    return;\n                                                }\n\n                                                var url = getDeep(data, uploadPluginOptions.urlPropertyName.split('.'));\n                                                trumbowyg.execCmd('insertImage', url, false, true);\n                                                var $img = $('img[src=\"' + url + '\"]:not([alt])', trumbowyg.$box);\n                                                $img.attr('alt', values.alt);\n                                                if (uploadPluginOptions.imageWidthModalEdit && parseInt(values.width) > 0) {\n                                                    $img.attr({\n                                                        width: values.width\n                                                    });\n                                                }\n                                                trumbowyg.syncCode();\n                                                setTimeout(function () {\n                                                    trumbowyg.closeModal();\n                                                }, 250);\n                                                trumbowyg.$c.trigger('tbwuploadsuccess', [trumbowyg, data, url]);\n                                            },\n\n                                            error: uploadPluginOptions.error || function () {\n                                                trumbowyg.addErrorOnModalField(\n                                                    $('input[type=file]', $modal),\n                                                    trumbowyg.lang.uploadError\n                                                );\n                                                trumbowyg.$c.trigger('tbwuploaderror', [trumbowyg]);\n\n                                                isUploading = false;\n                                            }\n                                        }\n                                    );\n                                }\n                            );\n\n                            $('input[type=file]').on('change', function (e) {\n                                // We just get the first.\n                                file = e.target.files[0];\n                            });\n                        }\n                    };\n\n                    trumbowyg.addBtnDef('upload', btnDef);\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "src/langs/ar.js",
    "content": "/* ===========================================================\n * ar.js\n * Arabic translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Abo Mokh ahmed (abomokhahmed)\n *          Github : https://github.com/abomokhahmed\n * Reviewed by : Abdellah Chadidi (chadidi)\n *          Github : https://github.com/chadidi\n */\n\njQuery.trumbowyg.langs.ar = {\n    _dir: 'rtl',\n\n    viewHTML: 'إعرض-HTML',\n\n    undo: 'تراجع',\n    redo: 'إعادة',\n\n    formatting: 'تنسيق',\n\n    p: 'فقرة',\n    blockquote: 'اقتباس',\n    code: 'كود',\n    header: 'رأس',\n\n    bold: 'عريض',\n    italic: 'مائل',\n    strikethrough: 'مشطوب',\n    underline: 'خطّ سفلي',\n\n    strong: 'بارز',\n    em: 'تغميق',\n    del: 'حذف',\n\n    superscript: 'الأس',\n    subscript: 'أس سفلي',\n\n    unorderedList: 'قائمة غير مرتّبة',\n    orderedList: 'قائمة مرتّبة',\n\n    insertImage: 'إدراج صورة',\n    insertVideo: 'إدراج فيديو',\n    link: 'رابط',\n    createLink: 'انشاء رابط',\n    unlink: 'حذف رابط',\n\n    justifyLeft: 'تصحيح للشمال',\n    justifyCenter: 'توسيط',\n    justifyRight: 'تصحيح لليمين',\n    justifyFull: 'تصحيح لكلا الإتّجاهين',\n\n    horizontalRule: 'إدراج خطّ أفقي',\n\n    fullscreen: 'ملء الشاشة',\n\n    close: 'إغلاق',\n\n    submit: 'إرسال',\n    reset: 'إعادة تعيين',\n\n    required: 'إلزامي',\n    description: 'وصف',\n    title: 'عنوان',\n    text: 'نصّ',\n    target: 'الهدف'\n};\n"
  },
  {
    "path": "src/langs/az.js",
    "content": "/* ===========================================================\n * az.js\n * Azerbaijani translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Qalib Qurbanov\n *          Github : https://github.com/qalibqurbanov\n */\n\njQuery.trumbowyg.langs.az = {\n    viewHTML: 'HTML Kodu',\n\n    formatting: 'Formatlama',\n    p: 'Abzas',\n    blockquote: 'Sitat',\n    code: 'Kod',\n    header: 'Başlıq',\n\n    undo: 'Geri al',\n    redo: 'İrəli al',\n\n    superscript: 'Sözüstü',\n    subscript: 'Sözaltı',\n\n    bold: 'Qalın',\n    italic: 'İtalik',\n    strikethrough: 'Üzeri xəttli',\n    underline: 'Altı xəttli',\n\n    strong: 'Qalın',\n    em: 'Vurğulu',\n    del: 'Üzəri xəttli',\n\n    unorderedList: 'İşarələnmiş siyahı',\n    orderedList: 'Nömrələnmiş siyahı',\n\n    insertImage: 'Şəkil yerləşdir',\n    insertVideo: 'Video yerləşdir',\n    link: 'Link',\n    createLink: 'Link yerləşdir',\n    unlink: 'Linki sil',\n\n    justifyLeft: 'Sola nizamla',\n    justifyCenter: 'Ortaya nizamla',\n    justifyRight: 'Sağa nizamla',\n    justifyFull: 'Üfüqi nizamla',\n\n    horizontalRule: 'Üfüqi xətt əlavə et',\n\n    fullscreen: 'Tam ekran',\n\n    close: 'Bağla',\n\n    submit: 'Təsdiq et',\n    reset: 'Sıfırla',\n\n    required: 'Vacib',\n    description: 'Açıqlama',\n    title: 'Başlıq',\n    text: 'Mətn',\n\n    removeformat: 'Formatlamanı təmizlə'\n};\n"
  },
  {
    "path": "src/langs/bg.js",
    "content": "/* ===========================================================\n * bg.js\n * Bulgarian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Aleksandar Dimitrov\n */\n\njQuery.trumbowyg.langs.bg = {\n    viewHTML: 'Прегледай HTML',\n\n    formatting: 'Форматиране',\n    p: 'Параграф',\n    blockquote: 'Цитат',\n    code: 'Код',\n    header: 'Заглавие',\n\n    bold: 'Удебелен',\n    italic: 'Наклонен',\n    strikethrough: 'Зачеркнат',\n    underline: 'Подчертан',\n\n    strong: 'Удебелен',\n    em: 'Наклонен',\n    del: 'Зачеркнат',\n\n    unorderedList: 'Обикновен списък',\n    orderedList: 'Номериран списък',\n\n    insertImage: 'Добави изображение',\n    insertVideo: 'Добави видео',\n    link: 'Връзка',\n    createLink: 'Създай връзка',\n    unlink: 'Премахни връзката',\n\n    justifyLeft: 'Подравни от ляво',\n    justifyCenter: 'Центрирай',\n    justifyRight: 'Подравни от дясно',\n    justifyFull: 'Подравни по ширина',\n\n    horizontalRule: 'Хоризонтална линия',\n\n    fullscreen: 'На цял екран',\n\n    close: 'Затвори',\n\n    submit: 'Впиши',\n    reset: 'Отмени',\n\n    required: 'Задължително',\n    description: 'Описание',\n    title: 'Заглавие',\n    text: 'Текст'\n};\n"
  },
  {
    "path": "src/langs/bn.js",
    "content": "/* ===========================================================\n * bn.js\n * Bangla translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Ahammad Naim\n * Website : https://github.com/AhammadNaim\n */\n\njQuery.trumbowyg.langs.bn = {\n    viewHTML: 'HTML দেখান',\n\n    undo: 'পূর্বাবস্থায় ফিরুন',\n    redo: 'পুনরায় করুন',\n\n    formatting: 'বিন্যাস',\n    p: 'অনুচ্ছেদ',\n    blockquote: 'উদ্ধৃতি',\n    code: 'কোড',\n    header: 'শিরোনাম',\n\n    bold: 'বোল্ড',\n    italic: 'ইটালিক',\n    strikethrough: 'স্ট্রাইকথ্রু',\n    underline: 'আন্ডারলাইন',\n\n    strong: 'বোল্ড',\n    em: 'ইটালিক',\n    del: 'স্ট্রাইকথ্রু',\n\n    superscript: 'সুপারস্ক্রিপ্ট',\n    subscript: 'সাবস্ক্রিপ্ট',\n\n    unorderedList: 'অসংখ্যায়িত তালিকা',\n    orderedList: 'সাজানো তালিকা',\n\n    insertImage: 'ছবি',\n    link: 'লিংক',\n    createLink: 'লিংক তৈরি করুন',\n    unlink: 'লিংক মুছুন',\n\n    justifyLeft: 'বামে জাস্টিফাইড',\n    justifyCenter: 'কেন্দ্রীভূত',\n    justifyRight: 'ডানে জাস্টিফাইড',\n    justifyFull: 'জাস্টিফাইড',\n\n    horizontalRule: 'আনুভূমিক দাগ',\n    removeformat: 'বিন্যাস অপসারণ করুন',\n\n    fullscreen: 'সম্পূর্ণ পর্দায় দেখুন',\n\n    close: 'বন্ধ',\n\n    submit: 'প্রেরণ',\n    reset: 'বাতিল',\n\n    required: 'আবশ্যক',\n    description: 'বর্ননা',\n    title: 'শিরোনাম',\n    text: 'পাঠ্য',\n    target: 'লক্ষ্য'\n};\n"
  },
  {
    "path": "src/langs/by.js",
    "content": "/* ===========================================================\n * by.js\n * Belarusian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Yury Karalkou\n */\n\njQuery.trumbowyg.langs.by = {\n    viewHTML: 'Паглядзець HTML',\n\n    undo: 'Скасаваць',\n    redo: 'Паўтарыць',\n\n    formatting: 'Фарматаванне',\n    p: 'Звычайны',\n    blockquote: 'Цытата',\n    code: 'Код',\n    header: 'Загаловак',\n\n    bold: 'Паўтлусты',\n    italic: 'Курсіў',\n    strikethrough: 'Закрэслены',\n    underline: 'Падкрэслены',\n\n    strong: 'Паўтлусты',\n    em: 'Курсіў',\n    del: 'Закрэслены',\n\n    superscript: 'Верхні індэкс',\n    subscript: 'Індэкс',\n\n    unorderedList: 'Звычайны спіс',\n    orderedList: 'Нумараваны спіс',\n\n    insertImage: 'Уставіць выяву',\n    insertVideo: 'Уставіць відэа',\n    link: 'Спасылка',\n    createLink: 'Уставіць спасылку',\n    unlink: 'Выдаліць спасылку',\n\n    justifyLeft: 'Па леваму боку',\n    justifyCenter: 'У цэнтры',\n    justifyRight: 'Па праваму боку',\n    justifyFull: 'Па шырыні',\n\n    horizontalRule: 'Гарызантальная лінія',\n    removeformat: 'Ачысціць фарматаванне',\n\n    fullscreen: 'На ўвесь экран',\n\n    close: 'Зачыніць',\n\n    submit: 'Уставіць',\n    reset: 'Скасаваць',\n\n    required: 'Абавязкова',\n    description: 'Апісанне',\n    title: 'Падказка',\n    text: 'Тэкст'\n};\n"
  },
  {
    "path": "src/langs/ca.js",
    "content": "/* ===========================================================\n * ca.js\n * Catalan translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Authors : Àlfons Sánchez (alsanan)\n *             Twitter : @alsanan\n *             Website : about.me/alsanan\n *             Github : https://github.com/alsanan\n *\n *           Carles Martínez\n *             Website : calaix.net\n */\n\njQuery.trumbowyg.langs.ca = {\n    viewHTML: 'Veure HTML',\n\n    undo: 'Desfés',\n    redo: 'Refés',\n\n    formatting: 'Format',\n    p: 'Paragraf',\n    blockquote: 'Citació',\n    code: 'Codi',\n    header: 'Títol',\n\n    bold: 'Negreta',\n    italic: 'Cursiva',\n    strikethrough: 'Ratllat',\n    underline: 'Subratllat',\n\n    strong: 'Negreta',\n    em: 'Cursiva',\n    del: 'Apagar',\n\n    superscript: 'Superíndex',\n    subscript: 'Subíndex',\n\n    unorderedList: 'Llista desordenada',\n    orderedList: 'Llista ordenada',\n\n    insertImage: 'Inserir imatge',\n    insertVideo: 'Inserir vídeo',\n    link: 'Enllaç',\n    createLink: 'Crear un enllaç',\n    unlink: 'Eliminar enllaç',\n\n    target: 'Obertura',\n    _self: 'Mateixa pestanya',\n    _blank: 'Nova pestanya',\n\n    justifyLeft: 'Alinear a esquerra',\n    justifyCenter: 'Centrar',\n    justifyRight: 'Alinear a dreta',\n    justifyFull: 'Justificar',\n\n    horizontalRule: 'Inserir separador horitzontal',\n\n    removeformat: 'Eliminar format',\n\n    fullscreen: 'Pantalla completa',\n\n    close: 'Tancar',\n\n    submit: 'Enviar',\n    reset: 'Cancel·lar',\n\n    required: 'Obligatori',\n    description: 'Descripció',\n    title: 'Títol',\n    text: 'Text',\n\n    width: 'Amplada'\n};\n"
  },
  {
    "path": "src/langs/cs.js",
    "content": "/* ===========================================================\n * cs.js\n * Czech translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Jan Svoboda (https://github.com/svoboda-jan)\n */\n\njQuery.trumbowyg.langs.cs = {\n    viewHTML: 'Zobrazit HTML',\n\n    redo: 'Vpřed',\n    undo: 'Zpět',\n\n    formatting: 'Formátování',\n    p: 'Odstavec',\n    blockquote: 'Citace',\n    code: 'Kód',\n    header: 'Nadpis',\n\n    bold: 'Tučné',\n    italic: 'Kurzíva',\n    strikethrough: 'Přeškrtnuté',\n    underline: 'Podtržené',\n\n    strong: 'Tučné',\n    em: 'Zvýraznit',\n    del: 'Přeškrtnuté',\n\n    superscript: 'Horní index',\n    subscript: 'Dolní index',\n\n    unorderedList: 'Netříděný seznam',\n    orderedList: 'Tříděný seznam',\n\n    insertImage: 'Vložit obrázek',\n    insertVideo: 'Vložit video',\n    link: 'Odkaz',\n    createLink: 'Vložit odkaz',\n    unlink: 'Smazat odkaz',\n\n    justifyLeft: 'Zarovnat doleva',\n    justifyCenter: 'Zarovnat na střed',\n    justifyRight: 'Zarovnat doprava',\n    justifyFull: 'Zarovnat do bloku',\n\n    horizontalRule: 'Vložit vodorovnou čáru',\n\n\n    removeformat: 'Vymazat formátování',\n    fullscreen: 'Režim celé obrazovky',\n\n    close: 'Zavřít',\n\n    submit: 'Potvrdit',\n    reset: 'Zrušit',\n\n    required: 'Povinné',\n    description: 'Popis',\n    title: 'Nadpis',\n    text: 'Text',\n    target: 'Cíl'\n};\n"
  },
  {
    "path": "src/langs/da.js",
    "content": "/* ===========================================================\n * da.js\n * Danish translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Christian Pedersen\n *          Github : https://github.com/chripede\n */\n\njQuery.trumbowyg.langs.da = {\n    viewHTML: 'Vis HTML',\n\n    undo: 'Fortryd',\n    redo: 'Anuller fortryd',\n\n    formatting: 'Formattering',\n    p: 'Afsnit',\n    blockquote: 'Citat',\n    code: 'Kode',\n    header: 'Overskrift',\n\n    bold: 'Fed',\n    italic: 'Kursiv',\n    strikethrough: 'Gennemstreg',\n    underline: 'Understreg',\n\n    strong: 'Vigtig',\n    em: 'Fremhæv',\n    del: 'Slettet',\n\n    superscript: 'Hævet skrift',\n    subscript: 'Sænket skrift',\n\n    unorderedList: 'Uordnet liste',\n    orderedList: 'Ordnet liste',\n\n    insertImage: 'Indsæt billede',\n    insertVideo: 'Indsæt video',\n    link: 'Link',\n    createLink: 'Indsæt link',\n    unlink: 'Fjern link',\n\n    justifyLeft: 'Venstrestil',\n    justifyCenter: 'Centrer',\n    justifyRight: 'Højrestil',\n    justifyFull: 'Lige margener',\n\n    horizontalRule: 'Horisontal linie',\n    removeformat: 'Ryd formattering',\n\n    fullscreen: 'Fuld skærm',\n\n    close: 'Luk',\n\n    submit: 'Bekræft',\n    reset: 'Annuller',\n\n    required: 'Påkrævet',\n    description: 'Beskrivelse',\n    title: 'Titel',\n    text: 'Tekst',\n    target: 'Mål',\n    width: 'Bredde'\n};\n"
  },
  {
    "path": "src/langs/de.js",
    "content": "/* ===========================================================\n * de.js\n * German translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Manfred Timm, johangroe\n *          Github : https://github.com/Manfred62, https://github.com/johangroe\n */\n\njQuery.trumbowyg.langs.de = {\n    viewHTML: 'HTML anzeigen',\n\n    undo: 'Rückgängig',\n    redo: 'Wiederholen',\n\n    formatting: 'Formatierung',\n    p: 'Absatz',\n    blockquote: 'Zitat',\n    code: 'Code',\n    header: 'Überschrift',\n\n    bold: 'Fett',\n    italic: 'Kursiv',\n    strikethrough: 'Durchgestrichen',\n    underline: 'Unterstrichen',\n\n    strong: 'Wichtig',\n    em: 'Betont',\n    del: 'Gelöscht',\n\n    superscript: 'Hochgestellt',\n    subscript: 'Tiefgestellt',\n\n    unorderedList: 'Ungeordnete Liste',\n    orderedList: 'Geordnete Liste',\n\n    image: 'Bild',\n    insertImage: 'Bild einfügen',\n    insertVideo: 'Video einfügen',\n    link: 'Link',\n    createLink: 'Link einfügen',\n    unlink: 'Link entfernen',\n\n    _self: 'Gleicher Tab (Standard)',\n    _blank: 'Neuer Tab',\n\n    justifyLeft: 'Links ausrichten',\n    justifyCenter: 'Zentrieren',\n    justifyRight: 'Rechts ausrichten',\n    justifyFull: 'Blocksatz',\n\n    horizontalRule: 'Horizontale Linie einfügen',\n    removeformat: 'Formatierung entfernen',\n\n    fullscreen: 'Vollbild',\n\n    close: 'Schließen',\n\n    submit: 'Bestätigen',\n    reset: 'Abbrechen',\n\n    required: 'Erforderlich',\n    description: 'Beschreibung',\n    title: 'Titel',\n    text: 'Text'\n};\n"
  },
  {
    "path": "src/langs/el.js",
    "content": "/* ===========================================================\n * el.js\n * Greek translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Merianos Nikos\n *          Twitter : @_webresources\n *          Website : http://www.wp-lion.com\n *          LinkedIn: https://gr.linkedin.com/in/merianosnikos\n *          Behance: https://www.behance.net/web_design_blog\n */\n\njQuery.trumbowyg.langs.el = {\n    viewHTML: 'Προβολή κώδικα HTML',\n\n    formatting: 'Μορφοποίηση',\n    p: 'Παράγραφος',\n    blockquote: 'Παράθεση',\n    code: 'Κώδικας',\n    header: 'Επικεφαλίδα',\n\n    bold: 'Έντονα',\n    italic: 'Πλάγια',\n    strikethrough: 'Διαγραφή',\n    underline: 'Υπογράμμιση',\n\n    strong: 'Έντονα',\n    em: 'Πλάγια',\n    del: 'Διαγραφή',\n\n    unorderedList: 'Αταξινόμητη λίστα',\n    orderedList: 'Ταξινομημένη λίστα',\n\n    insertImage: 'Εισαγωγή εικόνας',\n    insertVideo: 'Εισαγωγή βίντεο',\n    link: 'Σύνδεσμος',\n    createLink: 'Δημιουργία συνδέσμου',\n    unlink: 'Διαγραφή συνδέσμου',\n\n    justifyLeft: 'Στοίχιση αριστερά',\n    justifyCenter: 'Στοίχιση στο κέντρο',\n    justifyRight: 'Στοίχιση δεξιά',\n    justifyFull: 'Πλήρης στοίχιση',\n\n    horizontalRule: 'Οριζόντια γραμμή',\n    removeformat: 'Καθαρισμός μορφοποίησης',\n\n    fullscreen: 'Πλήρης οθόνη',\n\n    close: 'Κλείσιμο',\n\n    submit: 'Υποβολή',\n    reset: 'Επαναφορά',\n\n    required: 'Απαραίτητο',\n    description: 'Περιγραφή',\n    title: 'Τίτλος',\n    text: 'Κείμενο'\n};\n"
  },
  {
    "path": "src/langs/en.js",
    "content": "/* ===========================================================\n * en.js\n * English translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Alexandre Demode (Alex-D)\n *          Twitter : @AlexandreDemode\n *          Website : alex-d.fr\n */\n\n/**\n * English is the default language of Trumbowyg,\n * you don't need to include any file :)\n */\n"
  },
  {
    "path": "src/langs/es.js",
    "content": "/* ===========================================================\n * es.js\n * Spanish translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Moisés Márquez\n *          Email : moises.marquez.g@gmail.com\n */\n\njQuery.trumbowyg.langs.es = {\n    viewHTML: 'Ver HTML',\n\n    undo: 'Deshacer',\n    redo: 'Rehacer',\n\n    formatting: 'Formato',\n    p: 'Párrafo',\n    blockquote: 'Cita',\n    code: 'Código',\n    header: 'Título',\n\n    bold: 'Negrita',\n    italic: 'Cursiva',\n    strikethrough: 'Tachado',\n    underline: 'Subrayado',\n\n    strong: 'Negrita',\n    em: 'Énfasis',\n    del: 'Borrar',\n\n    superscript: 'Sobrescrito',\n    subscript: 'Subíndice',\n\n    unorderedList: 'Lista Desordenada',\n    orderedList: 'Lista Ordenada',\n\n    insertImage: 'Insertar una imagen',\n    insertVideo: 'Insertar un vídeo',\n    link: 'Enlace',\n    createLink: 'Insertar un enlace',\n    unlink: 'Suprimir un enlace',\n\n    justifyLeft: 'Izquierda',\n    justifyCenter: 'Centrar',\n    justifyRight: 'Derecha',\n    justifyFull: 'Justificado',\n\n    horizontalRule: 'Insertar separador horizontal',\n    removeformat: 'Eliminar formato',\n\n    fullscreen: 'Pantalla completa',\n\n    close: 'Cerrar',\n\n    submit: 'Enviar',\n    reset: 'Cancelar',\n\n    required: 'Obligatorio',\n    description: 'Descripción',\n    title: 'Título',\n    text: 'Texto',\n    target: 'Target'\n};\n"
  },
  {
    "path": "src/langs/es_ar.js",
    "content": "/* ===========================================================\n * es_ar.js\n * Spanish (Argentina) translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Félix Vera\n *          Email : felix.vera@gmail.com\n */\n\n// jshint camelcase:false\njQuery.trumbowyg.langs.es_ar = {\n    viewHTML: 'Ver HTML',\n\n    formatting: 'Formato',\n    p: 'Párrafo',\n    blockquote: 'Cita',\n    code: 'Código',\n    header: 'Título',\n\n    bold: 'Negrita',\n    italic: 'Itálica',\n    strikethrough: 'Tachado',\n    underline: 'Subrayado',\n\n    strong: 'Fuere',\n    em: 'Énfasis',\n    del: 'Borrar',\n\n    unorderedList: 'Lista Desordenada',\n    orderedList: 'Lista Ordenada',\n\n    insertImage: 'Insertar una imagen',\n    insertVideo: 'Insertar un video',\n    link: 'Vínculo',\n    createLink: 'Insertar un vínculo',\n    unlink: 'Suprimir un vínculo',\n\n    justifyLeft: 'Alinear a la Izquierda',\n    justifyCenter: 'Centrar',\n    justifyRight: 'Alinear a la Derecha',\n    justifyFull: 'Justificado',\n\n    horizontalRule: 'Insertar separado Horizontal',\n\n    fullscreen: 'Pantalla Completa',\n\n    close: 'Cerrar',\n\n    submit: 'Enviar',\n    reset: 'Cancelar',\n\n    required: 'Obligatorio',\n    description: 'Descripción',\n    title: 'Título',\n    text: 'Texto'\n};\n"
  },
  {
    "path": "src/langs/et.js",
    "content": "/* ===========================================================\n * et.js\n * Estonian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Mart Leib\n *          Web: https://voogle.ee\n */\n\njQuery.trumbowyg.langs.et = {\n    viewHTML: 'HTML vaade',\n\n    undo: 'Võta tagasi',\n    redo: 'Tee uuesti',\n\n    formatting: 'Vorming',\n    p: 'Lõik',\n    blockquote: 'Plokktsitaat',\n    code: 'Kood',\n    header: 'Pealkiri',\n\n    bold: 'Paks',\n    italic: 'Kaldkiri',\n    strikethrough: 'Läbikriipsutatud',\n    underline: 'Allakriipsutatud',\n\n    strong: 'Tugev rõhutus',\n    em: 'Rõhutus',\n    del: 'Eemaldatud',\n\n    superscript: 'Ülemine indeks',\n    subscript: 'Alumine indeks',\n\n    unorderedList: 'Järjestamata loend',\n    orderedList: 'Järjestatud loend',\n\n    insertImage: 'Lisa pilt',\n    insertVideo: 'Lisa video',\n    link: 'Link',\n    createLink: 'Lisa link',\n    unlink: 'Eemalda link',\n\n    justifyLeft: 'Joonda vasakule',\n    justifyCenter: 'Joonda keskele',\n    justifyRight: 'Joonda paremale',\n    justifyFull: 'Joonda rööpselt',\n\n    horizontalRule: 'Horisontaaljoon',\n    removeformat: 'Eemalda vorming',\n\n    fullscreen: 'Täisekraan',\n\n    close: 'Sulge',\n\n    submit: 'Salvesta',\n    reset: 'Tühista',\n\n    required: 'Kohustuslik',\n    description: 'Kirjeldus',\n    title: 'Pealkiri',\n    text: 'Tekst',\n    target: 'Sihtmärk',\n    width: 'Laius'\n\n};\n"
  },
  {
    "path": "src/langs/fa.js",
    "content": "/* ===========================================================\n * fa.js\n * Persian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Kiarash Soleimanzadeh\n *          Github : https://github.com/kiyarash\n *          Email : kiarash.s@hotmail.com\n */\n\njQuery.trumbowyg.langs.fa = {\n    _dir: 'rtl',\n\n    viewHTML: 'نمایش کد اچ تی ام ال',\n\n    formatting: 'قالب بندی',\n    p: 'پاراگراف',\n    blockquote: 'نقل قول',\n    code: 'کد',\n    header: 'سر تیتر',\n\n    bold: 'ضخیم',\n    italic: 'مورب',\n    strikethrough: 'میان خط دار',\n    underline: 'زیر خط دار',\n\n    strong: 'برجسته',\n    em: 'مورب',\n    del: 'حذف شده',\n\n    unorderedList: 'لیست نامرتب',\n    orderedList: 'لیست مرتب',\n\n    insertImage: 'درج تصویر',\n    insertVideo: 'درج ویدئو',\n    link: 'لینک',\n    createLink: 'درج لینک',\n    unlink: 'حذف لینک',\n\n    justifyLeft: 'تراز به چپ',\n    justifyCenter: 'تراز به وسط',\n    justifyRight: 'تراز به راست',\n    justifyFull: 'تراز به چپ و راست',\n\n    horizontalRule: 'درج خط افقی',\n\n    fullscreen: 'تمام صفحه',\n\n    close: 'بستن',\n\n    submit: 'تائید',\n    reset: 'انصراف',\n\n    required: 'اجباری',\n    description: 'توضیحات',\n    title: 'عنوان',\n    text: 'متن'\n};\n"
  },
  {
    "path": "src/langs/fi.js",
    "content": "/* ===========================================================\n * fi.js\n * Finnish translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Teppo Koivula (teppokoivula)\n *          Github : https://github.com/teppokoivula\n */\n\njQuery.trumbowyg.langs.fi = {\n    viewHTML: 'Näytä HTML',\n\n    undo: 'Kumoa',\n    redo: 'Tee uudelleen',\n\n    formatting: 'Muotoilu',\n    p: 'Kappale',\n    blockquote: 'Lainaus',\n    code: 'Koodi',\n    header: 'Otsikko',\n\n    bold: 'Lihavointi',\n    italic: 'Kursivointi',\n    strikethrough: 'Yliviivaus',\n    underline: 'Allevivaus',\n\n    strong: 'Vahvennus',\n    em: 'Painotus',\n    del: 'Poistettu',\n\n    unorderedList: 'Luettelo',\n    orderedList: 'Numeroitu luettelo',\n\n    insertImage: 'Lisää kuva',\n    insertVideo: 'Lisää video',\n    link: 'Linkki',\n    createLink: 'Luo linkki',\n    unlink: 'Poista linkki',\n\n    justifyLeft: 'Tasaa vasemmalle',\n    justifyCenter: 'Keskitä',\n    justifyRight: 'Tasaa oikealle',\n    justifyFull: 'Tasaa',\n\n    horizontalRule: 'Vaakaviiva',\n\n    fullscreen: 'Kokoruutu',\n\n    close: 'Sulje',\n\n    submit: 'Lisää',\n    reset: 'Palauta',\n\n    required: 'Pakollinen',\n    description: 'Kuvaus',\n    title: 'Otsikko',\n    text: 'Teksti'\n};\n"
  },
  {
    "path": "src/langs/fr.js",
    "content": "/* ===========================================================\n * fr.js\n * French translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Alexandre Demode (Alex-D)\n *          Twitter : @AlexandreDemode\n *          Website : alex-d.fr\n * Reviewed by : Abdou Developer (test20091)\n * \t    Github : https://github.com/test20091\n */\n\njQuery.trumbowyg.langs.fr = {\n    viewHTML: 'Voir le HTML',\n\n    undo: 'Annuler',\n    redo: 'Refaire',\n\n    formatting: 'Format',\n    p: 'Paragraphe',\n    blockquote: 'Citation',\n    code: 'Code',\n    header: 'Titre',\n\n    bold: 'Gras',\n    italic: 'Italique',\n    strikethrough: 'Barré',\n    underline: 'Souligné',\n\n    strong: 'Fort',\n    em: 'Emphase',\n    del: 'Supprimé',\n\n    superscript: 'Exposant',\n    subscript: 'Indice',\n\n    unorderedList: 'Liste à puces',\n    orderedList: 'Liste ordonnée',\n\n    insertImage: 'Insérer une image',\n    insertVideo: 'Insérer une video',\n    link: 'Lien',\n    createLink: 'Insérer un lien',\n    unlink: 'Supprimer le lien',\n\n    _self: 'Même onglet (par défaut)',\n    _blank: 'Nouvel onglet',\n\n    justifyLeft: 'Aligner à gauche',\n    justifyCenter: 'Centrer',\n    justifyRight: 'Aligner à droite',\n    justifyFull: 'Justifier',\n\n    horizontalRule: 'Insérer un séparateur horizontal',\n    removeformat: 'Supprimer formatage',\n\n    fullscreen: 'Plein écran',\n\n    close: 'Fermer',\n\n    submit: 'Valider',\n    reset: 'Annuler',\n\n    required: 'Obligatoire',\n    description: 'Description',\n    title: 'Titre',\n    text: 'Texte',\n    target: 'Cible'\n};\n"
  },
  {
    "path": "src/langs/he.js",
    "content": "/* ===========================================================\n * he.js\n * Hebrew translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Udi Doron (udidoron)\n *          Github : https://github.com/udidoron\n */\n\njQuery.trumbowyg.langs.he = {\n    _dir: 'rtl',\n\n    viewHTML: 'צפה ב-HTML',\n\n    formatting: 'פורמט',\n    p: 'פסקה',\n    blockquote: 'ציטוט',\n    code: 'קוד',\n    header: 'ראשית',\n\n    bold: 'מודגש',\n    italic: 'נטוי',\n    strikethrough: 'קו חוצה',\n    underline: 'קו תחתון',\n\n    strong: 'בולט',\n    em: 'הדגשה',\n    del: 'נמחק',\n\n    unorderedList: 'רשימה ללא סדר',\n    orderedList: 'רשימה מסודרת',\n\n    insertImage: 'הכנס תמונה',\n    insertVideo: 'הכנס סרטון',\n    link: 'קישור',\n    createLink: 'צור קישור',\n    unlink: 'הסר קישור',\n\n    justifyLeft: 'ישר לשמאל',\n    justifyCenter: 'מרכז',\n    justifyRight: 'ישר לימין',\n    justifyFull: 'ישר לשני הצדדים',\n\n    horizontalRule: 'הכנס קו אופקי',\n\n    fullscreen: 'מסך מלא',\n\n    close: 'סגור',\n\n    submit: 'שלח',\n    reset: 'אתחל מחדש',\n\n    required: 'נחוץ',\n    description: 'תיאור',\n    title: 'כותרת',\n    text: 'טקסט'\n};\n"
  },
  {
    "path": "src/langs/hr.js",
    "content": "/* ===========================================================\n * hr.js\n * Croatian translation for Trumbowyg\n * https://www.github.com/Buda9\n * ===========================================================\n * Author : Davor Budimir (https://www.github.com/Buda9)\n */\n\n// jshint camelcase:false\njQuery.trumbowyg.langs.hr = {\n    viewHTML: 'Poglеdaj HTML kód',\n\n    formatting: 'Formatiranjе',\n    p: 'Odlomak',\n    blockquote: 'Citat',\n    code: 'Kód',\n    header: 'Zaglavlje',\n\n    bold: 'Podеbljano',\n    italic: 'Nakošeno',\n    strikethrough: 'Prеcrtano',\n    underline: 'Podvučеno',\n\n    strong: 'Podеbljano',\n    em: 'Istaknuto',\n    del: 'Obrisano',\n\n    unorderedList: 'Neuređen popis',\n    orderedList: 'Uređen popis',\n    insertImage: 'Dodaj sliku',\n    insertVideo: 'Dodaj vidеo',\n    link: 'Povezica',\n    createLink: 'Dodaj povezicu',\n    unlink: 'Ukloni povezicu',\n\n    justifyLeft: 'Lijеvo poravnanjе',\n    justifyCenter: 'Središnje poravnanjе',\n    justifyRight: 'Dеsno poravnanjе',\n    justifyFull: 'Obostrano poravnanjе',\n\n    horizontalRule: 'Horizontalna crta',\n\n    fullscreen: 'Puni zaslon',\n\n    close: 'Zatvori',\n\n    submit: 'Unеsi',\n    reset: 'Otkaži',\n\n    required: 'Obavеzno poljе',\n    description: 'Opis',\n    title: 'Naslov',\n    text: 'Tеkst'\n};\n"
  },
  {
    "path": "src/langs/hu.js",
    "content": "/* ===========================================================\n * hu.js\n * Hungarian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Peter MATO\n *          Web: http://fixme.hu\n *          GitHub: https://github.com/matopeter\n */\n\njQuery.trumbowyg.langs.hu = {\n    viewHTML: 'HTML nézet',\n\n    undo: 'Visszavon',\n    redo: 'Visszállít',\n\n    formatting: 'Stílusok',\n\n    p: 'Bekezdés',\n    blockquote: 'Idézet',\n    code: 'Kód',\n    header: 'Címsor',\n\n    bold: 'Félkövér',\n    italic: 'Dőlt',\n    strikethrough: 'Áthúzott',\n    underline: 'Aláhúzott',\n\n    strong: 'Vastag',\n    em: 'Kiemelt',\n    del: 'Törölt',\n\n    unorderedList: 'Felsorolás',\n    orderedList: 'Számozás',\n\n    insertImage: 'Kép beszúrása',\n    insertVideo: 'Video beszúrása',\n    link: 'Link',\n    createLink: 'Link létrehozása',\n    unlink: 'Link eltávolítása',\n\n    justifyLeft: 'Balra igazítás',\n    justifyCenter: 'Középre igazítás',\n    justifyRight: 'Jobbra igazítás',\n    justifyFull: 'Sorkizárt',\n\n    horizontalRule: 'Vízszintes vonal',\n\n    fullscreen: 'Teljes képernyő',\n    close: 'Bezár',\n\n    submit: 'Beküldés',\n    reset: 'Alaphelyzet',\n\n    required: 'Kötelező',\n    description: 'Leírás',\n    title: 'Cím',\n    text: 'Szöveg',\n\n    removeformat: 'Formázás eltávolítása'\n};\n"
  },
  {
    "path": "src/langs/id.js",
    "content": "/* ===========================================================\n * id.js\n * Indonesian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Rezha Julio (kimiamania)\n *          Twitter : @kimiamania\n *          Website : http://rezhajulio.web.id\n *          Github : https://github.com/kimiamania\n */\n\njQuery.trumbowyg.langs.id = {\n    viewHTML: 'Lihat HTML',\n\n    formatting: 'Penyusunan',\n    p: 'Paragraf',\n    blockquote: 'Kutipan',\n    code: 'Kode',\n    header: 'Kepala',\n\n    bold: 'Tebal',\n    italic: 'Miring',\n    strikethrough: 'Coret',\n    underline: 'Garis bawah',\n\n    strong: 'Tebal',\n    em: 'Miring',\n    del: 'Dicoret',\n\n    unorderedList: 'Daftar tak teratur',\n    orderedList: 'Daftar teratur',\n\n    insertImage: 'Sisipkan gambar',\n    insertVideo: 'Sisipkan video',\n    link: 'Tautan',\n    createLink: 'Sisipkan Tautan',\n    unlink: 'Singkirkan tautan',\n\n    justifyLeft: 'Rata kiri',\n    justifyCenter: 'Rata Tengah',\n    justifyRight: 'Rata kanan',\n    justifyFull: 'Rata kiri dan kanan',\n\n    horizontalRule: 'Sisipkan garis mendatar',\n\n    fullscreen: 'Layar penuh',\n\n    close: 'Tutup',\n\n    submit: 'Setuju',\n    reset: 'Batal',\n\n    required: 'Diperlukan',\n    description: 'Deskripsi',\n    title: 'Judul',\n    text: 'Teks'\n};\n"
  },
  {
    "path": "src/langs/it.js",
    "content": "/* ===========================================================\n * it.js\n * Italian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Mirko Buffoni\n */\n\njQuery.trumbowyg.langs.it = {\n    viewHTML: 'Mostra HTML',\n\n    undo: 'Annulla',\n    redo: 'Ripeti',\n\n    formatting: 'Formattazione',\n    p: 'Paragrafo',\n    blockquote: 'Citazione',\n    code: 'Codice',\n    header: 'Intestazione',\n\n    bold: 'Grassetto',\n    italic: 'Italico',\n    strikethrough: 'Barrato',\n    underline: 'Sottolineato',\n\n    strong: 'Rafforza',\n    em: 'Enfatizza',\n    del: 'Cancella',\n\n    unorderedList: 'Elenco puntato',\n    orderedList: 'Elenco numerato',\n\n    insertImage: 'Inserisci immagine',\n    insertVideo: 'Inserisci video',\n    link: 'Collegamento',\n    createLink: 'Crea un collegamento',\n    unlink: 'Elimina collegamento',\n\n    justifyLeft: 'Allinea a sinistra',\n    justifyCenter: 'Centra',\n    justifyRight: 'Allinea a destra',\n    justifyFull: 'Giustifica',\n\n    horizontalRule: 'Inserisci un separatore orizzontale',\n\n    fullscreen: 'Schermo intero',\n\n    close: 'Chiudi',\n\n    submit: 'Invia',\n    reset: 'Annulla',\n\n    required: 'Obbligatorio',\n    description: 'Descrizione',\n    title: 'Titolo',\n    text: 'Testo',\n\n    removeformat: 'Rimuovi Formattazione',\n\n    superscript: 'Apice',\n    subscript: 'Pedice'\n};\n"
  },
  {
    "path": "src/langs/ja.js",
    "content": "/* ===========================================================\n * ja.js\n * Japanese translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Kouta Fukuhara (foo9)\n *          Twitter : @foo9\n *          Website : https://github.com/foo9\n */\n\njQuery.trumbowyg.langs.ja = {\n    viewHTML: 'HTML表示',\n\n    undo: '元に戻す',\n    redo: 'やり直す',\n\n    formatting: 'フォーマット',\n    p: '段落',\n    blockquote: '引用',\n    code: 'コード',\n    header: '見出し',\n\n    bold: '太字',\n    italic: '斜体',\n    strikethrough: '取り消し線',\n    underline: '下線',\n\n    strong: '太字',\n    em: '斜体',\n    del: '取り消し線',\n\n    superscript: '上付き文字',\n    subscript: '下付き文字',\n\n    unorderedList: '順序なしリスト',\n    orderedList: '順序ありリスト',\n\n    insertImage: '画像の挿入',\n    link: 'リンク',\n    createLink: 'リンクの作成',\n    unlink: 'リンクの削除',\n\n    justifyLeft: '左揃え',\n    justifyCenter: '中央揃え',\n    justifyRight: '右揃え',\n    justifyFull: '両端揃え',\n\n    horizontalRule: '横罫線',\n    removeformat: 'フォーマットの削除',\n\n    fullscreen: '全画面表示',\n\n    close: '閉じる',\n\n    submit: '送信',\n    reset: 'キャンセル',\n\n    required: '必須',\n    description: '説明',\n    title: 'タイトル',\n    text: 'テキスト',\n    target: 'ターゲット'\n};\n"
  },
  {
    "path": "src/langs/ko.js",
    "content": "/* ===========================================================\n * ko.js\n * Korean translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : SeungWoo Chae (SDuck4)\n *          Github : https://github.com/SDuck4\n *          Victor Chanil Park (opdev1004)\n *          Github : https://github.com/opdev1004\n */\n\njQuery.trumbowyg.langs.ko = {\n    viewHTML: 'HTML 보기',\n\n    undo: '되돌리기',\n    redo: '다시 실행',\n\n    formatting: '스타일',\n    p: '본문',\n    blockquote: '인용문',\n    code: '코드',\n    header: '제목',\n\n    bold: '진하게',\n    italic: '기울임',\n    strikethrough: '취소선',\n    underline: '밑줄',\n\n    strong: '중요',\n    em: '강조',\n    del: '삭제',\n\n    superscript: '위 첨자',\n    subscript: '아래 첨자',\n\n    unorderedList: '기호 목록',\n    orderedList: '번호 목록',\n\n    insertImage: '이미지 넣기',\n    insertVideo: '비디오 넣기',\n    link: '링크',\n    createLink: '링크 넣기',\n    unlink: '링크 지우기',\n\n    justifyLeft: '왼쪽 정렬',\n    justifyCenter: '가운데 정렬',\n    justifyRight: '오른쪽 정렬',\n    justifyFull: '양쪽 정렬',\n\n    horizontalRule: '구분선 넣기',\n    removeformat: '글꼴 효과 지우기',\n\n    fullscreen: '전체 화면',\n\n    close: '닫기',\n\n    submit: '확인',\n    reset: '취소',\n\n    required: '필수 입력',\n    description: '설명',\n    title: '툴팁',\n    text: '내용',\n    target: '타겟',\n    width: '너비'\n};\n"
  },
  {
    "path": "src/langs/lt.js",
    "content": "/* ===========================================================\n * lt.js\n * Lithuanian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Justas Brazauskas\n */\n\njQuery.trumbowyg.langs.lt = {\n    viewHTML: 'Žiūrėti HTML',\n\n    formatting: 'Formatuoti',\n    p: 'Paragrafas',\n    blockquote: 'Citata',\n    code: 'Kodas',\n    header: 'Antraštė',\n\n    bold: 'Paryškinti',\n    italic: 'Kursyvuoti',\n    strikethrough: 'Perbraukti',\n    underline: 'Pabrėžti',\n\n    strong: 'Paryškinti',\n    em: 'Pabrėžti',\n    del: 'Trinti',\n\n    unorderedList: 'Sąrašas',\n    orderedList: 'Numeruotas sąrašas',\n\n    insertImage: 'Pridėti vaizdą',\n    insertVideo: 'Pridėti video',\n    link: 'Nuoroda',\n    createLink: 'Kurti nuorodą',\n    unlink: 'Ištrinti nuorodą',\n\n    justifyLeft: 'Lyginti kairėn',\n    justifyCenter: 'Lygiuoti Centre',\n    justifyRight: 'Lyginti dešinėn',\n    justifyFull: 'Centruoti',\n\n    horizontalRule: 'Horizontali linija',\n\n    fullscreen: 'Pilnas ekranas',\n\n    close: 'Uždaryti',\n\n    submit: 'Siųsti',\n    reset: 'Atšaukti',\n\n    required: 'Privaloma',\n    description: 'Aprašymas',\n    title: 'Pavadinimas',\n    text: 'Tekstas',\n\n    removeformat: 'Pašalinti formatavimą',\n\n    superscript: 'Viršutinis indeksas',\n    subscript: 'Apatinis indeksas'\n};\n"
  },
  {
    "path": "src/langs/mn.js",
    "content": "/* ===========================================================\n * mn.js\n * Mongolian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Ganbayar.B (ganbayar13)\n */\n\njQuery.trumbowyg.langs.mn = {\n    viewHTML: 'HTML харах',\n    undo: 'Буцаах',\n    redo: 'Дахих',\n    formatting: 'Формат',\n    p: 'Догол мөр',\n    blockquote: 'Ишлэл',\n    code: 'Код',\n    header: 'Гарчиг',\n    bold: 'Тод',\n    italic: 'Налуу',\n    strikethrough: 'Дундуур зураас',\n    underline: 'Доогуур зураас',\n    strong: 'Тод',\n    em: 'Налуу',\n    del: 'Дундуур зураас',\n    superscript: 'Дээд индекс',\n    subscript: 'Доод индекс',\n    unorderedList: 'Дугаарлаагүй жагсаалт',\n    orderedList: 'Дугаарласан жагсаалт',\n    insertImage: 'Зураг оруулах',\n    insertVideo: 'Видео оруулах',\n    link: 'Холбоос',\n    createLink: 'Холбоос үүсгэх',\n    unlink: 'Холбоос цуцлах',\n    justifyLeft: 'Зүүн тийш шахах',\n    justifyCenter: 'Голлуулах',\n    justifyRight: 'Баруун Баруун тийш шахах',\n    justifyFull: 'Тэгшитгэх',\n    horizontalRule: 'Хөндлөн шугам',\n    removeformat: 'Формат арилгах',\n    fullscreen: 'Дэлгэц дүүргэх',\n    close: 'Хаах',\n    submit: 'Оруулах',\n    reset: 'Цуцлах',\n    required: 'Шаардлагатай',\n    description: 'Тайлбар',\n    title: 'Гарчиг',\n    text: 'Текст',\n    target: 'Бай'\n};\n"
  },
  {
    "path": "src/langs/my.js",
    "content": "/* ===========================================================\n * my.js\n * Malaysian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : JohnPozy\n */\n\njQuery.trumbowyg.langs.id = {\n    viewHTML: 'Lihat HTML',\n\n    formatting: 'Pemformatan',\n    p: 'Perenggan',\n    blockquote: 'Blockquote',\n    code: 'Kod',\n    header: 'Pengepala',\n\n    bold: 'Tebal',\n    italic: 'Condong',\n    strikethrough: 'Garis batal',\n    underline: 'Garis bawah',\n\n    strong: 'Kuat',\n    em: 'Condong',\n    del: 'Hapus',\n\n    unorderedList: 'Senarai tidak tertib',\n    orderedList: 'Senarai tertib',\n\n    insertImage: 'Masukkan imej',\n    insertVideo: 'Masukkan video',\n    link: 'Pautan',\n    createLink: 'Cipta pautan',\n    unlink: 'Hapus pautan',\n\n    justifyLeft: 'Mengimbangkan ke kiri',\n    justifyCenter: 'Mengimbangkan ke tengah',\n    justifyRight: 'Mengimbangkan ke kanan',\n    justifyFull: 'Mengimbangkan ke kiri dan kanan',\n\n    horizontalRule: 'Masukkan garis mendatar',\n\n    fullscreen: 'Skrin penuh',\n\n    close: 'Tutup',\n\n    submit: 'Hantar',\n    reset: 'Batal',\n\n    required: 'Diperlukan',\n    description: 'Perihal',\n    title: 'Tajuk',\n    text: 'Teks'\n};\n"
  },
  {
    "path": "src/langs/nb.js",
    "content": "/* ===========================================================\n * nb.js\n * Norwegian Bokmål translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Jon Severin Eivik Jakobsen\n *          Github : https://github.com/jsejakobsen\n *\n * Mod by:  Gunnar Tjomlid\n *          Github : https://github.com/civix74\n *          Twitter : @civix\n *          Website : https://about.me/civix\n */\n\n// jshint camelcase:false\njQuery.trumbowyg.langs.nb = {\n    viewHTML: 'Vis HTML',\n\n    undo: 'Angre',\n    redo: 'Gjør om',\n\n    formatting: 'Formater',\n    p: 'Avsnitt',\n    blockquote: 'Sitat',\n    code: 'Kode',\n    header: 'Overskrift',\n\n    bold: 'Fet',\n    italic: 'Kursiv',\n    strikethrough: 'Gjennomstreking',\n    underline: 'Understreking',\n\n    strong: 'Uthevet',\n    em: 'Kursiv',\n    del: 'Slettet',\n\n    superscript: 'Hevet',\n    subscript: 'Senket',\n\n    unorderedList: 'Punktliste',\n    orderedList: 'Nummerert liste',\n\n    insertImage: 'Sett inn bilde',\n    insertVideo: 'Sett inn video',\n    link: 'Lenke',\n    createLink: 'Sett inn lenke',\n    unlink: 'Fjern lenke',\n\n    justifyLeft: 'Venstrejuster',\n    justifyCenter: 'Midtstill',\n    justifyRight: 'Høyrejuster',\n    justifyFull: 'Blokkjuster',\n\n    horizontalRule: 'Horisontal linje',\n    removeformat: 'Fjern formatering',\n\n    fullscreen: 'Fullskjerm',\n\n    close: 'Lukk',\n\n    submit: 'Bekreft',\n    reset: 'Avbryt',\n\n    required: 'Påkrevd',\n    description: 'Beskrivelse',\n    title: 'Tittel',\n    text: 'Tekst',\n    target: 'Mål',\n    width: 'Bredde'\n};\n"
  },
  {
    "path": "src/langs/nl.js",
    "content": "/* ===========================================================\n * nl.js\n * Dutch translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Danny Hiemstra\n *          Github : https://github.com/dhiemstra\n */\n\njQuery.trumbowyg.langs.nl = {\n    viewHTML: 'HTML bekijken',\n\n    undo: 'Ongedaan maken',\n    redo: 'Opnieuw',\n\n    formatting: 'Opmaak',\n    p: 'Paragraaf',\n    blockquote: 'Citaat',\n    code: 'Code',\n    header: 'Kop',\n\n    bold: 'Vet',\n    italic: 'Cursief',\n    strikethrough: 'Doorhalen',\n    underline: 'Onderlijnen',\n\n    strong: 'Sterk',\n    em: 'Nadruk',\n    del: 'Verwijderd',\n\n    unorderedList: 'Ongenummerde lijst',\n    orderedList: 'Genummerde lijst',\n\n    insertImage: 'Afbeelding invoegen',\n    insertVideo: 'Video invoegen',\n    link: 'Link',\n    createLink: 'Link maken',\n    unlink: 'Link verwijderen',\n\n    justifyLeft: 'Links uitlijnen',\n    justifyCenter: 'Centreren',\n    justifyRight: 'Rechts uitlijnen',\n    justifyFull: 'Uitvullen',\n\n    horizontalRule: 'Horizontale lijn',\n    removeFormat: 'Opmaak verwijderen',\n\n    fullscreen: 'Volledig scherm',\n\n    close: 'Sluiten',\n\n    submit: 'Opslaan',\n    reset: 'Annuleren',\n\n    required: 'Verplicht',\n    description: 'Omschrijving',\n    title: 'Titel',\n    text: 'Tekst',\n    target: 'Doel',\n    width: 'Breedte'\n};\n"
  },
  {
    "path": "src/langs/ph.js",
    "content": "/* ===========================================================\n * ph.js\n * Filipino translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : @leogono\n */\n\njQuery.trumbowyg.langs.ph = {\n    viewHTML: 'Tumingin sa HTML',\n\n    formatting: 'Formatting',\n    p: 'Talata',\n    blockquote: 'Blockquote',\n    code: 'Kowd',\n    header: 'Header',\n\n    bold: 'Makapal',\n    italic: 'Hilig',\n    strikethrough: 'Strikethrough',\n    underline: 'Salungguhit',\n\n    strong: 'Malakas',\n    em: 'Hilig',\n    del: 'Tinanggal',\n\n    unorderedList: 'Hindi nakahanay na listahan',\n    orderedList: 'Nakahanay na listahan',\n\n    insertImage: 'Ilagay ang larawan',\n    insertVideo: 'Ilagay ang video',\n    link: 'Koneksyon',\n    createLink: 'Iugnay',\n    unlink: 'Tanggalin ang koneksyon',\n\n    justifyLeft: 'Ihanay sa kaliwa',\n    justifyCenter: 'Ihanay sa gitna',\n    justifyRight: 'Ihanay sa kanan',\n    justifyFull: 'Ihanay sa kaliwa at kanan',\n\n    horizontalRule: 'Pahalang na linya',\n\n    fullscreen: 'Fullscreen',\n\n    close: 'Isara',\n\n    submit: 'Ipasa',\n    reset: 'I-reset',\n\n    required: 'Kailangan',\n    description: 'Paglalarawan',\n    title: 'Pamagat',\n    text: 'Teksto'\n};\n"
  },
  {
    "path": "src/langs/pl.js",
    "content": "/* ===========================================================\n * pl.js\n * Polish translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Paweł Abramowicz\n *          Github : https://github.com/pawelabrams\n */\n\njQuery.trumbowyg.langs.pl = {\n    viewHTML: 'Pokaż HTML',\n\n    formatting: 'Format',\n    p: 'Akapit',\n    blockquote: 'Cytat',\n    code: 'Kod',\n    header: 'Nagłówek',\n\n    bold: 'Pogrubienie',\n    italic: 'Pochylenie',\n    strikethrough: 'Przekreślenie',\n    underline: 'Podkreślenie',\n\n    strong: 'Wytłuszczenie',\n    em: 'Uwydatnienie',\n    del: 'Usunięte',\n\n    unorderedList: 'Lista nieuporządkowana',\n    orderedList: 'Lista uporządkowana',\n\n    insertImage: 'Wstaw obraz',\n    insertVideo: 'Wstaw film',\n    link: 'Link',\n    createLink: 'Wstaw link',\n    unlink: 'Usuń link',\n\n    justifyLeft: 'Wyrównaj do lewej',\n    justifyCenter: 'Wyśrodkuj',\n    justifyRight: 'Wyrównaj do prawej',\n    justifyFull: 'Wyjustuj',\n\n    horizontalRule: 'Odkreśl linią',\n\n    fullscreen: 'Pełny ekran',\n\n    close: 'Zamknij',\n\n    submit: 'Zastosuj',\n    reset: 'Przywróć',\n\n    required: 'Wymagane',\n    description: 'Opis',\n    title: 'Tytuł',\n    text: 'Tekst'\n};\n"
  },
  {
    "path": "src/langs/pt.js",
    "content": "/* ===========================================================\n * pt.js\n * Portuguese translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Ramiro Varandas Jr (ramirovjr)\n *          Twitter : @ramirovjnr\n *          Website : about.me/ramirovjnr\n *          Github : https://github.com/ramirovjr\n */\n\njQuery.trumbowyg.langs.pt = {\n    viewHTML: 'Ver HTML',\n\n    undo: 'Desfazer',\n    redo: 'Refazer',\n\n    formatting: 'Formatar',\n    p: 'Paragráfo',\n    blockquote: 'Citação',\n    code: 'Código',\n    header: 'Título',\n\n    bold: 'Negrito',\n    italic: 'Itálico',\n    strikethrough: 'Suprimir',\n    underline: 'Sublinhado',\n\n    strong: 'Negrito',\n    em: 'Ênfase',\n    del: 'Apagar',\n\n    superscript: 'Sobrescrito',\n    subscript: 'Subscrito',\n\n    unorderedList: 'Lista não ordenada',\n    orderedList: 'Lista ordenada',\n\n    insertImage: 'Inserir imagem',\n    insertVideo: 'Inserir vídeo',\n    link: 'Link',\n    createLink: 'Criar um link',\n    unlink: 'Remover link',\n\n    justifyLeft: 'Alinhar a esquerda',\n    justifyCenter: 'Centralizar',\n    justifyRight: 'Alinhar a direita',\n    justifyFull: 'Justificar',\n\n    horizontalRule: 'Inserir separador horizontal',\n    removeformat: 'Remover formatação',\n\n    fullscreen: 'Tela cheia',\n\n    close: 'Fechar',\n\n    submit: 'Enviar',\n    reset: 'Limpar',\n\n    required: 'Obrigatório',\n    description: 'Descrição',\n    title: 'Título',\n    text: 'Texto',\n    target: 'Target'\n};\n"
  },
  {
    "path": "src/langs/pt_br.js",
    "content": "/* ===========================================================\n * pt_br.js\n * Portuguese Brazilian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Alex Gotardi (alexgotardi)\n *          Twitter : @alexgotardi\n *          Github : https://github.com/alexgotardi\n */\n\n// jshint camelcase:false\njQuery.trumbowyg.langs.pt_br = {\n    viewHTML: 'Ver HTML',\n\n    undo: 'Desfazer',\n    redo: 'Refazer',\n\n    formatting: 'Formatar',\n    p: 'Parágrafo',\n    blockquote: 'Citação',\n    code: 'Código',\n    header: 'Título',\n\n    bold: 'Negrito',\n    italic: 'Itálico',\n    strikethrough: 'Tachado',\n    underline: 'Sublinhado',\n\n    strong: 'Negrito',\n    em: 'Ênfase',\n    del: 'Apagar',\n\n    superscript: 'Sobrescrito',\n    subscript: 'Subscrito',\n\n    unorderedList: 'Lista não ordenada',\n    orderedList: 'Lista ordenada',\n\n    insertImage: 'Inserir imagem',\n    insertVideo: 'Inserir vídeo',\n    link: 'Link',\n    createLink: 'Criar um link',\n    unlink: 'Remover link',\n\n    justifyLeft: 'Alinhar a esquerda',\n    justifyCenter: 'Centralizar',\n    justifyRight: 'Alinhar a direita',\n    justifyFull: 'Justificar',\n\n    horizontalRule: 'Inserir separador horizontal',\n    removeformat: 'Remover formatação',\n\n    fullscreen: 'Tela cheia',\n\n    close: 'Fechar',\n\n    submit: 'Enviar',\n    reset: 'Limpar',\n\n    required: 'Obrigatório',\n    description: 'Descrição',\n    title: 'Título',\n    text: 'Texto',\n    target: 'Alvo'\n};\n"
  },
  {
    "path": "src/langs/ro.js",
    "content": "/* ===========================================================\n * ro.js\n * Romanian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Vladut Radulescu (pacMakaveli)\n *          Email: pacMakaveli90@gmail.com\n *          Twitter : @pacMakaveli90\n *          Website : creative-studio51.co.uk\n *          Github : https://github.com/pacMakaveli\n */\n\njQuery.trumbowyg.langs.ro = {\n    viewHTML: 'Vizualizare HTML',\n\n    formatting: 'Format',\n    p: 'Paragraf',\n    blockquote: 'Citație',\n    code: 'Cod',\n    header: 'Titlu',\n\n    bold: 'Bold',\n    italic: 'Italic',\n    strikethrough: 'Tăiat',\n    underline: 'Subliniat',\n\n    strong: 'Puternic',\n    em: 'Accentuat',\n    del: 'Sterge',\n\n    unorderedList: 'Lista dezordonată',\n    orderedList: 'Liste ordonată',\n\n    insertImage: 'Adăugare Imagine',\n    insertVideo: 'Adăugare Video',\n    link: 'Link',\n    createLink: 'Crează link',\n    unlink: 'Remover link',\n\n    justifyLeft: 'Aliniază stânga',\n    justifyCenter: 'Aliniază centru',\n    justifyRight: 'Aliniază dreapta',\n    justifyFull: 'Justificare',\n\n    horizontalRule: 'Linie orizontală',\n\n    fullscreen: 'Tot ecranul',\n\n    close: 'Închide',\n\n    submit: 'Procesează',\n    reset: 'Resetează',\n\n    required: 'Obligatoriu',\n    description: 'Descriere',\n    title: 'Titlu',\n    text: 'Text'\n};\n"
  },
  {
    "path": "src/langs/rs.js",
    "content": "/* ===========================================================\n * rs.js\n * Serbian (Cyrlic) translation for Trumbowyg\n * https://www.github.com/johonunu\n * ===========================================================\n * Author : Nikola Trifunovic (https://www.github.com/johonunu)\n */\n\njQuery.trumbowyg.langs.rs = {\n    viewHTML: 'Погледај HTML кóд',\n\n    formatting: 'Форматирање',\n    p: 'Параграф',\n    blockquote: 'Цитат',\n    code: 'Кóд',\n    header: 'Наслов',\n\n    bold: 'Подебљано',\n    italic: 'Курзив',\n    strikethrough: 'Прецртано',\n    underline: 'Подвучено',\n\n    strong: 'Подебљано',\n    em: 'Истакнуто',\n    del: 'Обрисано',\n\n    unorderedList: 'Ненабројива листа',\n    orderedList: 'Набројива листа',\n    insertImage: 'Унеси слику',\n    insertVideo: 'Унеси видео',\n    link: 'Линк',\n    createLink: 'Унеси линк',\n    unlink: 'Уклони линк',\n\n    justifyLeft: 'Лево равнање',\n    justifyCenter: 'Централно равнање',\n    justifyRight: 'Десно равнање',\n    justifyFull: 'Обострано равнање',\n\n    horizontalRule: 'Хоризонтална линија',\n\n    fullscreen: 'Режим читавог екрана',\n\n    close: 'Затвори',\n\n    submit: 'Унеси',\n    reset: 'Откажи',\n\n    required: 'Обавезно поље',\n    description: 'Опис',\n    title: 'Наслов',\n    text: 'Текст'\n};\n"
  },
  {
    "path": "src/langs/rs_latin.js",
    "content": "/* ===========================================================\n * rs_latin.js\n * Serbian (Latin) translation for Trumbowyg\n * https://www.github.com/johonunu\n * ===========================================================\n * Author : Nikola Trifunovic (https://www.github.com/johonunu)\n */\n\n// jshint camelcase:false\njQuery.trumbowyg.langs.rs_latin = {\n    viewHTML: 'Poglеdaj HTML kód',\n\n    formatting: 'Formatiranjе',\n    p: 'Paragraf',\n    blockquote: 'Citat',\n    code: 'Kód',\n    header: 'Naslov',\n\n    bold: 'Podеbljano',\n    italic: 'Kurziv',\n    strikethrough: 'Prеcrtano',\n    underline: 'Podvučеno',\n\n    strong: 'Podеbljano',\n    em: 'Istaknuto',\n    del: 'Obrisano',\n\n    unorderedList: 'Nеnabrojiva lista',\n    orderedList: 'Nabrojiva lista',\n    insertImage: 'Unеsi sliku',\n    insertVideo: 'Unеsi vidеo',\n    link: 'Link',\n    createLink: 'Unеsi link',\n    unlink: 'Ukloni link',\n\n    justifyLeft: 'Lеvo ravnanjе',\n    justifyCenter: 'Cеntralno ravnanjе',\n    justifyRight: 'Dеsno ravnanjе',\n    justifyFull: 'Obostrano ravnanjе',\n\n    horizontalRule: 'Horizontalna linija',\n\n    fullscreen: 'Rеžim čitavog еkrana',\n\n    close: 'Zatvori',\n\n    submit: 'Unеsi',\n    reset: 'Otkaži',\n\n    required: 'Obavеzno poljе',\n    description: 'Opis',\n    title: 'Naslov',\n    text: 'Tеkst'\n};\n"
  },
  {
    "path": "src/langs/ru.js",
    "content": "/* ===========================================================\n * ru.js\n * Russian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Yuri Lya\n */\n\njQuery.trumbowyg.langs.ru = {\n    viewHTML: 'Посмотреть HTML',\n\n    undo: 'Отменить',\n    redo: 'Повторить',\n\n    formatting: 'Форматирование',\n    p: 'Обычный',\n    blockquote: 'Цитата',\n    code: 'Код',\n    header: 'Заголовок',\n\n    bold: 'Полужирный',\n    italic: 'Курсив',\n    strikethrough: 'Зачеркнутый',\n    underline: 'Подчеркнутый',\n\n    strong: 'Полужирный',\n    em: 'Курсив',\n    del: 'Зачеркнутый',\n\n    superscript: 'Надстрочный',\n    subscript: 'Подстрочный',\n\n    unorderedList: 'Обычный список',\n    orderedList: 'Нумерованный список',\n\n    insertImage: 'Вставить изображение',\n    insertVideo: 'Вставить видео',\n    link: 'Ссылка',\n    createLink: 'Вставить ссылку',\n    unlink: 'Удалить ссылку',\n\n    justifyLeft: 'По левому краю',\n    justifyCenter: 'По центру',\n    justifyRight: 'По правому краю',\n    justifyFull: 'По ширине',\n\n    horizontalRule: 'Горизонтальная линия',\n    removeformat: 'Очистить форматирование',\n\n    fullscreen: 'Во весь экран',\n\n    close: 'Закрыть',\n\n    submit: 'Вставить',\n    reset: 'Отменить',\n\n    required: 'Обязательное',\n    description: 'Описание',\n    title: 'Подсказка',\n    text: 'Текст'\n};\n"
  },
  {
    "path": "src/langs/sk.js",
    "content": "/* ===========================================================\n * sk.js\n * Slovak translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : VeeeneX (https://github.com/VeeeneX)\n */\n\njQuery.trumbowyg.langs.sk = {\n    viewHTML: 'Zobraziť HTML',\n\n    formatting: 'Formátovanie',\n    p: 'Paragraf',\n    blockquote: 'Citácia',\n    code: 'Kód',\n    header: 'Nadpis',\n\n    bold: 'Tučné',\n    italic: 'Kurzíva',\n    strikethrough: 'Preškrtnuté',\n    underline: 'Podčiarknuté',\n\n    strong: 'Tučné',\n    em: 'Zvýrazniť',\n    del: 'Zmazať',\n\n    unorderedList: 'Netriedený zoznam',\n    orderedList: 'Triedený zoznam',\n\n    insertImage: 'Vložiť obrázok',\n    insertVideo: 'Vložiť video',\n    link: 'Odkaz',\n    createLink: 'Vložiť odkaz',\n    unlink: 'Zmazať odkaz',\n\n    justifyLeft: 'Zarovnať doľava',\n    justifyCenter: 'Zarovnať na stred',\n    justifyRight: 'Zarovnať doprava',\n    justifyFull: 'Zarovnať do bloku',\n\n    horizontalRule: 'Vložit vodorovnú čiaru',\n\n    fullscreen: 'Režim celej obrazovky',\n\n    close: 'Zavrieť',\n\n    submit: 'Potvrdiť',\n    reset: 'Zrušiť',\n\n    required: 'Povinné',\n    description: 'Popis',\n    title: 'Nadpis',\n    text: 'Text'\n};\n"
  },
  {
    "path": "src/langs/sl.js",
    "content": "/* ===========================================================\n * sl.js\n * Slovenian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author: Matjaz Zavski (https://github.com/matjaz321)\n * Mod: Uros Gaber (uros@powercom.si)\n */\n\njQuery.trumbowyg.langs.sl = {\n    viewHTML: 'Prikaži HTML',\n\n    undo: 'Razveljavi',\n    redo: 'Ponovno uveljavi',\n\n    formatting: 'Oblika',\n    p: 'Odstavek',\n    blockquote: 'Citat',\n    code: 'Koda',\n    header: 'Glava',\n\n    bold: 'Krepko',\n    italic: 'Ležeče',\n    strikethrough: 'Prečrtano',\n    underline: 'Podčrtano',\n\n    strong: 'Odebljeno',\n    em: 'Poudarjeno',\n    del: 'Izbrisano',\n\n    unorderedList: 'Neoštevilčen seznam',\n    orderedList: 'Oštevilčen seznam',\n\n    image: 'Slika',\n    insertImage: 'Vstavi sliko',\n    insertVideo: 'Vstavi video',\n    link: 'Povezava',\n    createLink: 'Vstavi povezavo',\n    unlink: 'Odstrani povezavo',\n\n    justifyLeft: 'Poravnava levo',\n    justifyCenter: 'Poravnaj na sredino',\n    justifyRight: 'Poravnava desno',\n    justifyFull: 'Obojestranska poravnava',\n\n    horizontalRule: 'Vstavite vodoravno črto',\n    removeformat: 'Odstrani format',\n\n    fullscreen: 'Celozaslonski način',\n\n    close: 'Zapri',\n\n    submit: 'Potrdi',\n    reset: 'Prekliči',\n\n    required: 'Zahtevano',\n    description: 'Opis',\n    title: 'Naslov',\n    text: 'Besedilo'\n};\n"
  },
  {
    "path": "src/langs/sq.js",
    "content": "/* ===========================================================\n * sq.js\n * Albanian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Adalen Vladi\n */\n\njQuery.trumbowyg.langs.sq = {\n\n    viewHTML: 'Shfaq HTML',\n\n    undo: 'Prish',\n    redo: 'Ribej',\n\n    formatting: 'Formatimi',\n    p: 'Paragraf',\n    blockquote: 'Citat',\n    code: 'Kodi',\n    header: 'Koka',\n\n    bold: 'Spikatur',\n    italic: 'Pjerret',\n    strikethrough: 'Vize ne mes',\n    underline: 'Nenvizo',\n\n    strong: 'I trashe',\n    em: 'I theksuar',\n    del: 'I fshire',\n\n    superscript: 'Indeks i sipërm',\n    subscript: 'Indeks i poshtem',\n\n    unorderedList: 'Liste e parenditur',\n    orderedList: 'Liste e renditur',\n\n\n    insertImage: 'Fut Foto',\n    insertVideo: 'Fut Video',\n    link: 'Link',\n    createLink: 'Krijo Link',\n    unlink: 'Hiq Link',\n\n    justifyLeft: 'Drejto Majtas',\n    justifyCenter: 'Drejto ne Qender',\n    justifyRight: 'Drejto Djathtas',\n    justifyFull: 'Drejto Vete',\n\n    horizontalRule: 'Vendos rregulloren horizontale',\n    removeformat: 'Hiq formatin',\n\n    fullscreen: 'Ekran i plotë',\n\n    close: 'Mbyll',\n\n    submit: 'Konfirmo',\n    reset: 'Anullo',\n\n    required: 'I detyrueshem',\n    description: 'Pershkrimi',\n    title: 'Titulli',\n    text: 'Tekst',\n    target: 'Objektivi',\n    width: 'Gjeresia'\n};\n"
  },
  {
    "path": "src/langs/sv.js",
    "content": "/* ===========================================================\n * sv.js\n * Swedish translation for Trumbowyg\n * http://www.tim-international.net\n * ===========================================================\n * Author : T. Almroth\n * Github : https://github.com/timint\n *\n * Review : M Hagberg\n * Github : https://github.com/pestbarn\n */\n\njQuery.trumbowyg.langs.sv = {\n    viewHTML: 'Visa HTML',\n\n    formatting: 'Formatering',\n    p: 'Paragraf',\n    blockquote: 'Citat',\n    code: 'Kod',\n    header: 'Rubrik',\n\n    bold: 'Fet',\n    italic: 'Kursiv',\n    strikethrough: 'Genomstruken',\n    underline: 'Understruken',\n\n    strong: 'Fet',\n    em: 'Kursiv',\n    del: 'Rensa formatering',\n\n    unorderedList: 'Punktlista',\n    orderedList: 'Numrerad lista',\n\n    insertImage: 'Infoga bild',\n    insertVideo: 'Infoga video',\n    link: 'Länk',\n    createLink: 'Infoga länk',\n    unlink: 'Ta bort länk',\n\n    justifyLeft: 'Vänsterjustera',\n    justifyCenter: 'Centrera',\n    justifyRight: 'Högerjustera',\n    justifyFull: 'Marginaljustera',\n\n    horizontalRule: 'Horisontell linje',\n    removeformat: 'Ta bort formatering',\n\n    fullscreen: 'Fullskärm',\n\n    close: 'Stäng',\n\n    submit: 'Bekräfta',\n    reset: 'Återställ',\n\n    required: 'Obligatorisk',\n    description: 'Beskrivning',\n    title: 'Titel',\n    text: 'Text'\n};\n"
  },
  {
    "path": "src/langs/th.js",
    "content": "/* ===========================================================\n * th.js\n * Thai translation for Trumbowyg\n * https://github.com/ionsoft/Trumbowyg\n * ===========================================================\n * Author : Gonatee Klanktong\n *          Github : https://github.com/gonateek\n */\n\njQuery.trumbowyg.langs.th = {\n    viewHTML: 'ดู HTML',\n\n    formatting: 'จัดรูปแบบ',\n    p: 'ย่อหน้า',\n    blockquote: 'อ้างอิง',\n    code: 'โค๊ด',\n    header: 'ส่วนหัว',\n\n    bold: 'หนา',\n    italic: 'เอียง',\n    strikethrough: 'ขีดทับ',\n    underline: 'เส้นใต้',\n\n    strong: 'สำคัญ',\n    em: 'เน้น',\n    del: 'ลบ',\n\n    unorderedList: 'รายการ',\n    orderedList: 'รายการ(ตัวเลข)',\n\n    insertImage: 'ใส่รูป',\n    insertVideo: 'ใส่วิดีโอ',\n    link: 'ลิงค์',\n    createLink: 'สร้างลิงค์',\n    unlink: 'ยกเลิกลิงค์',\n\n    justifyLeft: 'ชิดซ้าย',\n    justifyCenter: 'กลาง',\n    justifyRight: 'ชิดขวา',\n    justifyFull: 'เต็มบรรทัด',\n\n    horizontalRule: 'เส้นแนวนอน',\n\n    fullscreen: 'เต็มหน้าจอ',\n\n    close: 'ปิด',\n\n    submit: 'ตกลง',\n    reset: 'เริ่มใหม่',\n\n    required: 'จำเป็น',\n    description: 'คำอธิบาย',\n    title: 'หัวเรื่อง',\n    text: 'ข้อความ'\n};\n"
  },
  {
    "path": "src/langs/tr.js",
    "content": "/* ===========================================================\n * tr.js\n * Turkish translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Emrah Bilbay (munzur)\n *          Github : https://github.com/munzur\n *\n *          Özgür Görgülü (ozgurg)\n *          Github : https://github.com/ozgurg\n */\n\njQuery.trumbowyg.langs.tr = {\n    viewHTML: 'HTML Kodu',\n\n    undo: 'Yinele',\n    redo: 'Geri al',\n\n    formatting: 'Biçimlendirme',\n    p: 'Paragraf',\n    blockquote: 'Alıntı',\n    code: 'Kod',\n    header: 'Başlık',\n\n    bold: 'Kalın',\n    italic: 'İtalik',\n    strikethrough: 'Üzeri çizgili',\n    underline: 'Altı çizgili',\n\n    strong: 'Koyu',\n    em: 'Vurgulu',\n    del: 'Üzeri çizgili',\n\n    unorderedList: 'Simgeli liste',\n    orderedList: 'Numaralı liste',\n\n    insertImage: 'Resim yerleştir',\n    insertVideo: 'Video yerleştir',\n    link: 'Link',\n    createLink: 'Link yerleştir',\n    unlink: 'Linki sil',\n\n    justifyLeft: 'Sola hizala',\n    justifyCenter: 'Ortaya hizala',\n    justifyRight: 'Sağa hizala',\n    justifyFull: 'Yasla',\n\n    horizontalRule: 'Yatay satır ekle',\n\n    fullscreen: 'Tam ekran',\n\n    close: 'Kapat',\n\n    submit: 'Onayla',\n    reset: 'Sıfırla',\n\n    required: 'Gerekli',\n    description: 'Açıklama',\n    title: 'Başlık',\n    text: 'Metin',\n\n    removeformat: 'Biçimlendirmeyi temizle'\n};\n"
  },
  {
    "path": "src/langs/ua.js",
    "content": "/* ===========================================================\n * ua.js\n * Ukrainian translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Igor Buksha\n */\n\njQuery.trumbowyg.langs.ua = {\n    viewHTML: 'Подивитись HTML',\n\n    formatting: 'Форматування',\n    p: 'Звичайний',\n    blockquote: 'Витяг',\n    code: 'Код',\n    header: 'Заголовок',\n\n    bold: 'Напівжирний',\n    italic: 'Курсив',\n    strikethrough: 'Закреслений',\n    underline: 'Підкреслений',\n\n    strong: 'Напівжирний',\n    em: 'Курсив',\n    del: 'Закреслений',\n\n    unorderedList: 'Звичайний список',\n    orderedList: 'Нумерований список',\n\n    insertImage: 'Вставити зображення',\n    insertVideo: 'Вставити відео',\n    link: 'Посилання',\n    createLink: 'Вставити посилання',\n    unlink: 'Видалити посилання',\n\n    justifyLeft: 'По лівому краю',\n    justifyCenter: 'В центрі',\n    justifyRight: 'По правому краю',\n    justifyFull: 'По ширині',\n\n    horizontalRule: 'Горизонтальна лінія',\n\n    fullscreen: 'На весь екран',\n\n    close: 'Закрити',\n\n    submit: 'Вставити',\n    reset: 'Скасувати',\n\n    required: 'Обов\\'язкове',\n    description: 'Опис',\n    title: 'Підказка',\n    text: 'Текст'\n};\n"
  },
  {
    "path": "src/langs/vi.js",
    "content": "/* ===========================================================\n * vi.js\n * Vietnamese translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : heocoi\n *          Github: https://github.com/heocoi\n */\n\njQuery.trumbowyg.langs.vi = {\n    viewHTML: 'Hiển thị HTML',\n\n    formatting: 'Định dạng',\n    p: 'Đoạn',\n    blockquote: 'Trích dẫn',\n    code: 'Code',\n    header: 'Đầu trang',\n\n    bold: 'In đậm',\n    italic: 'In nghiêng',\n    strikethrough: 'Gạch ngang',\n    underline: 'Gạch chân',\n\n    strong: 'In đậm',\n    em: 'In nghiêng',\n    del: 'Gạch ngang',\n\n    unorderedList: 'Danh sách không thứ tự',\n    orderedList: 'Danh sách có thứ tự',\n\n    insertImage: 'Chèn hình ảnh',\n    insertVideo: 'Chèn video',\n    link: 'Đường dẫn',\n    createLink: 'Tạo đường dẫn',\n    unlink: 'Hủy đường dẫn',\n\n    justifyLeft: 'Canh lề trái',\n    justifyCenter: 'Canh giữa',\n    justifyRight: 'Canh lề phải',\n    justifyFull: 'Canh đều',\n\n    horizontalRule: 'Thêm đường kẻ ngang',\n\n    fullscreen: 'Toàn màn hình',\n\n    close: 'Đóng',\n\n    submit: 'Đồng ý',\n    reset: 'Hủy bỏ',\n\n    required: 'Bắt buộc',\n    description: 'Mô tả',\n    title: 'Tiêu đề',\n    text: 'Nội dung',\n    target: 'Đối tượng'\n};\n"
  },
  {
    "path": "src/langs/zh_cn.js",
    "content": "/* ===========================================================\n * zh_cn.js\n * Simplified Chinese translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Liu Kai (akai)\n *          Twitter : @akai404\n *          Github : https://github.com/akai\n */\n\n// jshint camelcase:false\njQuery.trumbowyg.langs.zh_cn = {\n    viewHTML: '源代码',\n\n    formatting: '格式',\n    p: '段落',\n    blockquote: '引用',\n    code: '代码',\n    header: '标题',\n\n    bold: '加粗',\n    italic: '斜体',\n    strikethrough: '删除线',\n    underline: '下划线',\n\n    strong: '加粗',\n    em: '斜体',\n    del: '删除线',\n\n    unorderedList: '无序列表',\n    orderedList: '有序列表',\n\n    insertImage: '插入图片',\n    insertVideo: '插入视频',\n    link: '超链接',\n    createLink: '插入链接',\n    unlink: '取消链接',\n\n    justifyLeft: '居左对齐',\n    justifyCenter: '居中对齐',\n    justifyRight: '居右对齐',\n    justifyFull: '两端对齐',\n\n    horizontalRule: '插入分隔线',\n\n    fullscreen: '全屏',\n\n    close: '关闭',\n\n    submit: '确定',\n    reset: '取消',\n\n    required: '必需的',\n    description: '描述',\n    title: '标题',\n    text: '文字'\n};\n"
  },
  {
    "path": "src/langs/zh_tw.js",
    "content": "/* ===========================================================\n * zh_tw.js\n * Traditional Chinese translation for Trumbowyg\n * http://alex-d.github.com/Trumbowyg\n * ===========================================================\n * Author : Peter Dave Hello (PeterDaveHello)\n *          Twitter : @PeterDaveHello\n *          Github : https://github.com/PeterDaveHello\n */\n\n// jshint camelcase:false\njQuery.trumbowyg.langs.zh_tw = {\n    viewHTML: '原始碼',\n\n    undo: '復原',\n    redo: '重做',\n\n    formatting: '格式',\n    p: '段落',\n    blockquote: '引用',\n    code: '代碼',\n    header: '標題',\n\n    bold: '加粗',\n    italic: '斜體',\n    strikethrough: '刪除線',\n    underline: '底線',\n\n    strong: '粗體',\n    em: '斜體',\n    del: '刪除線',\n\n    superscript: '上標',\n    subscript: '下標',\n\n    unorderedList: '無序列表',\n    orderedList: '有序列表',\n\n    insertImage: '插入圖片',\n    insertVideo: '插入影片',\n    link: '超連結',\n    createLink: '插入連結',\n    unlink: '取消連結',\n\n    justifyLeft: '靠左對齊',\n    justifyCenter: '置中對齊',\n    justifyRight: '靠右對齊',\n    justifyFull: '左右對齊',\n\n    horizontalRule: '插入分隔線',\n    removeformat: '移除格式',\n\n    fullscreen: '全螢幕',\n\n    close: '關閉',\n\n    submit: '確定',\n    reset: '取消',\n\n    required: '必需的',\n    description: '描述',\n    title: '標題',\n    text: '文字',\n    target: '目標',\n    width: '寬度'\n};\n"
  },
  {
    "path": "src/trumbowyg.js",
    "content": "jQuery.trumbowyg = {\n    langs: {\n        en: {\n            viewHTML: 'View HTML',\n\n            undo: 'Undo',\n            redo: 'Redo',\n\n            formatting: 'Formatting',\n            p: 'Paragraph',\n            blockquote: 'Quote',\n            code: 'Code',\n            header: 'Header',\n\n            bold: 'Bold',\n            italic: 'Italic',\n            strikethrough: 'Strikethrough',\n            underline: 'Underline',\n\n            strong: 'Strong',\n            em: 'Emphasis',\n            del: 'Deleted',\n\n            superscript: 'Superscript',\n            subscript: 'Subscript',\n\n            unorderedList: 'Unordered list',\n            orderedList: 'Ordered list',\n\n            insertImage: 'Insert Image',\n            link: 'Link',\n            createLink: 'Insert link',\n            unlink: 'Remove link',\n\n            _self: 'Same tab (default)',\n            _blank: 'New tab',\n\n            justifyLeft: 'Align Left',\n            justifyCenter: 'Align Center',\n            justifyRight: 'Align Right',\n            justifyFull: 'Align Justify',\n\n            horizontalRule: 'Insert horizontal rule',\n            removeformat: 'Remove format',\n\n            fullscreen: 'Fullscreen',\n\n            close: 'Close',\n\n            submit: 'Confirm',\n            reset: 'Cancel',\n\n            required: 'Required',\n            description: 'Description',\n            title: 'Title',\n            text: 'Text',\n            target: 'Target',\n            width: 'Width'\n        }\n    },\n\n    // Plugins\n    plugins: {},\n\n    // SVG Path globally\n    svgPath: null,\n    svgAbsoluteUseHref: false,\n\n    hideButtonTexts: null\n};\n\n// Makes default options read-only\nObject.defineProperty(jQuery.trumbowyg, 'defaultOptions', {\n    value: {\n        lang: 'en',\n\n        fixedBtnPane: false,\n        fixedFullWidth: false,\n        autogrow: false,\n        autogrowOnEnter: false,\n        imageWidthModalEdit: false,\n        hideButtonTexts: null,\n\n        prefix: 'trumbowyg-',\n        tagClasses: {},\n        semantic: true,\n        semanticKeepAttributes: false,\n        resetCss: false,\n        removeformatPasted: false,\n        tabToIndent: false,\n        tagsToRemove: [],\n        tagsToKeep: ['hr', 'img', 'embed', 'iframe', 'input'],\n        btns: [\n            ['viewHTML'],\n            ['undo', 'redo'], // Only supported in Blink browsers\n            ['formatting'],\n            ['strong', 'em', 'del'],\n            ['superscript', 'subscript'],\n            ['link'],\n            ['insertImage'],\n            ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],\n            ['unorderedList', 'orderedList'],\n            ['horizontalRule'],\n            ['removeformat'],\n            ['fullscreen']\n        ],\n        // For custom button definitions\n        btnsDef: {},\n        changeActiveDropdownIcon: false,\n\n        inlineElementsSelector: 'a,abbr,acronym,b,caption,cite,code,col,dfn,dir,dt,dd,em,font,hr,i,kbd,li,q,span,strikeout,strong,sub,sup,u',\n\n        pasteHandlers: [],\n\n        // imgDblClickHandler: default is defined in constructor\n\n        plugins: {},\n\n        urlProtocol: false,\n        minimalLinks: false,\n        linkTargets: ['_self', '_blank'],\n\n        svgPath: null\n    },\n    writable: false,\n    enumerable: true,\n    configurable: false\n});\n\n(function (navigator, window, document, $) {\n    'use strict';\n\n    var CONFIRM_EVENT = 'tbwconfirm',\n        CANCEL_EVENT = 'tbwcancel';\n\n    $.fn.trumbowyg = function (options, params) {\n        var trumbowygDataName = 'trumbowyg';\n        if (options === Object(options) || !options) {\n            return this.each(function () {\n                if (!$(this).data(trumbowygDataName)) {\n                    $(this).data(trumbowygDataName, new Trumbowyg(this, options));\n                }\n            });\n        }\n        if (this.length === 1) {\n            try {\n                var t = $(this).data(trumbowygDataName);\n                switch (options) {\n                    // Exec command\n                    case 'execCmd':\n                        return t.execCmd(params.cmd, params.param, params.forceCss, params.skipTrumbowyg);\n\n                    // Modal box\n                    case 'openModal':\n                        return t.openModal(params.title, params.content);\n                    case 'closeModal':\n                        return t.closeModal();\n                    case 'openModalInsert':\n                        return t.openModalInsert(params.title, params.fields, params.callback);\n\n                    // Range\n                    case 'saveRange':\n                        return t.saveRange();\n                    case 'getRange':\n                        return t.range;\n                    case 'getRangeText':\n                        return t.getRangeText();\n                    case 'restoreRange':\n                        return t.restoreRange();\n\n                    // Enable/disable\n                    case 'enable':\n                        return t.setDisabled(false);\n                    case 'disable':\n                        return t.setDisabled(true);\n\n                    // Toggle\n                    case 'toggle':\n                        return t.toggle();\n\n                    // Destroy\n                    case 'destroy':\n                        return t.destroy();\n\n                    // Empty\n                    case 'empty':\n                        return t.empty();\n\n                    // HTML\n                    case 'html':\n                        return t.html(params);\n                }\n            } catch (c) {\n            }\n        }\n\n        return false;\n    };\n\n    // @param: editorElem is the DOM element\n    var Trumbowyg = function (editorElem, options) { // jshint ignore:line\n        var t = this,\n            trumbowygIconsId = 'trumbowyg-icons',\n            $trumbowyg = $.trumbowyg;\n\n        // Get the document of the element. It use to makes the plugin\n        // compatible on iframes.\n        t.doc = editorElem.ownerDocument || document;\n\n        // jQuery object of the editor\n        t.$ta = $(editorElem); // $ta : Textarea\n        t.$c = $(editorElem); // $c : creator\n\n        options = options || {};\n\n        // Localization management\n        if (options.lang != null || $trumbowyg.langs[options.lang] != null) {\n            t.lang = $.extend(true, {}, $trumbowyg.langs.en, $trumbowyg.langs[options.lang]);\n        } else {\n            t.lang = $trumbowyg.langs.en;\n        }\n\n        t.hideButtonTexts = $trumbowyg.hideButtonTexts != null ? $trumbowyg.hideButtonTexts : options.hideButtonTexts;\n\n        // SVG path\n        var svgPathOption = $trumbowyg.svgPath != null ? $trumbowyg.svgPath : options.svgPath;\n        t.hasSvg = svgPathOption !== false;\n\n        if (svgPathOption !== false && ($trumbowyg.svgAbsoluteUseHref || $('#' + trumbowygIconsId, t.doc).length === 0)) {\n            if (svgPathOption == null) {\n                // Hack to get svgPathOption based on trumbowyg.js path\n                var $scriptElements = $('script[src]');\n                $scriptElements.each(function (i, scriptElement) {\n                    var source = scriptElement.src;\n                    var matches = source.match('trumbowyg(\\.min)?\\.js');\n                    if (matches != null) {\n                        svgPathOption = source.substring(0, source.indexOf(matches[0])) + 'ui/icons.svg';\n                    }\n                });\n            }\n\n            // Do not merge with previous if block: svgPathOption can be redefined in it.\n            // Here we are checking that we find a match\n            if (svgPathOption == null) {\n                console.warn('You must define svgPath: https://goo.gl/CfTY9U'); // jshint ignore:line\n            } else if (!$trumbowyg.svgAbsoluteUseHref) {\n                var div = t.doc.createElement('div');\n                div.style.width = '0';\n                div.style.height = '0';\n                div.style.overflow = 'hidden';\n                div.style.visibility = 'hidden';\n                div.id = trumbowygIconsId;\n                t.doc.body.insertBefore(div, t.doc.body.childNodes[0]);\n                fetch(svgPathOption, {\n                    method: 'GET',\n                    headers: {\n                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'\n                    }\n                }).then((response) => {\n                    response.text()\n                        .then((svg) => {\n                            div.innerHTML = svg;\n                        });\n                });\n            }\n        }\n\n        var baseHref = !!t.doc.querySelector('base') ? window.location.href.replace(window.location.hash, '') : '';\n        t.svgPath = $trumbowyg.svgAbsoluteUseHref ? svgPathOption : baseHref;\n\n\n        /**\n         * When the button is associated to a empty object\n         * fn and title attributes are defined from the button key value\n         *\n         * For example\n         *      foo: {}\n         * is equivalent to :\n         *      foo: {\n         *          fn: 'foo',\n         *          title: this.lang.foo\n         *      }\n         */\n        var h = t.lang.header, // Header translation\n            isBlinkFunction = function () {\n                return (window.chrome || (window.Intl && Intl.v8BreakIterator)) && 'CSS' in window;\n            };\n        t.btnsDef = {\n            viewHTML: {\n                fn: 'toggle',\n                class: 'trumbowyg-not-disable'\n            },\n\n            undo: {\n                isSupported: isBlinkFunction,\n                key: 'Z'\n            },\n            redo: {\n                isSupported: isBlinkFunction,\n                key: 'Y'\n            },\n\n            p: {\n                fn: 'formatBlock'\n            },\n            blockquote: {\n                fn: 'formatBlock'\n            },\n            h1: {\n                fn: 'formatBlock',\n                title: h + ' 1'\n            },\n            h2: {\n                fn: 'formatBlock',\n                title: h + ' 2'\n            },\n            h3: {\n                fn: 'formatBlock',\n                title: h + ' 3'\n            },\n            h4: {\n                fn: 'formatBlock',\n                title: h + ' 4'\n            },\n            h5: {\n                fn: 'formatBlock',\n                title: h + ' 5'\n            },\n            h6: {\n                fn: 'formatBlock',\n                title: h + ' 6'\n            },\n            subscript: {\n                tag: 'sub'\n            },\n            superscript: {\n                tag: 'sup'\n            },\n\n            bold: {\n                key: 'B',\n                tag: 'b'\n            },\n            italic: {\n                key: 'I',\n                tag: 'i'\n            },\n            underline: {\n                tag: 'u'\n            },\n            strikethrough: {\n                tag: 'strike'\n            },\n\n            strong: {\n                fn: 'bold',\n                key: 'B'\n            },\n            em: {\n                fn: 'italic',\n                key: 'I'\n            },\n            del: {\n                fn: 'strikethrough'\n            },\n\n            createLink: {\n                key: 'K',\n                tag: 'a'\n            },\n            unlink: {},\n\n            insertImage: {},\n\n            justifyLeft: {\n                tag: 'left',\n                forceCss: true\n            },\n            justifyCenter: {\n                tag: 'center',\n                forceCss: true\n            },\n            justifyRight: {\n                tag: 'right',\n                forceCss: true\n            },\n            justifyFull: {\n                tag: 'justify',\n                forceCss: true\n            },\n\n            unorderedList: {\n                fn: 'insertUnorderedList',\n                tag: 'ul'\n            },\n            orderedList: {\n                fn: 'insertOrderedList',\n                tag: 'ol'\n            },\n\n            horizontalRule: {\n                fn: 'insertHorizontalRule'\n            },\n\n            removeformat: {},\n\n            fullscreen: {\n                class: 'trumbowyg-not-disable'\n            },\n            close: {\n                fn: 'destroy',\n                class: 'trumbowyg-not-disable'\n            },\n\n            // Dropdowns\n            formatting: {\n                dropdown: ['p', 'blockquote', 'h1', 'h2', 'h3', 'h4'],\n                ico: 'p'\n            },\n            link: {\n                dropdown: ['createLink', 'unlink']\n            }\n        };\n\n        // Default Options\n        t.o = $.extend(true, {}, $trumbowyg.defaultOptions, options);\n        if (!t.o.hasOwnProperty('imgDblClickHandler')) {\n            t.o.imgDblClickHandler = t.getDefaultImgDblClickHandler();\n        }\n\n        t.urlPrefix = t.setupUrlPrefix();\n\n        t.disabled = t.o.disabled || (editorElem.nodeName === 'TEXTAREA' && editorElem.disabled);\n\n        if (options.btns) {\n            t.o.btns = options.btns;\n        } else if (!t.o.semantic) {\n            t.o.btns[3] = ['bold', 'italic', 'underline', 'strikethrough'];\n        }\n\n        $.each(t.o.btnsDef, function (btnName, btnDef) {\n            t.addBtnDef(btnName, btnDef);\n        });\n\n        // put this here in the event it would be merged in with options\n        t.eventNamespace = 'trumbowyg-event';\n\n        // Keyboard shortcuts are load in this array\n        t.keys = [];\n\n        // Tag to button dynamically hydrated\n        t.tagToButton = {};\n        t.tagHandlers = [];\n\n        // Admit multiple paste handlers\n        t.pasteHandlers = [].concat(t.o.pasteHandlers);\n\n        // Check if browser is IE\n        t.isIE = navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') !== -1;\n\n        // Check if we are on macOs\n        t.isMac = navigator.platform.toUpperCase().indexOf('MAC') !== -1;\n\n        t.init();\n    };\n\n    Trumbowyg.prototype = {\n        DEFAULT_SEMANTIC_MAP: {\n            'b': 'strong',\n            'i': 'em',\n            's': 'del',\n            'strike': 'del',\n            'div': 'p'\n        },\n\n        init: function () {\n            var t = this;\n            t.height = t.$ta.outerHeight() - 39; // Remove button pane height\n\n            t.initPlugins();\n\n            try {\n                // Disable image resize, try-catch for old IE\n                t.doc.execCommand('enableObjectResizing', false, false);\n                t.doc.execCommand('defaultParagraphSeparator', false, 'p');\n            } catch (e) {\n            }\n\n            t.buildEditor();\n            t.buildBtnPane();\n\n            t.fixedBtnPaneEvents();\n\n            t.buildOverlay();\n\n            setTimeout(function () {\n                if (t.disabled) {\n                    t.setDisabled(true);\n                }\n                t.$c.trigger('tbwinit');\n            });\n        },\n\n        addBtnDef: function (btnName, btnDef) {\n            this.btnsDef[btnName] = $.extend(btnDef, this.btnsDef[btnName] || {});\n        },\n\n        setupUrlPrefix: function () {\n            var protocol = this.o.urlProtocol;\n            if (!protocol) {\n                return;\n            }\n\n            if (typeof (protocol) !== 'string') {\n                return 'https://';\n            }\n            return protocol.replace('://', '') + '://';\n        },\n\n        buildEditor: function () {\n            var t = this,\n                prefix = t.o.prefix,\n                html = '';\n\n            t.$box = $('<div/>', {\n                class: prefix + 'box ' + prefix + 'editor-visible ' + prefix + t.o.lang + ' trumbowyg'\n            });\n\n            t.$edBox = $('<div/>', {\n                class: prefix + 'editor-box'\n            });\n\n            // $ta = Textarea\n            // $ed = Editor\n            t.isTextarea = t.$ta.is('textarea');\n            if (t.isTextarea) {\n                html = t.$ta.val();\n                t.$ed = $('<div/>')\n                    .appendTo(t.$edBox);\n                t.$box\n                    .insertAfter(t.$ta)\n                    .append(t.$edBox, t.$ta);\n            } else {\n                t.$ed = t.$ta;\n                html = t.$ed.html();\n\n                t.$ta = $('<textarea/>', {\n                    name: t.$ta.attr('id'),\n                    height: t.height\n                }).val(html);\n\n                t.$box\n                    .insertAfter(t.$ed)\n                    .append(t.$ta, t.$edBox);\n                t.$edBox.append(t.$ed);\n                t.syncCode();\n            }\n\n            t.$ta\n                .addClass(prefix + 'textarea')\n                .attr('tabindex', -1)\n            ;\n\n            t.$ed\n                .addClass(prefix + 'editor')\n                .attr({\n                    contenteditable: true,\n                    dir: t.lang._dir || 'ltr'\n                })\n                .html(html)\n            ;\n\n            if (t.o.tabindex) {\n                t.$ed.attr('tabindex', t.o.tabindex);\n            }\n\n            if (t.$c.is('[placeholder]')) {\n                t.$ed.attr('placeholder', t.$c.attr('placeholder'));\n            }\n\n            if (t.$c.is('[spellcheck]')) {\n                t.$ed.attr('spellcheck', t.$c.attr('spellcheck'));\n            }\n\n            if (t.o.resetCss) {\n                t.$ed.addClass(prefix + 'reset-css');\n            }\n\n            t.semanticCode();\n            t.applyTagClasses();\n\n            if (t.o.autogrowOnEnter) {\n                t.$ed.addClass(prefix + 'autogrow-on-enter');\n            }\n\n            var ctrl = false,\n                composition = false,\n                debounceButtonPaneStatus;\n\n            t.$ed\n                .on('dblclick', 'img', t.o.imgDblClickHandler)\n                .on('keydown', function (e) {\n                    // append flags to differentiate Chrome spans\n                    var keyCode = e.which;\n                    if (keyCode === 8 || keyCode === 13 || keyCode === 46) {\n                        t.toggleSpan(true);\n                    }\n                    if ((e.ctrlKey || e.metaKey) && !e.altKey) {\n                        ctrl = true;\n                        var key = t.keys[String.fromCharCode(e.which).toUpperCase()];\n\n                        try {\n                            t.execCmd(key.fn, key.param);\n                            return false;\n                        } catch (c) {\n                        }\n                    } else {\n                        if (t.o.tabToIndent && e.key === 'Tab') {\n                            try {\n                                if (e.shiftKey) {\n                                    t.execCmd('outdent', true, null);\n                                } else {\n                                    t.execCmd('indent', true, null);\n                                }\n                                return false;\n                            } catch (c) {\n                            }\n                        }\n                    }\n                })\n                .on('compositionstart compositionupdate', function () {\n                    composition = true;\n                })\n                .on('keyup compositionend', function (e) {\n                    if (e.type === 'compositionend') {\n                        composition = false;\n                    } else if (composition) {\n                        return;\n                    }\n\n                    var keyCode = e.which;\n\n                    if (keyCode >= 37 && keyCode <= 40) {\n                        return;\n                    }\n\n                    // remove Chrome generated span tags\n                    if (keyCode === 8 || keyCode === 13 || keyCode === 46) {\n                        t.toggleSpan();\n                    }\n\n                    if ((e.ctrlKey || e.metaKey) && (keyCode === 89 || keyCode === 90)) {\n                        t.semanticCode(false, true);\n                        t.$c.trigger('tbwchange');\n                    } else if (!ctrl && keyCode !== 16 && keyCode !== 17) {\n                        var compositionEndIE = t.isIE ? e.type === 'compositionend' : true;\n                        t.semanticCode(false, compositionEndIE && keyCode === 13);\n                        t.$c.trigger('tbwchange');\n                    } else if (typeof e.which === 'undefined') {\n                        t.semanticCode(false, false, true);\n                    }\n\n                    setTimeout(function () {\n                        ctrl = false;\n                    }, 50);\n                })\n                .on('input', function (e) {\n                    // Trigger change event when spelling fixes applied\n                    var event = e.originalEvent;\n                    if (typeof event === 'object' && (event.inputType === 'insertReplacementText' ||\n                        (event.inputType === 'insertText' && event.data === null))) {\n                        t.$c.trigger('tbwchange');\n                    }\n                })\n                .on('mouseup keydown keyup', function (e) {\n                    if ((!e.ctrlKey && !e.metaKey) || e.altKey) {\n                        setTimeout(function () { // \"hold on\" to the ctrl key for 50ms\n                            ctrl = false;\n                        }, 50);\n                    }\n                    clearTimeout(debounceButtonPaneStatus);\n                    debounceButtonPaneStatus = setTimeout(function () {\n                        t.updateButtonPaneStatus();\n                    }, 50);\n                })\n                .on('focus blur', function (e) {\n                    if (e.type === 'blur') {\n                        t.clearButtonPaneStatus();\n                    }\n                    t.$c.trigger('tbw' + e.type);\n                    if (t.o.autogrowOnEnter) {\n                        if (t.autogrowOnEnterDontClose) {\n                            return;\n                        }\n                        if (e.type === 'focus') {\n                            t.autogrowOnEnterWasFocused = true;\n                            t.autogrowEditorOnEnter();\n                        } else if (!t.o.autogrow) {\n                            t.$edBox.css({height: t.$edBox.css('min-height')});\n                            t.$c.trigger('tbwresize');\n                        }\n                    }\n                })\n                .on('keyup focus', function () {\n                    if (!t.$ta.val().match(/<.*>/) && !t.$ed.html().match(/<.*>/)) {\n                        setTimeout(function () {\n                            var block = t.isIE ? '<p>' : 'p';\n                            t.doc.execCommand('formatBlock', false, block);\n                            t.syncCode();\n                        }, 0);\n                    }\n                })\n                .on('cut drop', function () {\n                    setTimeout(function () {\n                        t.semanticCode(false, true);\n                        t.$c.trigger('tbwchange');\n                    }, 0);\n                })\n                .on('paste', function (e) {\n                    if (t.o.removeformatPasted) {\n                        e.preventDefault();\n\n                        if (window.getSelection && window.getSelection().deleteFromDocument) {\n                            window.getSelection().deleteFromDocument();\n                        }\n\n                        try {\n                            // IE\n                            var text = window.clipboardData.getData('Text');\n\n                            try {\n                                // <= IE10\n                                t.doc.selection.createRange().pasteHTML(text);\n                            } catch (c) {\n                                // IE 11\n                                t.doc.getSelection().getRangeAt(0).insertNode(t.doc.createTextNode(text));\n                            }\n                            t.$c.trigger('tbwchange', e);\n                        } catch (d) {\n                            // Not IE\n                            t.execCmd('insertText', (e.originalEvent || e).clipboardData.getData('text/plain'));\n                        }\n                    }\n\n                    // Call pasteHandlers\n                    $.each(t.pasteHandlers, function (i, pasteHandler) {\n                        pasteHandler(e);\n                    });\n\n                    setTimeout(function () {\n                        t.semanticCode(false, true);\n                        t.$c.trigger('tbwpaste', e);\n                        t.$c.trigger('tbwchange');\n                    }, 0);\n                });\n\n            t.$ta\n                .on('keyup', function () {\n                    t.$c.trigger('tbwchange');\n                })\n                .on('paste', function () {\n                    setTimeout(function () {\n                        t.$c.trigger('tbwchange');\n                    }, 0);\n                });\n\n            $(t.doc.body).on('keydown.' + t.eventNamespace, function (e) {\n                if (e.which === 27 && $('.' + prefix + 'modal-box').length >= 1) {\n                    t.closeModal();\n                    return false;\n                }\n            });\n        },\n\n        //autogrow when entering logic\n        autogrowEditorOnEnter: function () {\n            var t = this;\n            t.$ed.removeClass('autogrow-on-enter');\n            var oldHeight = t.$ed[0].clientHeight;\n            t.$edBox.height('auto');\n            var totalHeight = t.$ed[0].scrollHeight;\n            t.$ed.addClass('autogrow-on-enter');\n            if (oldHeight !== totalHeight) {\n                t.$edBox.height(oldHeight);\n                setTimeout(function () {\n                    t.$edBox.css({height: totalHeight});\n                    t.$c.trigger('tbwresize');\n                }, 0);\n            }\n        },\n\n\n        // Build button pane, use o.btns option\n        buildBtnPane: function () {\n            var t = this,\n                prefix = t.o.prefix;\n\n            var $btnPane = t.$btnPane = $('<div/>', {\n                class: prefix + 'button-pane'\n            });\n\n            $.each(t.o.btns, function (i, btnGrp) {\n                if (!Array.isArray(btnGrp)) {\n                    btnGrp = [btnGrp];\n                }\n\n                var $btnGroup = $('<div/>', {\n                    class: prefix + 'button-group ' + ((btnGrp.indexOf('fullscreen') >= 0) ? prefix + 'right' : '')\n                });\n                $.each(btnGrp, function (i, btn) {\n                    try { // Prevent buildBtn error\n                        if (t.isSupportedBtn(btn)) { // It's a supported button\n                            $btnGroup.append(t.buildBtn(btn));\n                        }\n                    } catch (c) {\n                    }\n                });\n\n                if ($btnGroup.html().trim().length > 0) {\n                    $btnPane.append($btnGroup);\n                }\n            });\n\n            t.$box.prepend($btnPane);\n        },\n\n\n        // Build a button and his action\n        // @param btnName The name of the button\n        buildBtn: function (btnName) { // jshint ignore:line\n            var t = this,\n                prefix = t.o.prefix,\n                btn = t.btnsDef[btnName],\n                isDropdown = btn.dropdown,\n                hasIcon = btn.hasIcon != null ? btn.hasIcon : true,\n                textDef = t.lang[btnName] || btnName,\n\n                $btn = $('<button/>', {\n                    type: 'button',\n                    class: prefix + btnName + '-button ' + (btn.class || '') + (!hasIcon ? ' ' + prefix + 'textual-button' : ''),\n                    html: t.hasSvg && hasIcon ?\n                        '<svg><use xlink:href=\"' + t.svgPath + '#' + prefix + (btn.ico || btnName).replace(/([A-Z]+)/g, '-$1').toLowerCase() + '\"/></svg>' :\n                        t.hideButtonTexts ? '' : (btn.text || btn.title || t.lang[btnName] || btnName),\n                    title: (btn.title || btn.text || textDef) + (btn.key ? ' (' + (t.isMac ? 'Cmd' : 'Ctrl') + ' + ' + btn.key + ')' : ''),\n                    tabindex: -1,\n                    mousedown: function () {\n                        if (!isDropdown || $('.' + btnName + '-' + prefix + 'dropdown', t.$box).is(':hidden')) {\n                            $('body', t.doc).trigger('mousedown');\n                        }\n\n                        if ((t.$btnPane.hasClass(prefix + 'disable') || t.$box.hasClass(prefix + 'disabled')) &&\n                            !$(this).hasClass(prefix + 'active') &&\n                            !$(this).hasClass(prefix + 'not-disable')) {\n                            return false;\n                        }\n\n                        t.execCmd((isDropdown ? 'dropdown' : false) || btn.fn || btnName, btn.param || btnName, btn.forceCss);\n\n                        return false;\n                    }\n                });\n\n            if (isDropdown) {\n                $btn.addClass(prefix + 'open-dropdown');\n                var dropdownPrefix = prefix + 'dropdown',\n                    dropdownOptions = { // the dropdown\n                        class: dropdownPrefix + '-' + btnName + ' ' + dropdownPrefix + ' ' + prefix + 'fixed-top ' + (btn.dropdownClass || '')\n                    };\n                dropdownOptions['data-' + dropdownPrefix] = btnName;\n                var $dropdown = $('<div/>', dropdownOptions);\n                $.each(isDropdown, function (i, def) {\n                    if (t.btnsDef[def] && t.isSupportedBtn(def)) {\n                        $dropdown.append(t.buildSubBtn(def));\n                    }\n                });\n                t.$box.append($dropdown.hide());\n            } else if (btn.key) {\n                t.keys[btn.key] = {\n                    fn: btn.fn || btnName,\n                    param: btn.param || btnName\n                };\n            }\n\n            if (!isDropdown) {\n                t.tagToButton[(btn.tag || btnName).toLowerCase()] = btnName;\n            }\n\n            return $btn;\n        },\n        // Build a button for dropdown menu\n        // @param n : name of the subbutton\n        buildSubBtn: function (btnName) {\n            var t = this,\n                prefix = t.o.prefix,\n                btn = t.btnsDef[btnName],\n                hasIcon = btn.hasIcon != null ? btn.hasIcon : true;\n\n            if (btn.key) {\n                t.keys[btn.key] = {\n                    fn: btn.fn || btnName,\n                    param: btn.param || btnName\n                };\n            }\n\n            t.tagToButton[(btn.tag || btnName).toLowerCase()] = btnName;\n\n            return $('<button/>', {\n                type: 'button',\n                class: prefix + btnName + '-dropdown-button ' + (btn.class || '') + (btn.ico ? ' ' + prefix + btn.ico + '-button' : ''),\n                html: t.hasSvg && hasIcon ?\n                    '<svg><use xlink:href=\"' + t.svgPath + '#' + prefix + (btn.ico || btnName).replace(/([A-Z]+)/g, '-$1').toLowerCase() + '\"/></svg>' + (btn.text || btn.title || t.lang[btnName] || btnName) :\n                    (btn.text || btn.title || t.lang[btnName] || btnName),\n                title: (btn.key ? '(' + (t.isMac ? 'Cmd' : 'Ctrl') + ' + ' + btn.key + ')' : null),\n                style: btn.style || null,\n                mousedown: function () {\n                    $('body', t.doc).trigger('mousedown');\n\n                    t.execCmd(btn.fn || btnName, btn.param || btnName, btn.forceCss);\n\n                    return false;\n                }\n            });\n        },\n        // Check if button is supported\n        isSupportedBtn: function (btnName) {\n            try {\n                return this.btnsDef[btnName].isSupported();\n            } catch (e) {\n            }\n            return true;\n        },\n\n        // Build overlay for modal box\n        buildOverlay: function () {\n            var t = this;\n            t.$overlay = $('<div/>', {\n                class: t.o.prefix + 'overlay'\n            }).appendTo(t.$box);\n            return t.$overlay;\n        },\n        showOverlay: function () {\n            var t = this;\n            $(window).trigger('scroll');\n            t.$overlay.fadeIn(200);\n            t.$box.addClass(t.o.prefix + 'box-blur');\n        },\n        hideOverlay: function () {\n            var t = this;\n            t.$overlay.fadeOut(50);\n            t.$box.removeClass(t.o.prefix + 'box-blur');\n        },\n\n        // Management of fixed button pane\n        fixedBtnPaneEvents: function () {\n            var t = this,\n                fixedFullWidth = t.o.fixedFullWidth,\n                $box = t.$box;\n\n            if (!t.o.fixedBtnPane) {\n                return;\n            }\n\n            t.isFixed = false;\n\n            $(window)\n                .on('scroll.' + t.eventNamespace + ' resize.' + t.eventNamespace, function () {\n                    if (!$box) {\n                        return;\n                    }\n\n                    t.syncCode();\n\n                    var scrollTop = $(window).scrollTop(),\n                        offset = $box.offset().top + 1,\n                        $buttonPane = t.$btnPane,\n                        buttonPaneOuterHeight = $buttonPane.outerHeight() - 2;\n\n                    if ((scrollTop - offset > 0) && ((scrollTop - offset - t.height) < 0)) {\n                        if (!t.isFixed) {\n                            t.isFixed = true;\n                            $buttonPane.css({\n                                position: 'fixed',\n                                top: 0,\n                                left: fixedFullWidth ? 0 : 'auto',\n                                zIndex: 7\n                            });\n                            t.$box.css({paddingTop: $buttonPane.height()});\n                        }\n                        $buttonPane.css({\n                            width: fixedFullWidth ? '100%' : (($box.width() - 1))\n                        });\n\n                        $('.' + t.o.prefix + 'fixed-top', $box).css({\n                            position: fixedFullWidth ? 'fixed' : 'absolute',\n                            top: fixedFullWidth ? buttonPaneOuterHeight : buttonPaneOuterHeight + (scrollTop - offset),\n                            zIndex: 15\n                        });\n                    } else if (t.isFixed) {\n                        t.isFixed = false;\n                        $buttonPane.removeAttr('style');\n                        t.$box.css({paddingTop: 0});\n                        $('.' + t.o.prefix + 'fixed-top', $box).css({\n                            position: 'absolute',\n                            top: buttonPaneOuterHeight\n                        });\n                    }\n                });\n        },\n\n        // Disable editor\n        setDisabled: function (disable) {\n            var t = this,\n                prefix = t.o.prefix;\n\n            t.disabled = disable;\n\n            if (disable) {\n                t.$ta.attr('disabled', true);\n            } else {\n                t.$ta.removeAttr('disabled');\n            }\n            t.$box.toggleClass(prefix + 'disabled', disable);\n            t.$ed.attr('contenteditable', !disable);\n        },\n\n        // Destroy the editor\n        destroy: function () {\n            var t = this,\n                prefix = t.o.prefix;\n\n            if (t.isTextarea) {\n                t.$box.after(\n                    t.$ta\n                        .css({height: ''})\n                        .val(t.html())\n                        .removeClass(prefix + 'textarea')\n                        .show()\n                );\n            } else {\n                t.$box.after(\n                    t.$edBox\n                        .css({height: ''})\n                        .removeClass(prefix + 'editor')\n                        .removeAttr('contenteditable')\n                        .removeAttr('dir')\n                        .html(t.html())\n                        .show()\n                );\n            }\n\n            t.$ed.off('dblclick', 'img');\n\n            t.destroyPlugins();\n\n            t.$box.remove();\n            t.$c.removeData('trumbowyg');\n            $('body').removeClass(prefix + 'body-fullscreen');\n            t.$c.trigger('tbwclose');\n            $(window).off('scroll.' + t.eventNamespace + ' resize.' + t.eventNamespace);\n            $(t.doc.body).off('keydown.' + t.eventNamespace);\n        },\n\n\n        // Empty the editor\n        empty: function () {\n            this.doc.execCommand('insertHTML', false, '');\n            this.$ta.val('');\n            this.syncCode(true);\n        },\n\n\n        // Function call when click on viewHTML button\n        toggle: function () {\n            var t = this,\n                prefix = t.o.prefix;\n\n            if (t.o.autogrowOnEnter) {\n                t.autogrowOnEnterDontClose = !t.$box.hasClass(prefix + 'editor-hidden');\n            }\n\n            t.semanticCode(false, true);\n            t.$c.trigger('tbwchange');\n\n            setTimeout(function () {\n                t.doc.activeElement.blur();\n                t.$box.toggleClass(prefix + 'editor-hidden ' + prefix + 'editor-visible');\n                t.$btnPane.toggleClass(prefix + 'disable');\n                $('.' + prefix + 'viewHTML-button', t.$btnPane).toggleClass(prefix + 'active');\n                if (t.$box.hasClass(prefix + 'editor-visible')) {\n                    t.$ta.attr('tabindex', -1);\n                } else {\n                    t.$ta.removeAttr('tabindex');\n                }\n\n                if (t.o.autogrowOnEnter && !t.autogrowOnEnterDontClose) {\n                    t.autogrowEditorOnEnter();\n                }\n            }, 0);\n        },\n\n        // Remove or add flags to span tags to remove Chrome generated spans\n        toggleSpan: function (addFlag) {\n            var t = this;\n            t.$ed.find('span').each(function () {\n                if (addFlag === true) {\n                    $(this).attr('data-tbw-flag', true);\n                } else {\n                    if ($(this).attr('data-tbw-flag')) {\n                        $(this).removeAttr('data-tbw-flag');\n                    } else {\n                        $(this).contents().unwrap();\n                    }\n                }\n            });\n        },\n\n        // Open dropdown when click on a button which open that\n        dropdown: function (name) {\n            var t = this,\n                $body = $('body', t.doc),\n                prefix = t.o.prefix,\n                $dropdown = $('[data-' + prefix + 'dropdown=' + name + ']', t.$box),\n                $btn = $('.' + prefix + name + '-button', t.$btnPane),\n                show = $dropdown.is(':hidden');\n\n            $body.trigger('mousedown');\n\n            if (show) {\n                var btnOffsetLeft = $btn.offset().left;\n                $btn.addClass(prefix + 'active');\n\n                $dropdown.css({\n                    position: 'absolute',\n                    top: $btn.offset().top - t.$btnPane.offset().top + $btn.outerHeight(),\n                    left: (t.o.fixedFullWidth && t.isFixed) ? btnOffsetLeft : (btnOffsetLeft - t.$btnPane.offset().left)\n                }).show();\n\n                $(window).trigger('scroll');\n\n                $body.on('mousedown.' + t.eventNamespace, function (e) {\n                    if (!$dropdown.is(e.target)) {\n                        $('.' + prefix + 'dropdown', t.$box).hide();\n                        $('.' + prefix + 'active', t.$btnPane).removeClass(prefix + 'active');\n                        $body.off('mousedown.' + t.eventNamespace);\n                    }\n                });\n            }\n        },\n\n\n        // HTML Code management\n        html: function (html) {\n            var t = this;\n\n            if (html != null) {\n                t.$ta.val(html);\n                t.syncCode(true);\n                t.$c.trigger('tbwchange');\n                return t;\n            }\n\n            return t.$ta.val();\n        },\n        syncTextarea: function () {\n            var t = this;\n            t.$ta.val(t.$ed.text().trim().length > 0 || t.$ed.find(t.o.tagsToKeep.join(',')).length > 0 ? t.$ed.html() : '');\n        },\n        syncCode: function (force) {\n            var t = this;\n            if (!force && t.$ed.is(':visible')) {\n                t.syncTextarea();\n            } else {\n                // wrap the content in a div it's easier to get the inner html\n                var html = $('<div>').html(t.$ta.val());\n                // scrub the html before loading into the doc\n                var safe = $('<div>').append(html);\n                $(t.o.tagsToRemove.join(','), safe).remove();\n                t.$ed.html(safe.contents().html());\n            }\n\n            if (t.o.autogrow) {\n                t.height = t.$edBox.height();\n                if (t.height !== t.$ta.css('height')) {\n                    t.$ta.css({height: t.height});\n                    t.$c.trigger('tbwresize');\n                }\n            }\n            if (t.o.autogrowOnEnter) {\n                t.$edBox.height('auto');\n                var totalHeight = t.autogrowOnEnterWasFocused ? t.$edBox[0].scrollHeight : t.$edBox.css('min-height');\n                if (totalHeight !== t.$ta.css('height')) {\n                    t.$edBox.css({height: totalHeight});\n                    t.$c.trigger('tbwresize');\n                }\n            }\n        },\n\n        // Analyse and update to semantic code\n        // @param force : force to sync code from textarea\n        // @param full  : wrap text nodes in <p>\n        // @param keepRange  : leave selection range as it is\n        semanticCode: function (force, full, keepRange) {\n            var t = this;\n            t.saveRange();\n            t.syncCode(force);\n\n            var restoreRange = true;\n            if (t.range && t.range.collapsed) {\n                restoreRange = false;\n            }\n\n            if (t.o.semantic) {\n                t.semanticTag('b', t.o.semanticKeepAttributes);\n                t.semanticTag('i', t.o.semanticKeepAttributes);\n                t.semanticTag('s', t.o.semanticKeepAttributes);\n                t.semanticTag('strike', t.o.semanticKeepAttributes);\n\n                if (full) {\n                    var inlineElementsSelector = t.o.inlineElementsSelector,\n                        blockElementsSelector = ':not(' + inlineElementsSelector + ')';\n\n                    // Wrap text nodes in span for easier processing\n                    t.$ed.contents().filter(function () {\n                        return this.nodeType === 3 && this.nodeValue.trim().length > 0;\n                    }).wrap('<span data-tbw/>');\n\n                    // Wrap groups of inline elements in paragraphs (recursive)\n                    var wrapInlinesInParagraphsFrom = function ($from) {\n                        if ($from.length !== 0) {\n                            var $finalParagraph = $from.nextUntil(blockElementsSelector).addBack().wrapAll('<p/>').parent(),\n                                $nextElement = $finalParagraph.nextAll(inlineElementsSelector).first();\n                            $finalParagraph.next('br').remove();\n                            wrapInlinesInParagraphsFrom($nextElement);\n                        }\n                    };\n                    wrapInlinesInParagraphsFrom(t.$ed.children(inlineElementsSelector).first());\n\n                    t.semanticTag('div', true);\n\n                    // Get rid of temporary span's\n                    $('[data-tbw]', t.$ed).contents().unwrap();\n\n                    // Remove empty <p>\n                    t.$ed.find('p:empty').remove();\n                }\n\n                if (!keepRange && restoreRange) {\n                    t.restoreRange();\n                }\n\n                t.syncTextarea();\n            }\n        },\n\n        semanticTag: function (oldTag, copyAttributes, revert) {\n            var newTag, t = this;\n            var tmpTag = oldTag;\n\n            if (this.o.semantic != null && typeof this.o.semantic === 'object' && this.o.semantic.hasOwnProperty(oldTag)) {\n                newTag = this.o.semantic[oldTag];\n            } else if (this.o.semantic === true && this.DEFAULT_SEMANTIC_MAP.hasOwnProperty(oldTag)) {\n                newTag = this.DEFAULT_SEMANTIC_MAP[oldTag];\n            } else {\n                return;\n            }\n\n            if (revert) {\n                oldTag = newTag;\n                newTag = tmpTag;\n            }\n\n            $(oldTag, this.$ed).each(function () {\n                var resetRange = false;\n                var $oldTag = $(this);\n                if ($oldTag.contents().length === 0) {\n                    return false;\n                }\n\n                if (t.range && t.range.startContainer.parentNode === this) {\n                    resetRange = true;\n                }\n                var $newTag = $('<' + newTag + '/>');\n                $newTag.insertBefore($oldTag);\n                if (copyAttributes) {\n                    $.each($oldTag.prop('attributes'), function () {\n                        $newTag.attr(this.name, this.value);\n                    });\n                }\n                $newTag.html($oldTag.html());\n                $oldTag.remove();\n                if (resetRange === true) {\n                    t.range.selectNodeContents($newTag.get(0));\n                    t.range.collapse(false);\n                }\n            });\n        },\n\n        // Function call when user click on \"Insert Link\"\n        createLink: function () {\n            var t = this,\n                documentSelection = t.doc.getSelection(),\n                selectedRange = documentSelection.getRangeAt(0),\n                node = documentSelection.focusNode,\n                text = new XMLSerializer().serializeToString(selectedRange.cloneContents()) || selectedRange + '',\n                url,\n                title,\n                target,\n                linkDefaultTarget = t.o.linkTargets[0];\n\n            while (['A', 'DIV'].indexOf(node.nodeName) < 0) {\n                node = node.parentNode;\n            }\n\n            if (node && node.nodeName === 'A') {\n                var $a = $(node);\n                text = $a.text();\n                url = $a.attr('href');\n                if (!t.o.minimalLinks) {\n                    title = $a.attr('title');\n                    target = $a.attr('target') || linkDefaultTarget;\n                }\n                var range = t.doc.createRange();\n                range.selectNode(node);\n                documentSelection.removeAllRanges();\n                documentSelection.addRange(range);\n            }\n\n            t.saveRange();\n\n            var options = {\n                url: {\n                    label: t.lang.linkUrl || 'URL',\n                    required: true,\n                    value: url\n                },\n                text: {\n                    label: t.lang.text,\n                    value: text\n                }\n            };\n            if (!t.o.minimalLinks) {\n                var targetOptions = t.o.linkTargets.reduce(function (options, optionValue) {\n                    options[optionValue] = t.lang[optionValue];\n\n                    return options;\n                }, {});\n\n                $.extend(options, {\n                    title: {\n                        label: t.lang.title,\n                        value: title\n                    },\n                    target: {\n                        label: t.lang.target,\n                        value: target,\n                        options: targetOptions\n                    }\n                });\n            }\n\n            t.openModalInsert(t.lang.createLink, options, function (v) { // v is value\n                var url = t.prependUrlPrefix(v.url);\n                if (!url.length) {\n                    return false;\n                }\n\n                var link = $(['<a href=\"', url, '\">', v.text || v.url, '</a>'].join(''));\n\n                if (v.title) {\n                    link.attr('title', v.title);\n                }\n                if (v.target || linkDefaultTarget) {\n                    link.attr('target', v.target || linkDefaultTarget);\n                }\n                t.range.deleteContents();\n                t.range.insertNode(link[0]);\n                t.syncCode();\n                t.$c.trigger('tbwchange');\n                return true;\n            });\n        },\n        prependUrlPrefix: function (url) {\n            var t = this;\n            if (!t.urlPrefix) {\n                return url;\n            }\n\n            var VALID_LINK_PREFIX = /^([a-z][-+.a-z0-9]*:|\\/|#)/i;\n            if (VALID_LINK_PREFIX.test(url)) {\n                return url;\n            }\n\n            var SIMPLE_EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n            if (SIMPLE_EMAIL_REGEX.test(url)) {\n                return 'mailto:' + url;\n            }\n\n            return t.urlPrefix + url;\n        },\n        unlink: function () {\n            var t = this,\n                documentSelection = t.doc.getSelection(),\n                node = documentSelection.focusNode;\n\n            if (documentSelection.isCollapsed) {\n                while (['A', 'DIV'].indexOf(node.nodeName) < 0) {\n                    node = node.parentNode;\n                }\n\n                if (node && node.nodeName === 'A') {\n                    var range = t.doc.createRange();\n                    range.selectNode(node);\n                    documentSelection.removeAllRanges();\n                    documentSelection.addRange(range);\n                }\n            }\n            t.execCmd('unlink', undefined, undefined, true);\n        },\n        insertImage: function () {\n            var t = this;\n            t.saveRange();\n\n            var options = {\n                url: {\n                    label: 'URL',\n                    required: true\n                },\n                alt: {\n                    label: t.lang.description,\n                    value: t.getRangeText()\n                }\n            };\n\n            if (t.o.imageWidthModalEdit) {\n                options.width = {};\n            }\n\n            t.openModalInsert(t.lang.insertImage, options, function (v) { // v are values\n                t.execCmd('insertImage', v.url, false, true);\n                var $img = $('img[src=\"' + v.url + '\"]:not([alt])', t.$box);\n                $img.attr('alt', v.alt);\n\n                if (t.o.imageWidthModalEdit) {\n                    $img.attr({\n                        width: v.width\n                    });\n                }\n\n                t.syncCode();\n                t.$c.trigger('tbwchange');\n\n                return true;\n            });\n        },\n        fullscreen: function () {\n            var t = this,\n                prefix = t.o.prefix,\n                fullscreenCssClass = prefix + 'fullscreen',\n                fullscreenPlaceholderClass = fullscreenCssClass + '-placeholder',\n                isFullscreen,\n                editorHeight = t.$box.outerHeight();\n\n            t.$box.toggleClass(fullscreenCssClass);\n            isFullscreen = t.$box.hasClass(fullscreenCssClass);\n\n            if (isFullscreen) {\n                t.$box.before(\n                    $('<div/>', {\n                        class: fullscreenPlaceholderClass\n                    }).css({\n                        height: editorHeight\n                    })\n                );\n            } else {\n                $('.' + fullscreenPlaceholderClass).remove();\n            }\n\n            $('body').toggleClass(prefix + 'body-fullscreen', isFullscreen);\n            $(window).trigger('scroll');\n            t.$c.trigger('tbw' + (isFullscreen ? 'open' : 'close') + 'fullscreen');\n        },\n\n        applyTagClasses: function () {\n            var t = this;\n            for (const tag of Object.keys(t.o.tagClasses)) {\n                $(tag, t.$ed).addClass(t.o.tagClasses[tag]);\n            }\n            t.syncCode();\n        },\n\n        /*\n         * Call method of trumbowyg if exist\n         * else try to call anonymous function\n         * and finally native execCommand\n         */\n        execCmd: function (cmd, param, forceCss, skipTrumbowyg) {\n            var t = this;\n            skipTrumbowyg = !!skipTrumbowyg || '';\n\n            if (cmd !== 'dropdown') {\n                t.$ed.focus();\n            }\n\n            if (cmd === 'strikethrough' && t.o.semantic) {\n                t.semanticTag('strike', t.o.semanticKeepAttributes, true); // browsers cannot undo e.g. <del> as they expect <strike>\n            }\n\n            try {\n                t.doc.execCommand('styleWithCSS', false, forceCss || false);\n            } catch (c) {\n            }\n\n            try {\n                t[cmd + skipTrumbowyg](param);\n            } catch (c) {\n                try {\n                    cmd(param);\n                } catch (e2) {\n                    if (cmd === 'insertHorizontalRule') {\n                        param = undefined;\n                    } else if (cmd === 'formatBlock' && t.isIE) {\n                        param = '<' + param + '>';\n                    }\n\n                    t.doc.execCommand(cmd, false, param);\n\n                    t.syncCode();\n                    t.semanticCode(false, true);\n                }\n\n                if (cmd !== 'dropdown') {\n                    t.updateButtonPaneStatus();\n                    t.$c.trigger('tbwchange');\n                }\n            }\n\n            try {\n                t.applyTagClasses();\n            } catch (e) {\n            }\n        },\n\n\n        // Open a modal box\n        openModal: function (title, content, buildForm) {\n            var t = this,\n                prefix = t.o.prefix;\n\n            buildForm = buildForm !== false;\n\n            // No open a modal box when exist other modal box\n            if ($('.' + prefix + 'modal-box', t.$box).length > 0) {\n                return false;\n            }\n            if (t.o.autogrowOnEnter) {\n                t.autogrowOnEnterDontClose = true;\n            }\n\n            t.saveRange();\n            t.showOverlay();\n\n            // Disable all btnPane btns\n            t.$btnPane.addClass(prefix + 'disable');\n\n            // Build out of ModalBox, it's the mask for animations\n            var $modal = $('<div/>', {\n                class: prefix + 'modal ' + prefix + 'fixed-top'\n            }).css({\n                top: t.$box.offset().top + t.$btnPane.height(),\n                zIndex: 99999\n            }).appendTo($(t.doc.body));\n\n            var darkClass = prefix + 'dark';\n            if (t.$c.parents('.' + darkClass).length !== 0) {\n                $modal.addClass(darkClass);\n            }\n\n            // Click on overlay close modal by cancelling them\n            t.$overlay.one('click', function () {\n                $modal.trigger(CANCEL_EVENT);\n                return false;\n            });\n\n            // Build the form\n            var formOrContent;\n            if (buildForm) {\n                formOrContent = $('<form/>', {\n                    action: '',\n                    html: content\n                })\n                    .on('submit', function () {\n                        $modal.trigger(CONFIRM_EVENT);\n                        return false;\n                    })\n                    .on('reset', function () {\n                        $modal.trigger(CANCEL_EVENT);\n                        return false;\n                    })\n                    .on('submit reset', function () {\n                        if (t.o.autogrowOnEnter) {\n                            t.autogrowOnEnterDontClose = false;\n                        }\n                    });\n            } else {\n                formOrContent = content;\n            }\n\n\n            // Build ModalBox and animate to show them\n            var $box = $('<div/>', {\n                class: prefix + 'modal-box',\n                html: formOrContent\n            })\n                .css({\n                    top: '-' + t.$btnPane.outerHeight(),\n                    opacity: 0,\n                    paddingBottom: buildForm ? null : '5%'\n                })\n                .appendTo($modal)\n                .animate({\n                    top: 0,\n                    opacity: 1\n                }, 100);\n\n\n            // Append title\n            if (title) {\n                $('<span/>', {\n                    text: title,\n                    class: prefix + 'modal-title'\n                }).prependTo($box);\n            }\n\n            if (buildForm) {\n                // Focus in modal box\n                $(':input:first', $box).focus();\n\n                // Append Confirm and Cancel buttons\n                t.buildModalBtn('submit', $box);\n                t.buildModalBtn('reset', $box);\n\n                $modal.height($box.outerHeight() + 10);\n            }\n\n            $(window).trigger('scroll');\n            t.$c.trigger('tbwmodalopen');\n\n            return $modal;\n        },\n        // @param n is name of modal\n        buildModalBtn: function (n, $modal) {\n            var t = this,\n                prefix = t.o.prefix;\n\n            return $('<button/>', {\n                class: prefix + 'modal-button ' + prefix + 'modal-' + n,\n                type: n,\n                text: t.lang[n] || n\n            }).appendTo($('form', $modal));\n        },\n        // close current modal box\n        closeModal: function () {\n            var t = this,\n                prefix = t.o.prefix;\n\n            // Prevent multiple calls when having multiple editors in the same page\n            if (!t.$btnPane.hasClass(prefix + 'disable')) {\n                return;\n            }\n\n            t.$btnPane.removeClass(prefix + 'disable');\n            t.$overlay.off();\n\n            // Find the modal box\n            var $modalBox = $('.' + prefix + 'modal-box', $(t.doc.body));\n\n            $modalBox.animate({\n                top: '-' + $modalBox.height()\n            }, 100, function () {\n                $modalBox.parent().remove();\n                t.hideOverlay();\n                t.$c.trigger('tbwmodalclose');\n            });\n\n            t.restoreRange();\n        },\n        // Pre-formatted build and management modal\n        openModalInsert: function (title, fields, cmd) {\n            var t = this,\n                prefix = t.o.prefix,\n                lg = t.lang,\n                html = '',\n                idPrefix = prefix + 'form-' + Date.now() + '-';\n\n            $.each(fields, function (fieldName, field) {\n                var l = field.label || fieldName,\n                    n = field.name || fieldName,\n                    a = field.attributes || {},\n                    fieldId = idPrefix + fieldName;\n\n                var attr = Object.keys(a).map(function (prop) {\n                    return prop + '=\"' + a[prop] + '\"';\n                }).join(' ');\n\n                if (typeof field.type === 'function') {\n                    if (!field.name) {\n                        field.name = n;\n                    }\n\n                    html += field.type(field, fieldId, prefix, lg);\n\n                    return;\n                }\n\n                html += '<div class=\"' + prefix + 'input-row\">';\n                html += '<div class=\"' + prefix + 'input-infos\"><label for=\"' + fieldId + '\"><span>' + (lg[l] ? lg[l] : l) + '</span></label></div>';\n                html += '<div class=\"' + prefix + 'input-html\">';\n\n                if ($.isPlainObject(field.options)) {\n                    html += '<select id=\"' + fieldId + '\" name=\"' + n + '\">';\n                    html += Object.keys(field.options).map((optionValue) => {\n                        return '<option value=\"' + optionValue + '\" ' + (optionValue === field.value ? 'selected' : '') + '>' + field.options[optionValue] + '</option>';\n                    }).join('');\n                    html += '</select>';\n                } else {\n                    html += '<input id=\"' + fieldId + '\" type=\"' + (field.type || 'text') + '\" name=\"' + n + '\" ' + attr;\n                    html += (field.type === 'checkbox' && field.value ? ' checked=\"checked\"' : '') + ' value=\"' + (field.value || '').replace(/\"/g, '&quot;') + '\">';\n                }\n\n                html += '</div></div>';\n            });\n\n            return t.openModal(title, html)\n                .on(CONFIRM_EVENT, function () {\n                    var $form = $('form', $(this)),\n                        valid = true,\n                        values = {};\n\n                    $.each(fields, function (fieldName, field) {\n                        var n = field.name || fieldName;\n\n                        var $field = $(':input[name=\"' + n + '\"]', $form),\n                            inputType = $field[0].type;\n\n                        switch (inputType.toLowerCase()) {\n                            case 'checkbox':\n                                values[n] = $field.is(':checked');\n                                break;\n                            case 'radio':\n                                values[n] = $field.filter(':checked').val();\n                                break;\n                            default:\n                                values[n] = $field.val().trim();\n                                break;\n                        }\n                        // Validate value\n                        if (field.required && values[n] === '') {\n                            valid = false;\n                            t.addErrorOnModalField($field, t.lang.required);\n                        } else if (field.pattern && !field.pattern.test(values[n])) {\n                            valid = false;\n                            t.addErrorOnModalField($field, field.patternError);\n                        }\n                    });\n\n                    if (valid) {\n                        t.restoreRange();\n\n                        if (cmd(values, fields)) {\n                            t.syncCode();\n                            t.$c.trigger('tbwchange');\n                            t.closeModal();\n                            $(this).off(CONFIRM_EVENT);\n                        }\n                    }\n                })\n                .one(CANCEL_EVENT, function () {\n                    $(this).off(CONFIRM_EVENT);\n                    t.closeModal();\n                });\n        },\n        addErrorOnModalField: function ($field, err) {\n            var prefix = this.o.prefix,\n                spanErrorClass = prefix + 'msg-error',\n                $row = $field.closest('.' + prefix + 'input-row');\n\n            $field\n                .one('change keyup', function () {\n                    $row.removeClass(prefix + 'input-error');\n                });\n\n            $row.find('.' + spanErrorClass).remove();\n            $row\n                .addClass(prefix + 'input-error')\n                .find('.' + prefix + 'input-infos label')\n                .append(\n                    $('<span/>', {\n                        class: spanErrorClass,\n                        text: err\n                    })\n                );\n        },\n\n        getDefaultImgDblClickHandler: function () {\n            var t = this;\n\n            return function () {\n                var $img = $(this),\n                    src = $img.attr('src'),\n                    base64 = '(Base64)';\n\n                if (src.indexOf('data:image') === 0) {\n                    src = base64;\n                }\n\n                var options = {\n                    url: {\n                        label: 'URL',\n                        value: src,\n                        required: true\n                    },\n                    alt: {\n                        label: t.lang.description,\n                        value: $img.attr('alt')\n                    }\n                };\n\n                if (t.o.imageWidthModalEdit) {\n                    options.width = {\n                        value: $img.attr('width') ? $img.attr('width') : ''\n                    };\n                }\n\n                t.openModalInsert(t.lang.insertImage, options, function (v) {\n                    if (v.url !== base64) {\n                        $img.attr({\n                            src: v.url\n                        });\n                    }\n                    $img.attr({\n                        alt: v.alt\n                    });\n\n                    if (t.o.imageWidthModalEdit) {\n                        if (parseInt(v.width) > 0) {\n                            $img.attr({\n                                width: v.width\n                            });\n                        } else {\n                            $img.removeAttr('width');\n                        }\n                    }\n\n                    return true;\n                });\n                return false;\n            };\n        },\n\n        // Range management\n        saveRange: function () {\n            var t = this,\n                documentSelection = t.doc.getSelection();\n\n            t.range = null;\n\n            if (!documentSelection || !documentSelection.rangeCount) {\n                return;\n            }\n\n            var savedRange = t.range = documentSelection.getRangeAt(0),\n                range = t.doc.createRange(),\n                rangeStart;\n            range.selectNodeContents(t.$ed[0]);\n            range.setEnd(savedRange.startContainer, savedRange.startOffset);\n            rangeStart = (range + '').length;\n            t.metaRange = {\n                start: rangeStart,\n                end: rangeStart + (savedRange + '').length\n            };\n        },\n        restoreRange: function () {\n            var t = this,\n                metaRange = t.metaRange,\n                savedRange = t.range,\n                documentSelection = t.doc.getSelection(),\n                range;\n\n            if (!savedRange) {\n                return;\n            }\n\n            if (metaRange && metaRange.start !== metaRange.end) { // Algorithm from http://jsfiddle.net/WeWy7/3/\n                var charIndex = 0,\n                    nodeStack = [t.$ed[0]],\n                    node,\n                    foundStart = false,\n                    stop = false;\n\n                range = t.doc.createRange();\n\n                while (!stop && (node = nodeStack.pop())) {\n                    if (node.nodeType === 3) {\n                        var nextCharIndex = charIndex + node.length;\n                        if (!foundStart && metaRange.start >= charIndex && metaRange.start <= nextCharIndex) {\n                            range.setStart(node, metaRange.start - charIndex);\n                            foundStart = true;\n                        }\n                        if (foundStart && metaRange.end >= charIndex && metaRange.end <= nextCharIndex) {\n                            range.setEnd(node, metaRange.end - charIndex);\n                            stop = true;\n                        }\n                        charIndex = nextCharIndex;\n                    } else {\n                        var cn = node.childNodes,\n                            i = cn.length;\n\n                        while (i > 0) {\n                            i -= 1;\n                            nodeStack.push(cn[i]);\n                        }\n                    }\n                }\n            }\n\n            // Fix IE11 Error 'Could not complete the operation due to error 800a025e'.\n            // https://stackoverflow.com/questions/16160996/could-not-complete-the-operation-due-to-error-800a025e\n            try {\n                documentSelection.removeAllRanges();\n            } catch (e) {\n            }\n\n            documentSelection.addRange(range || savedRange);\n        },\n        getRangeText: function () {\n            return this.range + '';\n        },\n\n        clearButtonPaneStatus: function () {\n            var t = this,\n                prefix = t.o.prefix,\n                activeClasses = prefix + 'active-button ' + prefix + 'active',\n                originalIconClass = prefix + 'original-icon';\n\n            // Reset all buttons and dropdown state\n            $('.' + prefix + 'active-button', t.$btnPane).removeClass(activeClasses);\n            $('.' + originalIconClass, t.$btnPane).each(function () {\n                $(this).find('svg use').attr('xlink:href', $(this).data(originalIconClass));\n            });\n        },\n        updateButtonPaneStatus: function () {\n            var t = this,\n                prefix = t.o.prefix,\n                activeClasses = prefix + 'active-button ' + prefix + 'active',\n                originalIconClass = prefix + 'original-icon',\n                tags = t.getTagsRecursive(t.doc.getSelection().anchorNode);\n\n            t.clearButtonPaneStatus();\n\n            $.each(tags, function (i, tag) {\n                var btnName = t.tagToButton[tag.toLowerCase()],\n                    $btn = $('.' + prefix + btnName + '-button', t.$btnPane);\n\n                if ($btn.length > 0) {\n                    $btn.addClass(activeClasses);\n                } else {\n                    try {\n                        $btn = $('.' + prefix + 'dropdown .' + prefix + btnName + '-dropdown-button', t.$box);\n                        var $btnSvgUse = $btn.find('svg use'),\n                            dropdownBtnName = $btn.parent().data(prefix + 'dropdown'),\n                            $dropdownBtn = $('.' + prefix + dropdownBtnName + '-button', t.$box),\n                            $dropdownBtnSvgUse = $dropdownBtn.find('svg use');\n\n                        // Highlight the dropdown button\n                        $dropdownBtn.addClass(activeClasses);\n\n                        // Switch dropdown icon to the active sub-icon one\n                        if (t.o.changeActiveDropdownIcon && $btnSvgUse.length > 0) {\n                            // Save original icon\n                            $dropdownBtn\n                                .addClass(originalIconClass)\n                                .data(originalIconClass, $dropdownBtnSvgUse.attr('xlink:href'));\n\n                            // Put the active sub-button's icon\n                            $dropdownBtnSvgUse\n                                .attr('xlink:href', $btnSvgUse.attr('xlink:href'));\n                        }\n                    } catch (e) {\n                    }\n                }\n            });\n        },\n        getTagsRecursive: function (element, tags) {\n            var t = this;\n            tags = tags || (element && element.tagName ? [element.tagName] : []);\n\n            if (element && element.parentNode) {\n                if (element.nodeType !== Node.ELEMENT_NODE) {\n                    element = element.parentNode;\n                }\n            } else {\n                return tags;\n            }\n\n            var tag = element.tagName;\n            if (tag === 'DIV') {\n                return tags;\n            }\n            if (tag === 'P' && element.style.textAlign !== '') {\n                tags.push(element.style.textAlign);\n            }\n\n            $.each(t.tagHandlers, function (i, tagHandler) {\n                tags = tags.concat(tagHandler(element, t));\n            });\n\n            tags.push(tag);\n\n            return t.getTagsRecursive(element.parentNode, tags).filter(function (tag) {\n                return tag != null;\n            });\n        },\n\n        // Plugins\n        initPlugins: function () {\n            var t = this;\n            t.loadedPlugins = [];\n            $.each($.trumbowyg.plugins, function (name, plugin) {\n                if (!plugin.shouldInit || plugin.shouldInit(t)) {\n                    plugin.init(t);\n                    if (plugin.tagHandler) {\n                        t.tagHandlers.push(plugin.tagHandler);\n                    }\n                    t.loadedPlugins.push(plugin);\n                }\n            });\n        },\n        destroyPlugins: function () {\n            var t = this;\n            $.each(this.loadedPlugins, function (i, plugin) {\n                if (plugin.destroy) {\n                    plugin.destroy(t);\n                }\n            });\n        }\n    };\n})(navigator, window, document, jQuery);\n"
  },
  {
    "path": "src/ui/sass/trumbowyg.scss",
    "content": "@use \"sass:color\";\n\n$button-size: 35px;\n$icon-size: 17px;\n$pane-spacing: 5px;\n\n$light-color: #ecf0f1;\n$light-background-color-pane: color.adjust($light-color, $lightness: -3%, $space: hsl);\n$light-background-color-button: #ecf0f1;\n$light-background-color-button-active: #fff;\n$light-background-color-editor: #fff;\n$light-background-color-dropdown: #fff;\n$light-background-color-dropdown-button: #fff;\n$light-background-color-modal: #fff;\n$light-border-color: #d7e0e2;\n$light-text-color: #222;\n$light-text-color-dropdown-button: #222;\n\n$dark-color: #222;\n$dark-background-color-editor: #222;\n$dark-background-color-pane: $dark-color;\n$dark-background-color-button: $dark-color;\n$dark-background-color-dropdown: $dark-background-color-pane;\n$dark-background-color-dropdown-button: $dark-background-color-pane;\n$dark-background-color-modal: #333;\n$dark-background-color-modal-button: #333;\n$dark-border-color: #343434;\n$dark-text-color: #fff;\n$dark-text-color-dropdown-button: #fff;\n\n$modal-submit-color: #2ecc71 !default;\n$modal-reset-color: #eee !default;\n\n$transition-duration: 150ms !default;\n$slow-transition-duration: 300ms !default;\n\n$modal-label-width: 150px;\n\n#trumbowyg-icons,\n.trumbowyg-icons {\n    overflow: hidden;\n    visibility: hidden;\n    height: 0;\n    width: 0;\n}\n\n.trumbowyg-box,\n.trumbowyg-modal {\n    *,\n    *::before,\n    *::after {\n        box-sizing: border-box;\n    }\n\n    svg {\n        width: $icon-size;\n        height: 100%;\n        color: $light-text-color;\n        fill: $light-text-color;\n    }\n}\n\n.trumbowyg-box {\n    display: flex;\n    flex-direction: column;\n    min-height: 300px;\n}\n\n.trumbowyg-editor-box {\n    display: block;\n    flex: 1;\n}\n\n.trumbowyg-box,\n.trumbowyg-editor-box {\n    position: relative;\n    width: 100%;\n    border: 1px solid $light-border-color;\n}\n\n.trumbowyg-box .trumbowyg-editor {\n    min-height: 100%;\n    margin: 0 auto;\n}\n\n.trumbowyg-box.trumbowyg-fullscreen {\n    background: #fefefe;\n    border: none !important;\n}\n\n.trumbowyg-editor-box,\n.trumbowyg-textarea {\n    position: relative;\n    box-sizing: border-box;\n    padding: 20px;\n    width: 100%;\n    border-style: none;\n    resize: none;\n    outline: none;\n    overflow: auto;\n    user-select: text; // Avoid issues on iOS\n\n    &.trumbowyg-autogrow-on-enter {\n        transition: height $slow-transition-duration ease-out;\n    }\n}\n\n.trumbowyg-editor-box {\n    padding: 0;\n}\n\n\n.trumbowyg-editor {\n    outline: none;\n    padding: 20px;\n}\n\n.trumbowyg-box-blur .trumbowyg-editor {\n    *,\n    &::before {\n        color: transparent !important;\n        text-shadow: 0 0 7px #333;\n    }\n\n    img,\n    hr {\n        opacity: 0.2;\n    }\n}\n\n.trumbowyg-textarea {\n    position: relative;\n    display: block;\n    overflow: auto;\n    border: none;\n    font-size: 14px;\n    font-family: \"Consolas\", \"Courier\", \"Courier New\", monospace;\n    line-height: 18px;\n}\n\n.trumbowyg-box.trumbowyg-editor-visible {\n    .trumbowyg-textarea {\n        height: 1px !important;\n        width: 25%;\n        min-height: 0 !important;\n        padding: 0 !important;\n        background: none;\n        opacity: 0 !important;\n    }\n}\n\n.trumbowyg-box.trumbowyg-editor-hidden {\n    .trumbowyg-textarea {\n        display: block;\n        flex: 1;\n        margin-bottom: 1px;\n    }\n\n    .trumbowyg-editor-box {\n        display: none;\n    }\n}\n\n.trumbowyg-box.trumbowyg-disabled {\n    .trumbowyg-textarea {\n        opacity: 0.8;\n        background: none;\n    }\n}\n\n.trumbowyg-editor-box[contenteditable=true]:empty:not(:focus)::before {\n    content: attr(placeholder);\n    color: #999;\n    pointer-events: none;\n    white-space: break-spaces;\n}\n\n.trumbowyg-button-pane {\n    display: flex;\n    flex-wrap: wrap;\n    width: 100%;\n    min-height: $button-size + 1;\n    background: $light-color;\n    border-bottom: 1px solid $light-border-color;\n    margin: 0;\n    padding: 0 $pane-spacing;\n    position: relative;\n    list-style-type: none;\n    line-height: 10px;\n    backface-visibility: hidden;\n    overflow: hidden;\n    z-index: 11;\n\n    &::before,\n    &::after {\n        content: \" \";\n        display: block;\n        position: absolute;\n        top: $button-size;\n        left: 0;\n        right: 0;\n        width: 100%;\n        height: 1px;\n        background: color.adjust($light-color, $lightness: -7%, $space: hsl);\n    }\n\n    &::after {\n        top: $button-size * 2 + 1;\n    }\n\n    .trumbowyg-button-group {\n        display: flex;\n        flex-wrap: wrap;\n\n        .trumbowyg-fullscreen-button svg {\n            color: transparent;\n        }\n\n        &::after {\n            content: \" \";\n            display: block;\n            width: 1px;\n            background: color.adjust($light-color, $lightness: -7%, $space: hsl);\n            margin: 0 $pane-spacing;\n            height: $button-size;\n            vertical-align: top;\n        }\n\n        &:last-child::after {\n            content: none;\n        }\n    }\n\n    button {\n        display: block;\n        position: relative;\n        width: $button-size;\n        height: $button-size;\n        padding: 1px 6px !important;\n        margin-bottom: 1px;\n        overflow: hidden;\n        border: none;\n        cursor: pointer;\n        background: none;\n        vertical-align: middle;\n        transition: background-color $transition-duration, opacity $transition-duration;\n\n        &.trumbowyg-textual-button {\n            width: auto;\n            line-height: $button-size;\n            user-select: none;\n        }\n    }\n\n    &.trumbowyg-disable button:not(.trumbowyg-not-disable):not(.trumbowyg-active),\n    button.trumbowyg-disable,\n    .trumbowyg-disabled & button:not(.trumbowyg-not-disable):not(.trumbowyg-viewHTML-button) {\n        opacity: 0.2;\n        cursor: default;\n        pointer-events: none;\n    }\n\n    &.trumbowyg-disable,\n    .trumbowyg-disabled & {\n        .trumbowyg-button-group::before {\n            background: color.adjust($light-background-color-button, $lightness: -3%, $space: hsl);\n        }\n    }\n\n    button:not(.trumbowyg-disable):hover,\n    button:not(.trumbowyg-disable):focus,\n    button.trumbowyg-active {\n        background-color: $light-background-color-button-active;\n        outline: none;\n    }\n\n    .trumbowyg-open-dropdown {\n        &::after {\n            display: block;\n            content: \" \";\n            position: absolute;\n            top: 27px;\n            right: 3px;\n            height: 0;\n            width: 0;\n            border: 3px solid transparent;\n            border-top-color: #555;\n        }\n\n        &.trumbowyg-textual-button {\n            padding-left: 10px !important;\n            padding-right: 18px !important;\n\n            &::after {\n                top: $icon-size;\n                right: 7px;\n            }\n        }\n    }\n\n    .trumbowyg-right {\n        margin-left: auto;\n    }\n}\n\n.trumbowyg-dropdown {\n    max-width: 300px;\n    max-height: 250px;\n    overflow-y: auto;\n    overflow-x: hidden;\n    white-space: nowrap;\n    border: 1px solid $light-border-color;\n    padding: $pane-spacing 0;\n    border-top: none;\n    background: $light-background-color-dropdown;\n    color: $light-text-color;\n    margin-left: -1px;\n    box-shadow: rgba(0, 0, 0, .1) 0 2px 3px;\n    z-index: 12;\n\n    button {\n        display: block;\n        width: 100%;\n        height: $button-size;\n        line-height: $button-size;\n        text-decoration: none;\n        background: $light-background-color-dropdown-button;\n        padding: 0 20px 0 10px;\n        color: $light-text-color-dropdown-button;\n        border: none;\n        cursor: pointer;\n        text-align: left;\n        font-size: 15px;\n        transition: all $transition-duration;\n\n        &:hover,\n        &:focus {\n            background: $light-color;\n        }\n\n        svg {\n            float: left;\n            margin-right: 14px;\n        }\n    }\n}\n\n/* Modal box */\n.trumbowyg-modal {\n    position: absolute;\n    top: 0;\n    left: 50%;\n    transform: translateX(-50%);\n    max-width: 520px;\n    width: 100%;\n    height: 350px;\n    z-index: 12;\n    overflow: hidden;\n    backface-visibility: hidden;\n}\n\n.trumbowyg-modal-box {\n    position: absolute;\n    top: 0;\n    left: 50%;\n    transform: translateX(-50%);\n    max-width: 500px;\n    width: calc(100% - 20px);\n    padding-bottom: 45px;\n    z-index: 1;\n    background-color: $light-background-color-modal;\n    text-align: center;\n    font-size: 14px;\n    font-family: \"Trebuchet MS\", Helvetica, Verdana, sans-serif;\n    box-shadow: rgba(0, 0, 0, .2) 0 2px 3px;\n    backface-visibility: hidden;\n\n    .trumbowyg-modal-title {\n        font-size: 24px;\n        font-weight: bold;\n        margin: 0 0 20px;\n        padding: 15px 0 13px;\n        display: block;\n        border-bottom: 1px solid $light-border-color;\n    }\n\n    .trumbowyg-progress {\n        width: 100%;\n        height: 3px;\n        position: absolute;\n        top: 58px;\n\n        .trumbowyg-progress-bar {\n            background: #2BC06A;\n            width: 0;\n            height: 100%;\n            transition: width $transition-duration linear;\n        }\n    }\n\n    .trumbowyg-input {\n        &-row {\n            position: relative;\n            margin: 15px 12px;\n            border: 1px solid #dedede;\n            overflow: hidden;\n        }\n\n        &-infos {\n            text-align: left;\n            transition: all 150ms;\n            width: $modal-label-width;\n            border-right: 1px solid #dedede;\n            padding: 0 7px;\n            background-color: color.adjust($light-color, $lightness: 5%, $space: hsl);\n            position: absolute;\n            left: 0;\n            top: 0;\n            bottom: 0;\n\n            label {\n                color: color.adjust($light-color, $lightness: -45%, $space: hsl);\n                overflow: hidden;\n                height: 27px;\n                line-height: 27px;\n\n                &, span {\n                    display: block;\n                    height: 27px;\n                    line-height: 27px;\n                    transition: all $transition-duration;\n                }\n            }\n\n            .trumbowyg-msg-error {\n                color: #e74c3c;\n            }\n        }\n\n        &-html {\n            padding: 1px 1px 1px $modal-label-width + 2px;\n\n            &, input, textarea, select {\n                font-size: 14px;\n            }\n\n            input, textarea, select {\n                transition: all $transition-duration;\n                height: 27px;\n                line-height: 27px;\n                border: 0;\n                width: 100%;\n                padding: 0 7px;\n\n                &:hover,\n                &:focus {\n                    outline: 1px solid #95a5a6;\n                }\n\n                &:focus {\n                    background: color.adjust($light-color, $lightness: 5%, $space: hsl);\n                }\n            }\n\n            input[type=\"checkbox\"] {\n                width: 16px;\n                height: 16px;\n                padding: 0;\n            }\n\n            &-with-checkbox {\n                text-align: left;\n                padding: 3px 1px 1px 3px;\n            }\n        }\n\n        &-error {\n            input, select, textarea {\n                outline: 1px solid #e74c3c;\n            }\n\n            .trumbowyg-input-infos label span:first-child {\n                margin-top: -27px;\n            }\n        }\n    }\n\n    .error {\n        margin-top: 25px;\n        display: block;\n        color: red;\n    }\n\n    .trumbowyg-modal-button {\n        position: absolute;\n        bottom: 10px;\n        right: 0;\n        text-decoration: none;\n        color: #fff;\n        display: block;\n        width: 100px;\n        height: $button-size;\n        line-height: 33px;\n        margin: 0 10px;\n        background-color: #333;\n        border: none;\n        cursor: pointer;\n        font-family: \"Trebuchet MS\", Helvetica, Verdana, sans-serif;\n        font-size: 16px;\n        transition: all $transition-duration;\n\n        &.trumbowyg-modal-submit {\n            right: 110px;\n            background: color.adjust($modal-submit-color, $lightness: -3%, $space: hsl);\n\n            &:hover,\n            &:focus {\n                background: color.adjust($modal-submit-color, $lightness: 5%, $space: hsl);\n                outline: none;\n            }\n\n            &:active {\n                background: color.adjust($modal-submit-color, $lightness: -10%, $space: hsl);\n            }\n        }\n\n        &.trumbowyg-modal-reset {\n            color: #555;\n            background: color.adjust($modal-reset-color, $lightness: -3%, $space: hsl);\n\n            &:hover,\n            &:focus {\n                background: color.adjust($modal-reset-color, $lightness: 5%, $space: hsl);\n                outline: none;\n            }\n\n            &:active {\n                background: color.adjust($modal-reset-color, $lightness: -10%, $space: hsl);\n            }\n        }\n    }\n}\n\n.trumbowyg-overlay {\n    position: absolute;\n    background-color: hsla(0, 0%, 100%, 0.5);\n    height: 100%;\n    width: 100%;\n    left: 0;\n    display: none;\n    top: 0;\n    z-index: 10;\n}\n\n/**\n * Fullscreen\n */\nbody.trumbowyg-body-fullscreen {\n    overflow: hidden;\n}\n\n.trumbowyg-fullscreen {\n    position: fixed;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    margin: 0;\n    padding: 0;\n    z-index: 99999;\n\n    &.trumbowyg-box,\n    .trumbowyg-editor-box {\n        border: none;\n    }\n\n    .trumbowyg-editor-box,\n    .trumbowyg-textarea {\n        height: auto !important;\n        overflow: auto;\n    }\n\n    .trumbowyg-overlay {\n        height: 100% !important;\n    }\n\n    .trumbowyg-button-group .trumbowyg-fullscreen-button svg {\n        color: $dark-color;\n        fill: transparent;\n    }\n}\n\n.trumbowyg-editor {\n    object,\n    embed,\n    video,\n    img {\n        max-width: 100%;\n    }\n\n    video,\n    img {\n        height: auto;\n    }\n\n    img {\n        cursor: move;\n    }\n\n    canvas:focus {\n        outline: none;\n    }\n\n    /*\n     * For resetCss option\n     */\n    &.trumbowyg-reset-css {\n        background: #fefefe !important;\n        font-family: \"Trebuchet MS\", Helvetica, Verdana, sans-serif !important;\n        font-size: 14px !important;\n        line-height: 1.45em !important;\n        color: #333 !important;\n        font-weight: normal !important;\n\n        a {\n            color: #15c !important;\n            text-decoration: underline !important;\n        }\n\n        div,\n        p,\n        ul,\n        ol,\n        blockquote {\n            box-shadow: none !important;\n            background: none !important;\n            margin: 0 !important;\n            margin-bottom: 15px !important;\n            line-height: 1.4em !important;\n            font-family: \"Trebuchet MS\", Helvetica, Verdana, sans-serif !important;\n            font-size: 14px !important;\n            border: none !important;\n        }\n\n        iframe,\n        object,\n        hr {\n            margin-bottom: 15px !important;\n        }\n\n        blockquote {\n            margin-left: 32px !important;\n            font-style: italic !important;\n            color: #555 !important;\n        }\n\n        ul {\n            list-style: disc !important;\n        }\n\n        ol {\n            list-style: decimal !important;\n        }\n\n        ul,\n        ol {\n            padding-left: 20px !important;\n        }\n\n        ul ul,\n        ol ol,\n        ul ol,\n        ol ul {\n            border: none !important;\n            margin: 2px !important;\n            padding: 0 !important;\n            padding-left: 24px !important;\n        }\n\n        hr {\n            display: block !important;\n            height: 1px !important;\n            border: none !important;\n            border-top: 1px solid #CCC !important;\n        }\n\n        h1,\n        h2,\n        h3,\n        h4 {\n            color: #111 !important;\n            background: none !important;\n            margin: 0 !important;\n            padding: 0 !important;\n            font-weight: bold !important;\n        }\n\n        h1 {\n            font-size: 32px !important;\n            line-height: 38px !important;\n            margin-bottom: 20px !important;\n        }\n\n        h2 {\n            font-size: 26px !important;\n            line-height: 34px !important;\n            margin-bottom: 15px !important;\n        }\n\n        h3 {\n            font-size: 22px !important;\n            line-height: 28px !important;\n            margin-bottom: 7px !important;\n        }\n\n        h4 {\n            font-size: 16px !important;\n            line-height: 22px !important;\n            margin-bottom: 7px !important;\n        }\n    }\n}\n\n/*\n * Dark theme\n */\n.trumbowyg-dark {\n    .trumbowyg-textarea {\n        background: $dark-background-color-editor;\n        color: $dark-text-color;\n        border-color: $dark-border-color;\n    }\n\n    .trumbowyg-box {\n        border: 1px solid color.adjust($dark-color, $lightness: 7%, $space: hsl);\n\n        &.trumbowyg-fullscreen {\n            background: #111;\n        }\n\n        &.trumbowyg-box-blur .trumbowyg-editor {\n            *,\n            &::before {\n                text-shadow: 0 0 7px #ccc;\n            }\n        }\n\n        svg {\n            fill: $dark-text-color;\n            color: $dark-text-color;\n        }\n    }\n\n    .trumbowyg-button-pane {\n        background-color: $dark-background-color-pane;\n        border-bottom-color: $dark-border-color;\n\n        &::before,\n        &::after {\n            background: color.adjust($dark-color, $lightness: 7%, $space: hsl);\n        }\n\n        .trumbowyg-button-group:not(:empty) {\n            &::after {\n                background-color: color.adjust($dark-color, $lightness: 7%, $space: hsl);\n            }\n\n            .trumbowyg-fullscreen-button svg {\n                color: transparent;\n            }\n        }\n\n        &.trumbowyg-disable {\n            .trumbowyg-button-group::after {\n                background-color: color.adjust($dark-color, $lightness: 3%, $space: hsl);\n            }\n        }\n\n        button:not(.trumbowyg-disable):hover,\n        button:not(.trumbowyg-disable):focus,\n        button.trumbowyg-active {\n            background-color: #333;\n        }\n\n        .trumbowyg-open-dropdown::after {\n            border-top-color: #fff;\n        }\n    }\n\n    .trumbowyg-fullscreen {\n        .trumbowyg-button-pane .trumbowyg-button-group:not(:empty) .trumbowyg-fullscreen-button svg {\n            color: $light-color;\n            fill: transparent;\n        }\n    }\n\n    .trumbowyg-dropdown {\n        border-color: $dark-border-color;\n        background: $dark-background-color-modal;\n        box-shadow: rgba(0, 0, 0, .3) 0 2px 3px;\n\n        button {\n            background: $dark-background-color-modal-button;\n            color: $dark-text-color;\n\n            &:hover,\n            &:focus {\n                background: $dark-color;\n            }\n        }\n    }\n\n    // Modal box\n    .trumbowyg-modal-box {\n        background-color: $dark-background-color-modal;\n        color: $dark-text-color;\n\n        .trumbowyg-modal-title {\n            border-bottom: 1px solid #555;\n            color: $dark-text-color;\n            background: color.adjust($dark-color, $lightness: 10%, $space: hsl);\n        }\n\n        .trumbowyg-input-row {\n            border-color: $dark-background-color-button;\n        }\n\n        .trumbowyg-input-infos {\n            color: #eee;\n            background-color: color.adjust($dark-color, $lightness: 5%, $space: hsl);\n            border-right-color: $dark-background-color-button;\n\n            span {\n                color: #eee;\n                background-color: color.adjust($dark-color, $lightness: 5%, $space: hsl);\n                border-color: $dark-border-color;\n            }\n\n            span.trumbowyg-msg-error {\n                color: #e74c3c;\n            }\n        }\n\n        .trumbowyg-input-row.trumbowyg-input-error {\n            input,\n            select,\n            textarea {\n                border-color: #e74c3c;\n            }\n        }\n\n        input,\n        select,\n        textarea {\n            border-color: $dark-border-color;\n            color: $dark-text-color;\n            background: $dark-background-color-editor;\n\n            &:hover,\n            &:focus {\n                border-color: color.adjust($dark-color, $lightness: 25%, $space: hsl);\n            }\n\n            &:focus {\n                background-color: color.adjust($dark-color, $lightness: 5%, $space: hsl);\n            }\n        }\n\n        .trumbowyg-modal-button {\n            &.trumbowyg-modal-submit {\n                background: color.adjust($modal-submit-color, $lightness: -20%, $space: hsl);\n\n                &:hover,\n                &:focus {\n                    background: color.adjust($modal-submit-color, $lightness: -10%, $space: hsl);\n                }\n\n                &:active {\n                    background: color.adjust($modal-submit-color, $lightness: -25%, $space: hsl);\n                }\n            }\n\n            &.trumbowyg-modal-reset {\n                background: #333;\n                color: #ccc;\n\n                &:hover,\n                &:focus {\n                    background: #444;\n                }\n\n                &:active {\n                    background: #111;\n                }\n            }\n        }\n    }\n\n    .trumbowyg-overlay {\n        background-color: rgba(15, 15, 15, 0.6);\n    }\n}\n"
  }
]