[
  {
    "path": ".gitattributes",
    "content": ".gitattributes export-ignore\n.gitignore export-ignore\n.travis.yml export-ignore\ncomposer.json export-ignore\nCONTRIBUTING.md export-ignore\nGruntfile.js export-ignore\npackage.json export-ignore\nREADME.md export-ignore\ntests/ export-ignore\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules\n.sass-cache\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: php\n\nsudo: false\n\nphp:\n  - 5.4\n  - 5.5\n  - 5.6\n  - hhvm\n  - nightly\n\n# Specify versions of WordPress to test against\nenv:\n  - WP_VERSION=latest WP_MULTISITE=0\n  - WP_VERSION=latest WP_MULTISITE=1\n  - WP_VERSION=4.1 WP_MULTISITE=0\n  - WP_VERSION=4.0 WP_MULTISITE=0\n  - WP_VERSION=3.9.2 WP_MULTISITE=0\n\nmatrix:\n  include:\n    - php: 5.3\n      env: WP_VERSION=latest WP_MULTISITE=1\n  exclude:\n    - php: hhvm\n      env: WP_VERSION=3.9.2 WP_MULTISITE=0\n    - php: hhvm\n      env: WP_VERSION=4.0 WP_MULTISITE=0\n\nnotifications:\n  slack: aesop:GGeOu8QQeUGTkLvO1zTblBZv\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "This repository is for reporting Editus bugs only. This is not a support forum. If you need any help with Editus please email help@lasso.is with the same email that you purchased Editus with so that our system will identify you. \n\nWhen submitting a pull request, test Editus with [Aesop Story Theme](https://github.com/AesopInteractive/aesop-story-theme), and make any pull requests against our latest release branch.\n"
  },
  {
    "path": "Gruntfile.js",
    "content": "'use strict';\nmodule.exports = function(grunt) {\n\n    require('load-grunt-tasks')(grunt);\n\n    grunt.initConfig({\n\n        // watch our project for changes\n        watch: {\n        \tconcat: {\n        \t\tfiles: ['public/assets/js/source/*'],\n        \t\ttasks:['concat:dist', 'uglify' ]\n        \t},\n            less: {\n\t\t\t\tfiles: ['public/assets/less/**/*','admin/assets/less/**/*'],\n                tasks: ['less:coreLess','less:settingsLess']\n            },\n            livereload: {\n                options: { livereload: true },\n                files: ['public/assets/**/*','admin/assets/**/*', '**/*.html', '**/*.php', 'public/assets/img/**/*.{png,jpg,jpeg,gif,webp,svg}']\n            },\n        },\n        less: {\n\t\t  \tcoreLess: {\n\t\t  \t\toptions: {\n\t\t      \t\tpaths: ['public/assets/less/*'],\n\t\t      \t\tcleancss:true\n\t\t    \t},\n\t\t    \tfiles: {\n\t\t      \t\t'public/assets/css/lasso.css': 'public/assets/less/style.less'\n\t\t    \t}\n\t\t  \t},\n\t\t  \tsettingsLess: {\n\t\t  \t\toptions: {\n\t\t      \t\tpaths: ['admin/assets/less/*'],\n\t\t      \t\tcleancss:true\n\t\t    \t},\n\t\t    \tfiles: {\n\t\t      \t\t'admin/assets/css/lasso-editor-settings.css': 'admin/assets/less/style.less'\n\t\t    \t}\n\t\t    }\n        },\n   \t\tconcat: {\n            dist: {\n                src: [\n                    'public/assets/js/source/util--undo.js',\n                    'public/assets/js/source/util--rangy-core.js',\n                    'public/assets/js/source/util--rangy-classapplier.js',\n                    'public/assets/js/source/util--content-editable.js',\n                    'public/assets/js/source/util--scrollbar.js',\n                    'public/assets/js/source/util--sweet-alert.js',\n                    'public/assets/js/source/util--geo-complete.js',\n                    'public/assets/js/source/util--imagesloaded.js',\n                    'public/assets/js/source/util--slider.js',\n                    'public/assets/js/source/util--touch-punch.js',\n                    'public/assets/js/source/util--tagit.js',\n                    'public/assets/js/source/enter-editor.js',\n                    'public/assets/js/source/post-settings.js',\n                    'public/assets/js/source/settings-panel.js',\n                    'public/assets/js/source/settings-live-editing.js',\n                    'public/assets/js/source/toolbar.js',\n                    'public/assets/js/source/process-save.js',\n                    'public/assets/js/source/process-gallery.js',\n                    'public/assets/js/source/process-gallery-opts.js',\n                    'public/assets/js/source/process-map.js',\n                    'public/assets/js/source/process-image-upload.js',\n                    'public/assets/js/source/process-save-component.js',\n                    'public/assets/js/source/process-new-post.js',\n                    'public/assets/js/source/process-save-title.js',\n                    'public/assets/js/source/process-wpimg.js',\n                    'public/assets/js/source/process-save-meta.js',\n                    'public/assets/js/source/modal-sizing.js',\n                    'public/assets/js/source/all-posts.js',\n                    'public/assets/js/source/tour.js',\n                    'public/assets/js/source/revisions.js'\n               \t],\n                dest: 'public/assets/js/lasso.js'\n            }\n        },\n   \t\tuglify: {\n            scripts: {\n            \toptions: {\n\t\t\t\t\tsourceMap: 'public/assets/js/lasso.js.map',\n\t\t\t\t\tsourceMappingURL: 'lasso.js.map'\n\t\t\t\t},\n                files: {\n                    'public/assets/js/lasso.min.js': [\n                        'public/assets/js/lasso.js'\n                    ]\n                }\n            }\n        },\n        makepot: {\n\t\t    target: {\n\t\t        options: {\n\t\t          \tdomainPath: '/languages/',    // Where to save the POT file.\n\t\t          \texclude: ['build/.*'],\n\t\t          \tmainFile: 'lasso.php',    // Main project file.\n\t\t          \tpotFilename: 'lasso.pot',    // Name of the POT file.\n\t\t          \tpotHeaders: {\n\t\t                poedit: true,                 // Includes common Poedit headers.\n\t\t              \t'x-poedit-keywordslist': true // Include a list of all possible gettext functions.\n\t\t           \t},\n\t\t         \ttype: 'wp-plugin',    // Type of project (wp-plugin or wp-theme).\n\t\t          \tupdateTimestamp: true,    // Whether the POT-Creation-Date should be updated without other changes.\n\t\t          \tprocessPot: function( pot, options ) {\n\t\t            \tpot.headers['report-msgid-bugs-to'] = 'http://edituswp.com';\n\t\t            \tpot.headers['language'] = 'en_US';\n\t\t            \treturn pot;\n\t\t          \t}\n\t\t        }\n\t\t    }\n\t    }\n    });\n\n    // register task\n    grunt.registerTask('default', ['watch']);\n\n};\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License."
  },
  {
    "path": "README.md",
    "content": " <table width=\"100%\">\n\t<tr>\n\t\t<td align=\"left\" width=\"70%\">\n\t\t\t<strong><a href=\"https://edituswp.com\">Editus</a></strong><br />\n\t\t\tContent creation and editing made simple\n\t\t</td>\n\t\t<td align=\"right\" width=\"20%\">\n\t\t\t<a href=\"https://scrutinizer-ci.com/g/AesopInteractive/lasso/?branch=master\">\n\t\t\t\t<img src=\"https://scrutinizer-ci.com/g/AesopInteractive/lasso/badges/quality-score.png?b=master\" alt=\"Build status\">\n\t\t\t</a>\n\t\t</td>\n\t</tr>\n</table>\n\nEditus is a commercial plugin available from https://edituswp.com. The plugin is hosted here on a public GitHub repository in order to better faciliate community contributions from developers and users alike. If you have a suggestion, a bug report, or a patch for an issue, feel free to submit it [here](https://github.com/AesopInteractive/lasso/issues). When submitting a pull request, test Editus with [Aesop Story Theme](https://github.com/AesopInteractive/aesop-story-theme), and make any pull requests against our latest release branch.\n\nWe do ask, however, that if you are using the plugin on a live site that you please purchase a valid license from the website. We cannot provide support to anyone who does not hold a valid license key.\n\nDeveloper documentation can be found [here](https://github.com/AesopInteractive/lasso-documentation).\n\nPull requests for our documentation are [welcome](https://github.com/AesopInteractive/lasso-documentation/pulls). \n\n## Requirements\n\nEditus requires PHP 5.4 or above.\n"
  },
  {
    "path": "README.txt",
    "content": "=== Editus ===\nContributors: nphaskins, hyunster, michaelbeil\nPlugin URI: https://edituswp.com\nRequires at least: 3.5\nTested up to: 5.9\nStable tag: 1.5.1\n\nFront-end editing and creation suite.\n\n== Description ==\n\nFront-end editing and creation suite.\n\n\n== Changelog ==\n= 1.5.1\n* Support for Gutenberg list blocks\n\n= 1.5.0\n* Allowing the component pop up when using a keyboard without a mouse\n\n= 1.4.9\n* Improved compatibility with standard WP blocks\n\n= 1.4.5\n* NEW: Optional Paragraph component\n* Further changes for the popup menu option\n* Timeline Component Fix\n\n= 1.4.3\n* NEW: Text popup menu option\n* A fix for custom post types\n\n= 1.4.1\n* A bug fix for simple image component\n* NEW: Setting to change the placeholder text for new posts\n\n= 1.4.0\n* NEW: Custom Taxonomy Support Option\n\n= 1.3.10\n* Partial support for Gutenberg Cover Block\n* Fixed the issue where the component controls were disappearing after saving\n\n= 1.3.8\n* Support for Gutenberg Image Block\n* Fixed the issue that custom post types could not save custom fields\n\n= 1.3.6\n* The table component component right click menu now supports deleting the table\n* Minor bug fixes\n\n= 1.3.5\n* Fix for simple image components\n* New option to auto-prefix links with http://\n\n= 1.3.4\n* More non-Aesop image component options\n\n\n= 1.3.3\n* More non-Aesop image component options\n* Support for More Tag\n* Bug fixes\n\n= 1.3.0\n* NEW option to edit excerpts\n* NEW new options for non-Aesop image components\n\n= 1.2.9\n* Bug fix for custom fields\n\n= 1.2.8\n* New optional table component\n\n= 1.2.6\n* UI customization fixes\n\n\n= 1.2.5\n* Fix for gallery create/update\n* Allow component icon color customization\n* Further Gutenberg compatibility work\n\n= 1.2.4\n* Fix for post settings\n* Further Gutenberg compatibility work\n\n= 1.2.3\n* Fix for Aesop Image component\n\n= 1.2.2\n* PHP error fix\n\n= 1.2.1\n* Some JS fixes\n\n= 1.2.0\n* Support for multi-page posts\n\n= 1.1.11\n* Fix for multiple users trying to edit the same post at the same time\n* Changed the behavior when the user deletes all text while using the editor. \n\n= 1.1.10\n* Styles fixes for mobile\n\n= 1.1.9\n* Now you can use Ctrl+SPACE to remove formatting from selected text.\n\n= 1.1.8\n* A bug fix in the component editor\n\n= 1.1.7\n* Support for WP Column and Spacer blocks.\n\n= 1.1.6\n* Fix for the map component.\n\n= 1.1.5\n* Fix for searching and auto save.\n\n= 1.1.4\n* Added a filter for the table html codes\n\n= 1.1.3\n* Fix for the \"Click\" UI setting\n* Fix for custom fields\n\n= 1.1.2\n* Fix for multi-sites\n\n= 1.1.1\n* Added Icons for OL and UL for the toolbar\n* German translation update\n\n= 1.1.0\n* NEW: OL and UL buttons to create lists.\n\n= 1.0.9.2\n* Fix for post locking\n* Further AJAX changes\n\n= 1.0.8\n* Added the delete post button to mobile\n\n= 1.0.7\n* Fix for meta information saving\n\n= 1.0.6\n* Fix for Status saving and component insertion\n\n= 1.0.5\n* Fix for Aesop Gallery component\n\n\n= 1.0.4\n* Fix for draft posts when preview setting is required\n\n= 1.0.3 =\n* Added the delete post button\n* Option to disable \"Pending\" status\n* More changes for custom fields\n\n= 1.0.2 =\n* Changes for custom fields\n\n= 1.0.1 =\n* A new option setting to make links editable under the Edit mode\n* Fixed a bug with multiple custom field entries\n\n= 1.0.0 =\n* Added new UI color customization options\n* The Post Settings button is now available under the edit mode\n* Fixed a bug with automatically entering the edit mode\n* Copy and paste from MS Word strips the formatting\n* Fixed a bug with the new post dialog\n\n= 0.10.2.2 =\n* Fixed a bug for non-English installation\n\n= 0.10.2.1 =\n* A \"Contributor\" can now create posts, just not publish\n\n= 0.10.2.0 =\n* Posts can be now set to \"Pending\"\n\n= 0.10.1.1 =\n* Some style fixes and internal changes\n\n= 0.10.1.0 =\n* Fixed some issues with BR tags\n\n= 0.10.0.3 =\n* UI and language file adjustment\n\n= 0.10.0.0 =\n* NEW UI option to automatically add a Component button to an empty paragraph\n* Now Insert HTML box can accept a URL to embed, such as Youtube, Twitter etc.\n\n= 0.9.18.4 =\n* NEW UI option to switch from Drag-Drop to simple click for inserting components\n* Fix for shortcode features on the insert HTML button\n\n= 0.9.18.1 =\n* A bug fix for Quote when ASE is not installed\n* Some mobile fixes\n\n= 0.9.18.0 =\n* Post setting dialog fix for mobile\n\n= 0.9.17.9 =\n* An error fix for tags/categories\n\n= 0.9.17.8 =\n* Improved the Aesop Component properties handling\n* Fixed some compatibility issues with certain themes.\n\n= 0.9.17.6 =\n* Fixed a style bug with the category editing.\n\n= 0.9.17.5 =\n* Fixed a bug with the Set Date codes.\n* Changed the way PASTE works when the source is an HTML code.\n\n= 0.9.17.4 =\n* Fixed a bug that happens when the \"Post\" type is not selected under the \"Enable for\" options\n* Added an option allow users to create new categories for posts.\n\n= 0.9.17.3 =\n* Changed the code to obtain the REST API root \n\n= 0.9.17.2 =\n* A JS bug fix.\n\n= 0.9.17.1 =\n* Added support for subtitle editing, for Aesop themes and the Subtitle (https://wordpress.org/plugins/subtitles/) plugin.\n* Added an option to enable changing post dates using the Post Setting dialog\n* Changed the AJAX code to hide the tour dialog\n\n= 0.9.16.8 =\n* Added Twitter handling codes\n* Tour dialog uses REST API to save settings\n* More social share plugins supported.\n\n= 0.9.16.4 =\n* Added lasso_wrap_shortcode_exceptions filter\n* Fixed a bug where you could delete readonly elements by selecting and hitting \n  a key other than BS and DEL.\n\n= 0.9.16.3 =\n* Adjusted the content filter so it can filter shortcode content\n\n= 0.9.16.2 =\n* Added lasso_required_plugins filter\n\n= 0.9.16.1 =\n* A bug fix for multisite installation.\n* A bug fix for page list.\n* Added a way to add a filter to the save operation.\n\n= 0.9.16.0 =\n* Option to work with custom fields from frontend: (https://edituswp.com/editing-and-updating-custom-fields-from-frontend/)\n* Improvement to the Undo behavior.\n* A bug fix for shortcode handling\n* Aesop event support\n\n= 0.9.15.3 =\n* More fix for custom post types\n* New option to set the tag for the \"Italic\" style\n\n= 0.9.15.2 =\n* Fix for post delete\n* Settings page update. New option to set the tag for the \"Bold\" style\n* Added style to hide controls from printing\n\n= 0.9.15.1 =\n* Insert HTML button can now process 3rd party shortcodes \n\n= 0.9.15.0 =\n* The Post List dialog now displays draft posts\n* The Post List dialog now displays custom post types properly.\n\n= 0.9.14.2 =\n* Editus tag classes now removed when saving\n* Fixed support email\n\n= 0.9.14.1 =\n* Fixed a bug involving an empty post\n* Fixed the icon file missing.\n\n\n= 0.9.14.0 =\n* Inserting H2 and H3 now also inserts p tags \n* Fixed the tour dialog getting stuck at loading \n* Fixed an issue where a component somtimes goes invisible after editing\n* All contenteditable attributes removed before being saved\n\n\n= 0.9.13.9 =\n* Fixed a bug where shortcodes were not properly restored while saving using REST API\n* Links are now always clickable.\n\n\n= 0.9.13.7 =\n* Aesop Video Component is now updated using AJAX\n* Fix for the publish button \n\n\n= 0.9.13.6 =\n* Fixed an issue with saving post titles\n* Aesop Content Component is now updated using AJAX\n* UI fixes for small mobile devices\n\n= 0.9.13.5 =\n* Now Editus uses REST API to save posts when it can.\n* REST API saving can also be disabled from the options.\n* Addressed the issue where cursor jumps when pasting texts.\n* Filters \\' in components when edited. Filters it back to single apostrophe\n\n\n= 0.9.13.3 =\n* Fixed an issue with REST API codes causing an error during the loading of javascripts.\n* Fixes for dialog text colors on certain themes.\n* Dialog behaviors improved for mobile platforms.\n\n= 0.9.13.2 =\n* Fixed some styling issues for mobile.\n* Fixed an issue in third party shortcode handling.\n\n= 0.9.13.1 =\n* Save removes html comments\n\n= 0.9.13.0 =\n* Added REST API v2 support\n* Added codes to check if someone else is editing the post/page.\n* Fixed a bug automatically entering Edit Mode when it shouldn't.\n\n= 0.9.12.2 =\n* Fixed some issues with \"Read Only\" item options\n* Added an option to show the \"Ignored Items\" and keep them read only\n\n= 0.9.12.0 =\n* Aesop Hero Gallery has been added\n* Fixed several issues with Gallery AJAX update\n* When a new post is created Editus automatically enters Edit Mode\n\n= 0.9.11.1 =\n* Added an option to open a link a new browser tab.\n\n= 0.9.11.0 =\n* Now Gallery components update without having to reload the page, using AJAX. \n* Also fixed a bug in gallery image update.\n\n= 0.9.10.5 =\n* Major new features in Beta:\n* Added Color Text Button Options.\n* Added Text Alignment Button Options.\n\n= 0.9.10.2 =\n* Added a new option to set non-editable elements that are parts of the post.\n* Live update improvement for Video Component.\n\n= 0.9.10.1 =\n* Restored mobile support, for both phones and tablets\n* A few more style fixes\n\n= 0.9.10.0 =\n* Fixed a FireFox bug where links could not be inserted\n* Fixed a bug involving texts without any tags, resulting in the first lines disappearing\n* Further style fixes\n* New components shows setting dialogs when inserted for more intuitive user interface\n* Added Auto Save option\n* Disabled for mobile devices for now.\n* Added Aesop Gallery Pop support\n\n= 0.9.9.10 =\n* Fixed the error reporting for AJAX calls\n* Fixed the short code wrapping for non core Aesop components\n* Fixed a bug with creating gallery\n\n= 0.9.9.9 =\n* replaced the deprecated JQuery calls to live()\n\n= 0.9.9.8 =\n* fixed a bug in the shortcode saving codes\n* some form style and color adjustments\n\n= 0.9.9.7 =\n* added the following filter:\n   lasso_user_can_filter\n* fixed a bug in adding a custom type post \n\n= 0.9.9.6 =\n* added the following hooks:\n   lasso_title_class\n   lasso_content_class\n   lasso_featured_image_class\n   lasso_dont_save\n* Tour dialog loading code has been changed.\n\n= 0.9.9.5 =\n* multi-site menu restored\n* added an option to specify gallery name while creating a new gallery.\n\n= 0.9.9.3 =\n* fixed unsaved data check\n* swapping gallery updates the images in the gallery sidebar\n* added button to create gallery to the gallery sidebar.\n\n= 0.9.9.1 =\n* fixed some styling issues where edit boxes and some buttons were not readable under certain themes\n* fixed the issue where featured images were not updated in the post settings dialog box\n* Editus now auto-detects article class if it's .entry-content\n* Editus now auto-detects title class if it's .entry-header\n* most short codes are now preserved (props Rouven Hurling)\n* multi-site menu has been changed (props Philipp Stracker)\n* post type issue with non-english sites fixed (props Philipp Stracker)\n\n= 0.9.8.2 =\n* fixed references to lasso.is\n\n= 0.9.8.1 = Oct 8 2015 =\n\n* fixed a capability issue that was allowing contributors to edit other users posts\n\n= 0.9.8 = Aug 14 2015\n\n* renamed Lasso to Editus\n\n= 0.9.7 = July 30 2015\n\n* updated TGM Plugin Activation to latest (props Ahmad Awais)\n\n* improved live editing video source switching in Video Component\n\n* added dismissible license notices if license is not supplied, expired, or invalid\n\n* fixed a capability issue with saving that was introduced with WordPress 4.2.3 (props Josh Polluck)\n\n= 0.9.6 = June 30 2015\n\n* added the ability to access and restore post and page revisions\n\n* fixed a bug introduced on the last update with new posts/pages being duplicated when created\n\n* fixed authors not being able to publish posts\n\n* fixed a bug with Lasso Meta API not saving\n\n= 0.9.5 = June 17 2015\n\n* added ability to search posts and pages within the all posts modal\n\n* added abilty to choose post type to create within new post creation modal\n\n* component now slides into view on settings click\n\n* fixed bug with video component not switching providers\n\n* fixed bug with galleries not saving gallery images properly\n\n* improved Meta API for developers wishing to integrate within Lassos post settings\n\n* mobile style improvement - props @peiche\n\n= 0.9.4.1 = May 28th 2015\n\n* fixed bug with automatic updates - props @pippinsplugins\n\n* fixed bug with admins not seeing all posts in addition to their own\n\n= 0.9.4 = May 26 2015\n\n* WARNING - PHP 5.4 or higher required!!\n\n* added ability to access and delete posts and pages (and custom post types with a filter) from the front-end (requires the WP REST API plugin). If the user is an Author or Contributor they will only be shown their posts or pages.\n\n* added ability to add a post from anywhere on the site\n\n* added ability to set featured image within settings modal if current theme supports post thumbnails\n\n* added ability to add categories and tags within settings modal\n\n* added CMD + S hot key to save post while in editor\n\n* added a close button to exit the editor\n\n* added a new API to allow third-party addons to add new settings modals (beta). They appear as a tab and work with only a filter. This is in preparation for releasing ACF, CMB2, and Ninja Forms integration addons.\n\n* added Canvas and Exposure themes to automatic theme support\n\n* fixed bug with tour hide not calculating correctly\n\n* fixed bug with Author or Contributor roles not being able to put a post in draft\n\n* fixed options not being cleaned up on uninstall\n\n* improved automatic theme support means supported themes work out of the box with no setup\n\n* improved user interface colors to better match WordPress design patterns\n\n* improved drag and drop detection between paragraphs\n\n* improved toolbar width logic - props @peiche\n\n* improved CSS selector performance\n\n* replaced tour GIFs with images\n\n= 0.9.3 = April 26th 2015\n\n* fixed .entry-content being applied as a default Article CSS Class\n\n* allow escaping the warning modal that warns users if no Article CSS class is present\n\n* fixed image control setting with images inserted without Aesop Story Engine active\n\n* fixed featured image not being saved\n\n= 0.9.2 = April 14th 2015\n\n* fixed links not working if editor was active but not in use\n\n* massive internal rewrite to use a custom API for processing requests instead of hitting admin-ajax. This increases the saving speed and ensures compatibility for very large WordPress installations and Enterprise users. Tested and working on WordPress MU, Apache, Nginx , and HHVM.\n\n= 0.9.1.1 = March 28th 2015\n\n* fixed a js error that happened if an uploaded media item wasn't large enough to be resized to large\n\n= 0.9.1 = March 27th 2015\n\n* added ability to insert standard WordPress images and blockquote. If Aesop Story Engine is activated, it replaces these with Aesop Story Engine's story components.\n\n* fixed css class names in toolbar components not being namespaced\n\n* better iOS compatibility with editing toolbar\n\n* removed H2 and H3 buttons from the insert HTML area if Extended Toolbar is selected as its redundant(Extended Toolbar puts H2, and H3 buttons into the toolbar)\n\n* clarified in the instructions that the article class name in the settings should include the preceding dot\n\n* if an embedded Tweet is in the content, we now remove it when you enter the editor so it's not save as HTML. In a future update, we plan to actually have some type of live ombed parsing system. This is a good fix for the time being.\n\n* prepended a ul class to ul.editor-controls and ul.editor-component-controls as well as set letter-spacing to 0 in hopes of clearing up theme CSS conflicting with Lasso CSS. Normally this is bad practice (ul.this), but it's better than applying !important.\n\n= 0.9 = March 21st 2015\n\n* fixed a capability issue where contributors were allowed to publish posts\n\n* class visibility methods\n\n= 0.8.8 = March 19th 2015\n\n* added an alert that pops up if the user tries to use the editor but hasn't added the required Article Class in order to use Lasso\n\n* added all Aesop built themes to automatically supported themes list\n\n* updated pot file\n\n= 0.8.7 = March 16th 2015\n\n* added a new option that lets you list CSS classes of items to ignore on save. This makes Lasso compatible wity 99.99% of all WordPress themes\n\n= 0.8.6 = March 12th 2015\n\n* new pre-flight function to check to ensure plugin settings are configured\n\n* added automatic theme support for WordPress core themes and UpThemes\n\n* added a new define define('LASSO_AGENCY_MODE') which removes the license page and links out to Lasso website\n\n* added a new tab for Lasso to hold the status page, license page, and settings\n\n* added new license menu page in preperation of the public launch of this plugin\n\n* fixed an issue with the height in the Tour slider sometimes not calculating correctly\n\n* fixed a permission issue where a user was allowed to edit another users posts. we were using edit_posts and switched to edit_post\n\n= 0.8.5 = March 8th 2015\n\n* misc bug fixes\n\n* removed the \"url helper\" field for creating new posts as it was confusing some users\n\n* added helper text to the field for creating new posts as a better visual guide\n\n* new activation welcome screen in WordPress\n\n* fixed the content component from not correctly saving\n\n* added two actions: lasso_editor_controls_before &#038;&#038; lasso_editor_controls_after\n\n* added two css classes that get applied to the body when a featured thumbnail is added or removed : lasso-post-thumb-added &#038;&#038; lasso-post-thumb-removed"
  },
  {
    "path": "admin/assets/css/lasso-editor-settings.css",
    "content": ".lasso--animate__spin{-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.not-visible{opacity:0;filter:alpha(opacity=0);display:none;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease}.lasso--welcome{max-width:600px;margin:20px auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso--welcome *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso--welcome p{font-size:15px}.lasso--welcome .lasso--welcome__steps{padding:0;list-style-type:none;margin:0 auto}.lasso--welcome .lasso--welcome__steps li{padding:25px;background:#fff;border:1px solid #d9d9d9;border-radius:5px;text-align:center;position:relative;margin-top:-25px;margin-bottom:100px}.lasso--welcome .lasso--welcome__steps li:before{font-family:Dashicons;color:#fff;padding:14px 27px 15px 14px;width:22px;font-size:36px;border-radius:100%;text-align:center;position:absolute;top:-33px;left:0;right:0;margin:0 auto;height:34px;line-height:37px}.lasso--welcome .lasso--welcome__steps li.info:before{content:'\\f348';background:#2bc2ff}.lasso--welcome .lasso--welcome__steps li.success:before{content:'\\f147';background:#4da34d}.lasso--welcome .lasso--welcome__steps li.error:before{content:'\\f227';background:#d9534f}.lasso--welcome .lasso--welcome__steps li p{margin-bottom:0}.lasso--welcome .lasso--welcome__steps li h3{margin-bottom:5px}.lasso--welcome .lasso--welcome__top{text-align:center;margin-bottom:100px}.lasso--welcome .lasso--welcome__top:before,.lasso--welcome .lasso--welcome__top:after{content:\" \";display:table}.lasso--welcome .lasso--welcome__top:after{clear:both}.lasso--welcome .lasso--welcome__top img{max-width:150px;margin:0 auto;border-radius:3px}.lasso--welcome .lasso--welcome__top h1+p{font-style:italic}.lasso--welcome .lasso--welcome__social{list-style:none;margin:0;padding:7px 0;border-top:1px solid #d9d9d9;border-bottom:1px solid #d9d9d9}.lasso--welcome .lasso--welcome__social:before,.lasso--welcome .lasso--welcome__social:after{content:\" \";display:table}.lasso--welcome .lasso--welcome__social:after{clear:both}.lasso--welcome .lasso--welcome__social li{display:inline-block;line-height:1;margin:0}.lasso--welcome .lasso--welcome__social a{padding:2px 6px;display:block;text-decoration:none;color:inherit;line-height:1.5;font-weight:700}.lasso--welcome .lasso--welcome__social a:hover{color:#007aab;text-decoration:none}.lasso--welcome .lasso--welcome__social a i{font-size:16px;top:2px;line-height:19px;color:#007aab}.lasso--form-settings{max-width:500px;padding:20px;background:#fff;border-radius:5px;border:1px solid #cdcdcd;position:relative}.lasso--form-settings *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso--form-settings:before,.lasso--form-settings:after{content:\" \";display:table}.lasso--form-settings:after{clear:both}.lasso--form-settings .iris-picker{box-sizing:initial}.lasso--form-settings .iris-picker *{box-sizing:inherit}.lasso--form-settings .lasso-editor-settings--option-wrap{margin-bottom:25px;margin-left:15px}.lasso--form-settings .lasso-editor-settings--option-wrap.last .lasso-editor-settings--option-inner{border-bottom:0;padding-bottom:0}.lasso--form-settings .lasso-editor-settings--option-inner{border-bottom:1px solid #e7e7e7;padding-bottom:25px}.lasso--form-settings label{font-weight:700;font-size:110%;display:block}.lasso--form-settings textarea,.lasso--form-settings input[type=text]{border-radius:3px;width:240px;background-color:#f8f8f8;color:#000;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.1);box-shadow:inset 1px 1px 1px rgba(0,0,0,.1)}.lasso--form-settings input[type=checkbox]{float:left}.lasso--form-settings input[type=checkbox]~label{float:left;position:relative;top:-4px;left:4px}.lasso--form-settings input[type=submit]:active{outline:0}.lasso--form-settings input[type=submit]:disabled{opacity:.4;filter:alpha(opacity=40)}.lasso--form-settings .lasso--setting-description{display:block;margin:5px 0 10px;max-width:400px;color:#888;line-height:1.3;clear:left}.lasso--form-settings .lasso-editor-settings--submit{position:fixed;top:88px;left:760px}.lasso--form-settings .lasso-editor-settings--confirm{background:#fff;border:1px solid #cdcdcd;border-radius:3px;padding:10px 20px 14px 12px;margin-top:10px;-webkit-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear}.lasso--form-settings .lasso-editor-settings--confirm.success:before,.lasso--form-settings .lasso-editor-settings--confirm.error:before{font-family:Dashicons;speak:none;font-size:18px;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:relative;top:4px;right:3px}.lasso--form-settings .lasso-editor-settings--confirm.success:before{content:'\\f147';color:#5CB85C}.lasso--form-settings .lasso-editor-settings--confirm.error:before{content:'\\f158';color:#d9534f}#wpbody #lasso-editor-settings-form .button-primary.saved{background:#5CB85C!important}"
  },
  {
    "path": "admin/assets/js/lasso-editor-settings.js",
    "content": "jQuery(document).ready(function($){\n\n\t// entry handler\n  \t$('#lasso-editor-settings-form').submit(function(e) {\n\n  \t\tvar $this = $(this);\n\n  \t\te.preventDefault();\n\n\t\t$this.find(':submit').attr( 'disabled','disabled' );\n\n  \t\tvar data = $this.serialize();\n\n\t  \t$.post( ajaxurl, data, function(response) {\n\n\t  \t\tif ( response.success ) {\n\n\t  \t\t\t$this.find(':submit').addClass('saved');\n\t  \t\t\t$this.find('.lasso-editor-settings--submit').append('<div class=\"lasso-editor-settings--confirm success\">Settings Saved!</div>');\n\n\t  \t\t\tsetTimeout( function(){\n\t  \t\t\t\t$this.find(':submit').removeClass('saved');\n\t  \t\t\t\t$this.find('.lasso-editor-settings--confirm').remove();\n\t  \t\t\t\t$this.find(':submit').attr( 'disabled',false );\n\t  \t\t\t}, 2000 );\n\n\t  \t\t} else {\n\n\t  \t\t\t$this.find('.lasso-editor-settings--submit').append('<div class=\"lasso-editor-settings--confirm error\">Something went wrong! :(</div>');\n\n\t  \t\t}\n\t    }).fail(function(xhr, err) { \n\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t$this.find('.lasso-editor-settings--submit').append('<div class=\"lasso-editor-settings--confirm error\">Something went wrong! :(</div>');\t\t\n\t\t});\n\n    });\n\t\t\n\t$('.color-picker').wpColorPicker();\n\t// initialize color pickers with default values\n\t$('#lasso-editor-settings--default-colors').click(function() {\n\t\t$($(\".color-picker\")[0]).wpColorPicker('color', \"#0000ff\");\n\t\t$($(\".color-picker\")[1]).wpColorPicker('color', \"#000030\");\n\t\t$($(\".color-picker\")[2]).wpColorPicker('color', \"#000055\");\n\t\t$($(\".color-picker\")[3]).wpColorPicker('color', \"#ffffff\");\n\t});\n\t\n\t$('#lasso_editor_use_old_ui').change(function() {\n\t\tif(this.checked) {\n            $('#lasso-editor-settings--colors').slideUp();\n        } else {\n\t\t\t$('#lasso-editor-settings--colors').slideDown();   \n\t\t}\n        \n    });\n\n\n});"
  },
  {
    "path": "admin/assets/less/style.less",
    "content": "@import '../../../public/assets/less/source/mixins.less';\n@import 'welcome.less';\n\n@main:    #fff;\n@border:    #cdcdcd;\n@desc-color:  #888;\n@main-width:  500px;\n@admin-bar-width: 160px;\n.lasso--form-settings{\n\n    * { .box-sizing(border-box); }\n    max-width:@main-width;\n    padding:20px;\n    background:@main;\n    border-radius:5px;\n    border:1px solid @border;\n    position: relative;\n    .clearfix();\n\n    .iris-picker {\n        box-sizing: initial;\n\n        * {\n            box-sizing: inherit;\n        }\n    }\n\n    .lasso-editor-settings--option-wrap {\n        margin-bottom:25px;\n\t\tmargin-left:15px;\n\n        &.last .lasso-editor-settings--option-inner{\n            border-bottom: none;\n            padding-bottom:0;\n        }\n    }\n\n    .lasso-editor-settings--option-inner {\n        border-bottom:1px solid lighten(@border,10);\n        padding-bottom:25px;\n    }\n\n    label {\n        font-weight:bold;\n        font-size:110%;\n        display:block;\n    }\n\n    textarea,\n    input[type=\"text\"] {\n        border-radius:3px;\n        width:240px;\n\t\tbackground-color: #f8f8f8;\n\t\tcolor: #000;\n        .box-shadow(inset 1px 1px 1px rgba(0,0,0,0.1));\n    }\n\n    input[type=\"checkbox\"] {\n        float: left;\n        & ~ label {\n            float: left;\n            position: relative;\n            top:-4px;\n            left:4px;\n        }\n    }\n\n    input[type=\"submit\"]{\n        &:active {\n            outline:none;\n        }\n        &:disabled {\n            .opacity(0.4);\n        }\n    }\n\n    .lasso--setting-description {\n        display:block;\n        margin:5px 0 10px;\n        max-width:400px;\n        color:@desc-color;\n        line-height: 1.3;\n        clear:left;\n    }\n\n    // sunmit\n    .lasso-editor-settings--submit {\n        position: fixed;\n        top:88px;\n        left: @main-width + @admin-bar-width + 100;\n\n    }\n\n    .lasso-editor-settings--confirm {\n        background: @main;\n        border:1px solid @border;\n        border-radius:3px;\n        padding:10px 20px 14px 12px;\n        margin-top:10px;\n        .transition(all .2s linear);\n\n        &.success:before,\n        &.error:before {\n            font-family: 'Dashicons';\n            speak: none;\n            font-size:18px;\n            font-style: normal;\n            font-weight: normal;\n            font-variant: normal;\n            text-transform: none;\n            line-height: 1;\n            -webkit-font-smoothing: antialiased;\n            -moz-osx-font-smoothing: grayscale;\n            position: relative;\n            top:4px;\n            right:3px;\n\n        }\n\n        &.success:before { content:'\\f147'; color:#5CB85C; }\n        &.error:before { content: '\\f158'; color:#d9534f; }\n\n    }\n\n}\n#wpbody #lasso-editor-settings-form .button-primary.saved {\n    background: #5CB85C !important;\n}"
  },
  {
    "path": "admin/assets/less/welcome.less",
    "content": ".lasso--welcome {\n\n    * { .box-sizing(border-box); }\n\n    max-width:600px;\n    margin:20px auto;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n\n    @bg:        white;\n    @accent:    darken(@bg,5);\n    @border:    darken(@bg, 15);\n    @link:      #007aab;\n    @success:   #4DA34D;\n    @error:     #d9534f;\n    @info:      lighten(@link,25);\n\n    p {\n        font-size:15px;\n    }\n\n    // initial welcome steps\n    .lasso--welcome__steps {\n        padding:0;\n        list-style-type:none;\n        margin:0 auto;\n\n        li {\n            padding:25px;\n            background: @bg;\n            border:1px solid @border;\n            border-radius:5px;\n            text-align: center;\n            position: relative;\n            margin-top:-25px;\n            margin-bottom: 100px;\n\n            &:before {\n                font-family: Dashicons;\n                color:white;\n                padding: 14px 27px 15px 14px;\n                width: 22px;\n                font-size: 36px;\n                border-radius: 100%;\n                text-align: center;\n                position: absolute;\n                top: -33px;\n                left: 0;\n                right: 0;\n                margin: 0 auto;\n                height: 34px;\n                line-height: 37px;\n            }\n\n            &.info:before {\n                content: '\\f348';\n                background: @info;\n            }\n            &.success:before {\n                content: '\\f147';\n                background: @success;\n            }\n            &.error:before {\n                content: '\\f227';\n                background:@error;\n            }\n            p{\n                margin-bottom: 0;\n            }\n\n            h3 {\n                margin-bottom: 5px;\n            }\n        }\n    }\n\n    .lasso--welcome__top{\n        .clearfix();\n        text-align: center;\n\n        img {\n            max-width:150px;\n            margin:0 auto;\n            border-radius:3px;\n        }\n\n        h1 + p {\n            font-style: italic;\n        }\n\n        margin-bottom:100px;\n    }\n\n    // social\n    .lasso--welcome__social {\n        list-style: none;\n        margin:0;\n        padding:7px 0;\n        .clearfix();\n        border-top:1px solid @border;\n        border-bottom:1px solid @border;\n\n        li {\n            display: inline-block;\n            line-height: 1;\n            margin:0;\n        }\n\n        a {\n            padding:2px 6px;\n            display: block;\n            text-decoration: none;\n            color:inherit;\n            line-height: 1.5;\n            font-weight: bold;\n\n            &:hover {\n                color:@link;\n                text-decoration: none;\n            }\n\n            i {\n                font-size:16px;\n                top:2px;\n                line-height: 19px;\n                color:@link;\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "admin/includes/EDD_SL_Plugin_Updater.php",
    "content": "<?php\n\n// uncomment this line for testing\n//set_site_transient( 'update_plugins', null );\n\n/**\n * Allows plugins to use their own update API.\n *\n * @author Pippin Williamson\n * @version 1.6\n */\nclass EDD_SL_Plugin_Updater {\n\tprivate $api_url   = '';\n\tprivate $api_data  = array();\n\tprivate $name      = '';\n\tprivate $slug      = '';\n\n\t/**\n\t * Class constructor.\n\t *\n\t * @uses plugin_basename()\n\t * @uses hook()\n\t *\n\t * @param string  $_api_url     The URL pointing to the custom API endpoint.\n\t * @param string  $_plugin_file Path to the plugin file.\n\t * @param array   $_api_data    Optional data to send with API calls.\n\t * @return void\n\t */\n\tfunction __construct( $_api_url, $_plugin_file, $_api_data = null ) {\n\t\t$this->api_url  = trailingslashit( $_api_url );\n\t\t$this->api_data = $_api_data;\n\t\t$this->name     = plugin_basename( $_plugin_file );\n\t\t$this->slug     = basename( $_plugin_file, '.php' );\n\t\t$this->version  = $_api_data['version'];\n\n\t\t// Set up hooks.\n\t\t$this->init();\n\t\tadd_action( 'admin_init', array( $this, 'show_changelog' ) );\n\t}\n\n\t/**\n\t * Set up WordPress filters to hook into WP's update process.\n\t *\n\t * @uses add_filter()\n\t *\n\t * @return void\n\t */\n\tpublic function init() {\n\n\t\tadd_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );\n\t\tadd_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );\n\n\t\tadd_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );\n\t}\n\n\t/**\n\t * Check for Updates at the defined API endpoint and modify the update array.\n\t *\n\t * This function dives into the update API just when WordPress creates its update array,\n\t * then adds a custom API call and injects the custom plugin data retrieved from the API.\n\t * It is reassembled from parts of the native WordPress plugin update code.\n\t * See wp-includes/update.php line 121 for the original wp_update_plugins() function.\n\t *\n\t * @uses api_request()\n\t *\n\t * @param array   $_transient_data Update array build by WordPress.\n\t * @return array Modified update array with custom plugin data.\n\t */\n\tfunction check_update( $_transient_data ) {\n\n\t\tglobal $pagenow;\n\n\t\tif ( ! is_object( $_transient_data ) ) {\n\t\t\t$_transient_data = new stdClass;\n\t\t}\n\n\t\tif ( 'plugins.php' == $pagenow && is_multisite() ) {\n\t\t\treturn $_transient_data;\n\t\t}\n\n\t\tif ( empty( $_transient_data->response ) || empty( $_transient_data->response[ $this->name ] ) ) {\n\n\t\t\t$version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );\n\n\t\t\tif ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {\n\n\t\t\t\t$this->did_check = true;\n\n\t\t\t\tif ( version_compare( $this->version, $version_info->new_version, '<' ) ) {\n\n\t\t\t\t\t$_transient_data->response[ $this->name ] = $version_info;\n\n\t\t\t\t}\n\n\t\t\t\t$_transient_data->last_checked = time();\n\t\t\t\t$_transient_data->checked[ $this->name ] = $this->version;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn $_transient_data;\n\t}\n\n\t/**\n\t * show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!\n\t *\n\t * @param string  $file\n\t * @param array   $plugin\n\t */\n\tpublic function show_update_notification( $file, $plugin ) {\n\n\t\tif ( ! current_user_can( 'update_plugins' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( ! is_multisite() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( $this->name != $file ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove our filter on the site transient\n\t\tremove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );\n\n\t\t$update_cache = get_site_transient( 'update_plugins' );\n\n\t\tif ( ! is_object( $update_cache ) || empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {\n\n\t\t\t$cache_key    = md5( 'edd_plugin_' .sanitize_key( $this->name ) . '_version_info' );\n\t\t\t$version_info = get_transient( $cache_key );\n\n\t\t\tif ( false === $version_info ) {\n\n\t\t\t\t$version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );\n\n\t\t\t\tset_transient( $cache_key, $version_info, 3600 );\n\t\t\t}\n\n\n\t\t\tif ( ! is_object( $version_info ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( version_compare( $this->version, $version_info->new_version, '<' ) ) {\n\n\t\t\t\t$update_cache->response[ $this->name ] = $version_info;\n\n\t\t\t}\n\n\t\t\t$update_cache->last_checked = time();\n\t\t\t$update_cache->checked[ $this->name ] = $this->version;\n\n\t\t\tset_site_transient( 'update_plugins', $update_cache );\n\n\t\t} else {\n\n\t\t\t$version_info = $update_cache->response[ $this->name ];\n\n\t\t}\n\n\t\t// Restore our filter\n\t\tadd_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );\n\n\t\tif ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {\n\n\t\t\t// build a plugin list row, with update notification\n\t\t\t$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );\n\t\t\techo '<tr class=\"plugin-update-tr\"><td colspan=\"' . $wp_list_table->get_column_count() . '\" class=\"plugin-update colspanchange\"><div class=\"update-message\">';\n\n\t\t\t$changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );\n\n\t\t\tif ( empty( $version_info->download_link ) ) {\n\t\t\t\tprintf(\n\t\t\t\t\t__( 'There is a new version of %1$s available. <a target=\"_blank\" class=\"thickbox\" href=\"%2$s\">View version %3$s details</a>.', 'lasso' ),\n\t\t\t\t\tesc_html( $version_info->name ),\n\t\t\t\t\tesc_url( $changelog_link ),\n\t\t\t\t\tesc_html( $version_info->new_version )\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tprintf(\n\t\t\t\t\t__( 'There is a new version of %1$s available. <a target=\"_blank\" class=\"thickbox\" href=\"%2$s\">View version %3$s details</a> or <a href=\"%4$s\">update now</a>.', 'lasso' ),\n\t\t\t\t\tesc_html( $version_info->name ),\n\t\t\t\t\tesc_url( $changelog_link ),\n\t\t\t\t\tesc_html( $version_info->new_version ),\n\t\t\t\t\tesc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) )\n\t\t\t\t);\n\t\t\t}\n\n\t\t\techo '</div></td></tr>';\n\t\t}\n\t}\n\n\n\t/**\n\t * Updates information on the \"View version x.x details\" page with custom data.\n\t *\n\t * @uses api_request()\n\t *\n\t * @param mixed   $_data\n\t * @param string  $_action\n\t * @param object  $_args\n\t * @return object $_data\n\t */\n\tfunction plugins_api_filter( $_data, $_action = '', $_args = null ) {\n\n\n\t\tif ( $_action != 'plugin_information' ) {\n\n\t\t\treturn $_data;\n\n\t\t}\n\n\t\tif ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) {\n\n\t\t\treturn $_data;\n\n\t\t}\n\n\t\t$to_send = array(\n\t\t\t'slug'   => $this->slug,\n\t\t\t'is_ssl' => is_ssl(),\n\t\t\t'fields' => array(\n\t\t\t\t'banners' => false, // These will be supported soon hopefully\n\t\t\t\t'reviews' => false\n\t\t\t)\n\t\t);\n\n\t\t$api_response = $this->api_request( 'plugin_information', $to_send );\n\n\t\tif ( false !== $api_response ) {\n\t\t\t$_data = $api_response;\n\t\t}\n\n\t\treturn $_data;\n\t}\n\n\n\t/**\n\t * Disable SSL verification in order to prevent download update failures\n\t *\n\t * @param array   $args\n\t * @param string  $url\n\t * @return object $array\n\t */\n\tfunction http_request_args( $args, $url ) {\n\t\t// If it is an https request and we are performing a package download, disable ssl verification\n\t\tif ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {\n\t\t\t$args['sslverify'] = false;\n\t\t}\n\t\treturn $args;\n\t}\n\n\t/**\n\t * Calls the API and, if successfull, returns the object delivered by the API.\n\t *\n\t * @uses get_bloginfo()\n\t * @uses wp_remote_post()\n\t * @uses is_wp_error()\n\t *\n\t * @param string  $_action The requested action.\n\t * @param array   $_data   Parameters for the API action.\n\t * @return false||object\n\t */\n\tprivate function api_request( $_action, $_data ) {\n\n\t\tglobal $wp_version;\n\n\t\t$data = array_merge( $this->api_data, $_data );\n\n\t\tif ( $data['slug'] != $this->slug )\n\t\t\treturn;\n\n\t\tif ( empty( $data['license'] ) )\n\t\t\treturn;\n\n\t\tif ( $this->api_url == home_url() ) {\n\t\t\treturn false; // Don't allow a plugin to ping itself\n\t\t}\n\n\t\t$api_params = array(\n\t\t\t'edd_action' => 'get_version',\n\t\t\t'license'    => $data['license'],\n\t\t\t'item_name'  => isset( $data['item_name'] ) ? $data['item_name'] : false,\n\t\t\t'item_id'    => isset( $data['item_id'] ) ? $data['item_id'] : false,\n\t\t\t'slug'       => $data['slug'],\n\t\t\t'author'     => $data['author'],\n\t\t\t'url'        => home_url()\n\t\t);\n\n\t\t$request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );\n\n\t\tif ( ! is_wp_error( $request ) ) {\n\t\t\t$request = json_decode( wp_remote_retrieve_body( $request ) );\n\t\t}\n\n\t\tif ( $request && isset( $request->sections ) ) {\n\t\t\t$request->sections = maybe_unserialize( $request->sections );\n\t\t} else {\n\t\t\t$request = false;\n\t\t}\n\n\t\treturn $request;\n\t}\n\n\tpublic function show_changelog() {\n\n\n\t\tif ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( empty( $_REQUEST['plugin'] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( empty( $_REQUEST['slug'] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( ! current_user_can( 'update_plugins' ) ) {\n\t\t\twp_die( __( 'You do not have permission to install plugin updates', 'lasso' ), __( 'Error', 'lasso' ), array( 'response' => 403 ) );\n\t\t}\n\n\t\t$response = $this->api_request( 'plugin_latest_version', array( 'slug' => $_REQUEST['slug'] ) );\n\n\t\tif ( $response && isset( $response->sections['changelog'] ) ) {\n\t\t\techo '<div style=\"background:#fff;padding:10px;\">' . $response->sections['changelog'] . '</div>';\n\t\t}\n\n\n\t\texit;\n\t}\n\n}\n"
  },
  {
    "path": "admin/includes/class-tgm-plugin-activation.php",
    "content": "<?php\n/**\n * Plugin installation and activation for WordPress themes.\n *\n * Please note that this is a drop-in library for a theme or plugin.\n * The authors of this library (Thomas, Gary and Juliette) are NOT responsible\n * for the support of your plugin or theme. Please contact the plugin\n * or theme author for support.\n *\n * @package   TGM-Plugin-Activation\n * @version   2.5.2\n * @link      http://tgmpluginactivation.com/\n * @author    Thomas Griffin, Gary Jones, Juliette Reinders Folmer\n * @copyright Copyright (c) 2011, Thomas Griffin\n * @license   GPL-2.0+\n *\n * @wordpress-plugin\n * Plugin Name: TGM Plugin Activation\n * Plugin URI:\n * Description: Plugin installation and activation for WordPress themes.\n * Version:     2.5.2\n * Author:      Thomas Griffin, Gary Jones, Juliette Reinders Folmer\n * Author URI:  http://tgmpluginactivation.com/\n * Text Domain: tgmpa\n * Domain Path: /languages/\n * Copyright:   2011, Thomas Griffin\n */\n\n/*\n\tCopyright 2011 Thomas Griffin (thomasgriffinmedia.com)\n\n\tThis program is free software; you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License, version 2, as\n\tpublished by the Free Software Foundation.\n\n\tThis program is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with this program; if not, write to the Free Software\n\tFoundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n*/\n\nif ( ! class_exists( 'TGM_Plugin_Activation' ) ) {\n\n\t/**\n\t * Automatic plugin installation and activation library.\n\t *\n\t * Creates a way to automatically install and activate plugins from within themes.\n\t * The plugins can be either bundled, downloaded from the WordPress\n\t * Plugin Repository or downloaded from another external source.\n\t *\n\t * @since 1.0.0\n\t *\n\t * @package TGM-Plugin-Activation\n\t * @author  Thomas Griffin\n\t * @author  Gary Jones\n\t */\n\tclass TGM_Plugin_Activation {\n\t\t/**\n\t\t * TGMPA version number.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @const string Version number.\n\t\t */\n\t\tconst TGMPA_VERSION = '2.5.2';\n\n\t\t/**\n\t\t * Regular expression to test if a URL is a WP plugin repo URL.\n\t\t *\n\t\t * @const string Regex.\n\t\t *\n\t\t * @since 2.5.0\n\t\t */\n\t\tconst WP_REPO_REGEX = '|^http[s]?://wordpress\\.org/(?:extend/)?plugins/|';\n\n\t\t/**\n\t\t * Arbitrary regular expression to test if a string starts with a URL.\n\t\t *\n\t\t * @const string Regex.\n\t\t *\n\t\t * @since 2.5.0\n\t\t */\n\t\tconst IS_URL_REGEX = '|^http[s]?://|';\n\n\t\t/**\n\t\t * Holds a copy of itself, so it can be referenced by the class name.\n\t\t *\n\t\t * @since 1.0.0\n\t\t *\n\t\t * @var TGM_Plugin_Activation\n\t\t */\n\t\tpublic static $instance;\n\n\t\t/**\n\t\t * Holds arrays of plugin details.\n\t\t *\n\t\t * @since 1.0.0\n\t\t *\n\t\t * @since 2.5.0 the array has the plugin slug as an associative key.\n\t\t *\n\t\t * @var array\n\t\t */\n\t\tpublic $plugins = array();\n\n\t\t/**\n\t\t * Holds arrays of plugin names to use to sort the plugins array.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @var array\n\t\t */\n\t\tprotected $sort_order = array();\n\n\t\t/**\n\t\t * Whether any plugins have the 'force_activation' setting set to true.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @var bool\n\t\t */\n\t\tprotected $has_forced_activation = false;\n\n\t\t/**\n\t\t * Whether any plugins have the 'force_deactivation' setting set to true.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @var bool\n\t\t */\n\t\tprotected $has_forced_deactivation = false;\n\n\t\t/**\n\t\t * Name of the unique ID to hash notices.\n\t\t *\n\t\t * @since 2.4.0\n\t\t *\n\t\t * @var string\n\t\t */\n\t\tpublic $id = 'tgmpa';\n\n\t\t/**\n\t\t * Name of the query-string argument for the admin page.\n\t\t *\n\t\t * @since 1.0.0\n\t\t *\n\t\t * @var string\n\t\t */\n\t\tprotected $menu = 'tgmpa-install-plugins';\n\n\t\t/**\n\t\t * Parent menu file slug.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @var string\n\t\t */\n\t\tpublic $parent_slug = 'themes.php';\n\n\t\t/**\n\t\t * Capability needed to view the plugin installation menu item.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @var string\n\t\t */\n\t\tpublic $capability = 'edit_theme_options';\n\n\t\t/**\n\t\t * Default absolute path to folder containing bundled plugin zip files.\n\t\t *\n\t\t * @since 2.0.0\n\t\t *\n\t\t * @var string Absolute path prefix to zip file location for bundled plugins. Default is empty string.\n\t\t */\n\t\tpublic $default_path = '';\n\n\t\t/**\n\t\t * Flag to show admin notices or not.\n\t\t *\n\t\t * @since 2.1.0\n\t\t *\n\t\t * @var boolean\n\t\t */\n\t\tpublic $has_notices = true;\n\n\t\t/**\n\t\t * Flag to determine if the user can dismiss the notice nag.\n\t\t *\n\t\t * @since 2.4.0\n\t\t *\n\t\t * @var boolean\n\t\t */\n\t\tpublic $dismissable = true;\n\n\t\t/**\n\t\t * Message to be output above nag notice if dismissable is false.\n\t\t *\n\t\t * @since 2.4.0\n\t\t *\n\t\t * @var string\n\t\t */\n\t\tpublic $dismiss_msg = '';\n\n\t\t/**\n\t\t * Flag to set automatic activation of plugins. Off by default.\n\t\t *\n\t\t * @since 2.2.0\n\t\t *\n\t\t * @var boolean\n\t\t */\n\t\tpublic $is_automatic = false;\n\n\t\t/**\n\t\t * Optional message to display before the plugins table.\n\t\t *\n\t\t * @since 2.2.0\n\t\t *\n\t\t * @var string Message filtered by wp_kses_post(). Default is empty string.\n\t\t */\n\t\tpublic $message = '';\n\n\t\t/**\n\t\t * Holds configurable array of strings.\n\t\t *\n\t\t * Default values are added in the constructor.\n\t\t *\n\t\t * @since 2.0.0\n\t\t *\n\t\t * @var array\n\t\t */\n\t\tpublic $strings = array();\n\n\t\t/**\n\t\t * Holds the version of WordPress.\n\t\t *\n\t\t * @since 2.4.0\n\t\t *\n\t\t * @var int\n\t\t */\n\t\tpublic $wp_version;\n\n\t\t/**\n\t\t * Holds the hook name for the admin page.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @var string\n\t\t */\n\t\tpublic $page_hook;\n\n\t\t/**\n\t\t * Adds a reference of this object to $instance, populates default strings,\n\t\t * does the tgmpa_init action hook, and hooks in the interactions to init.\n\t\t *\n\t\t * @internal This method should be `protected`, but as too many TGMPA implementations\n\t\t * haven't upgraded beyond v2.3.6 yet, this gives backward compatibility issues.\n\t\t * Reverted back to public for the time being.\n\t\t *\n\t\t * @since 1.0.0\n\t\t *\n\t\t * @see TGM_Plugin_Activation::init()\n\t\t */\n\t\tpublic function __construct() {\n\t\t\t// Set the current WordPress version.\n\t\t\t$this->wp_version = $GLOBALS['wp_version'];\n\n\t\t\t// Announce that the class is ready, and pass the object (for advanced use).\n\t\t\tdo_action_ref_array( 'tgmpa_init', array( $this ) );\n\n\t\t\t// When the rest of WP has loaded, kick-start the rest of the class.\n\t\t\tadd_action( 'init', array( $this, 'init' ) );\n\t\t}\n\n\t\t/**\n\t\t * Magic method to (not) set protected properties from outside of this class.\n\t\t *\n\t\t * @internal hackedihack... There is a serious bug in v2.3.2 - 2.3.6  where the `menu` property\n\t\t * is being assigned rather than tested in a conditional, effectively rendering it useless.\n\t\t * This 'hack' prevents this from happening.\n\t\t *\n\t\t * @see https://github.com/TGMPA/TGM-Plugin-Activation/blob/2.3.6/tgm-plugin-activation/class-tgm-plugin-activation.php#L1593\n\t\t *\n\t\t * @param string $name  Name of an inaccessible property.\n\t\t * @param mixed  $value Value to assign to the property.\n\t\t * @return void  Silently fail to set the property when this is tried from outside of this class context.\n\t\t *               (Inside this class context, the __set() method if not used as there is direct access.)\n\t\t */\n\t\tpublic function __set( $name, $value ) {\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Magic method to get the value of a protected property outside of this class context.\n\t\t *\n\t\t * @param string $name Name of an inaccessible property.\n\t\t * @return mixed The property value.\n\t\t */\n\t\tpublic function __get( $name ) {\n\t\t\treturn $this->{$name};\n\t\t}\n\n\t\t/**\n\t\t * Initialise the interactions between this class and WordPress.\n\t\t *\n\t\t * Hooks in three new methods for the class: admin_menu, notices and styles.\n\t\t *\n\t\t * @since 2.0.0\n\t\t *\n\t\t * @see TGM_Plugin_Activation::admin_menu()\n\t\t * @see TGM_Plugin_Activation::notices()\n\t\t * @see TGM_Plugin_Activation::styles()\n\t\t */\n\t\tpublic function init() {\n\t\t\t/**\n\t\t\t * By default TGMPA only loads on the WP back-end and not in an Ajax call. Using this filter\n\t\t\t * you can overrule that behaviour.\n\t\t\t *\n\t\t\t * @since 2.5.0\n\t\t\t *\n\t\t\t * @param bool $load Whether or not TGMPA should load.\n\t\t\t *                   Defaults to the return of `is_admin() && ! defined( 'DOING_AJAX' )`.\n\t\t\t */\n\t\t\tif ( true !== apply_filters( 'tgmpa_load', ( is_admin() && ! defined( 'DOING_AJAX' ) ) ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Load class strings.\n\t\t\t$this->strings = array(\n\t\t\t\t'page_title'                      => __( 'Install Required Plugins', 'tgmpa' ),\n\t\t\t\t'menu_title'                      => __( 'Install Plugins', 'tgmpa' ),\n\t\t\t\t'installing'                      => __( 'Installing Plugin: %s', 'tgmpa' ),\n\t\t\t\t'oops'                            => __( 'Something went wrong with the plugin API.', 'tgmpa' ),\n\t\t\t\t'notice_can_install_required'     => _n_noop(\n\t\t\t\t\t'This theme requires the following plugin: %1$s.',\n\t\t\t\t\t'This theme requires the following plugins: %1$s.',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'notice_can_install_recommended'  => _n_noop(\n\t\t\t\t\t'This theme recommends the following plugin: %1$s.',\n\t\t\t\t\t'This theme recommends the following plugins: %1$s.',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'notice_cannot_install'           => _n_noop(\n\t\t\t\t\t'Sorry, but you do not have the correct permissions to install the %1$s plugin.',\n\t\t\t\t\t'Sorry, but you do not have the correct permissions to install the %1$s plugins.',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'notice_ask_to_update'            => _n_noop(\n\t\t\t\t\t'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.',\n\t\t\t\t\t'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'notice_ask_to_update_maybe'      => _n_noop(\n\t\t\t\t\t'There is an update available for: %1$s.',\n\t\t\t\t\t'There are updates available for the following plugins: %1$s.',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'notice_cannot_update'            => _n_noop(\n\t\t\t\t\t'Sorry, but you do not have the correct permissions to update the %1$s plugin.',\n\t\t\t\t\t'Sorry, but you do not have the correct permissions to update the %1$s plugins.',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'notice_can_activate_required'    => _n_noop(\n\t\t\t\t\t'The following required plugin is currently inactive: %1$s.',\n\t\t\t\t\t'The following required plugins are currently inactive: %1$s.',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'notice_can_activate_recommended' => _n_noop(\n\t\t\t\t\t'The following recommended plugin is currently inactive: %1$s.',\n\t\t\t\t\t'The following recommended plugins are currently inactive: %1$s.',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'notice_cannot_activate'          => _n_noop(\n\t\t\t\t\t'Sorry, but you do not have the correct permissions to activate the %1$s plugin.',\n\t\t\t\t\t'Sorry, but you do not have the correct permissions to activate the %1$s plugins.',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'install_link'                    => _n_noop(\n\t\t\t\t\t'Begin installing plugin',\n\t\t\t\t\t'Begin installing plugins',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'update_link'                     => _n_noop(\n\t\t\t\t\t'Begin updating plugin',\n\t\t\t\t\t'Begin updating plugins',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'activate_link'                   => _n_noop(\n\t\t\t\t\t'Begin activating plugin',\n\t\t\t\t\t'Begin activating plugins',\n\t\t\t\t\t'tgmpa'\n\t\t\t\t),\n\t\t\t\t'return'                          => __( 'Return to Required Plugins Installer', 'tgmpa' ),\n\t\t\t\t'dashboard'                       => __( 'Return to the dashboard', 'tgmpa' ),\n\t\t\t\t'plugin_activated'                => __( 'Plugin activated successfully.', 'tgmpa' ),\n\t\t\t\t'activated_successfully'          => __( 'The following plugin was activated successfully:', 'tgmpa' ),\n\t\t\t\t'plugin_already_active'           => __( 'No action taken. Plugin %1$s was already active.', 'tgmpa' ),\n\t\t\t\t'plugin_needs_higher_version'     => __( 'Plugin not activated. A higher version of %s is needed for this theme. Please update the plugin.', 'tgmpa' ),\n\t\t\t\t'complete'                        => __( 'All plugins installed and activated successfully. %1$s', 'tgmpa' ),\n\t\t\t\t'dismiss'                         => __( 'Dismiss this notice', 'tgmpa' ),\n\t\t\t\t'contact_admin'                   => __( 'Please contact the administrator of this site for help.', 'tgmpa' ),\n\t\t\t);\n\n\t\t\tdo_action( 'tgmpa_register' );\n\n\t\t\t/* After this point, the plugins should be registered and the configuration set. */\n\n\t\t\t// Proceed only if we have plugins to handle.\n\t\t\tif ( empty( $this->plugins ) || ! is_array( $this->plugins ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set up the menu and notices if we still have outstanding actions.\n\t\t\tif ( true !== $this->is_tgmpa_complete() ) {\n\t\t\t\t// Sort the plugins.\n\t\t\t\tarray_multisort( $this->sort_order, SORT_ASC, $this->plugins );\n\n\t\t\t\tadd_action( 'admin_menu', array( $this, 'admin_menu' ) );\n\t\t\t\tadd_action( 'admin_head', array( $this, 'dismiss' ) );\n\n\t\t\t\t// Prevent the normal links from showing underneath a single install/update page.\n\t\t\t\tadd_filter( 'install_plugin_complete_actions', array( $this, 'actions' ) );\n\t\t\t\tadd_filter( 'update_plugin_complete_actions', array( $this, 'actions' ) );\n\n\t\t\t\tif ( $this->has_notices ) {\n\t\t\t\t\tadd_action( 'admin_notices', array( $this, 'notices' ) );\n\t\t\t\t\tadd_action( 'admin_init', array( $this, 'admin_init' ), 1 );\n\t\t\t\t\tadd_action( 'admin_enqueue_scripts', array( $this, 'thickbox' ) );\n\t\t\t\t}\n\n\t\t\t\tadd_action( 'load-plugins.php', array( $this, 'add_plugin_action_link_filters' ), 1 );\n\t\t\t}\n\n\t\t\t// Make sure things get reset on switch theme.\n\t\t\tadd_action( 'switch_theme', array( $this, 'flush_plugins_cache' ) );\n\n\t\t\tif ( $this->has_notices ) {\n\t\t\t\tadd_action( 'switch_theme', array( $this, 'update_dismiss' ) );\n\t\t\t}\n\n\t\t\t// Setup the force activation hook.\n\t\t\tif ( true === $this->has_forced_activation ) {\n\t\t\t\tadd_action( 'admin_init', array( $this, 'force_activation' ) );\n\t\t\t}\n\n\t\t\t// Setup the force deactivation hook.\n\t\t\tif ( true === $this->has_forced_deactivation ) {\n\t\t\t\tadd_action( 'switch_theme', array( $this, 'force_deactivation' ) );\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Prevent activation of plugins which don't meet the minimum version requirement from the\n\t\t * WP native plugins page.\n\t\t *\n\t\t * @since 2.5.0\n\t\t */\n\t\tpublic function add_plugin_action_link_filters() {\n\t\t\tforeach ( $this->plugins as $slug => $plugin ) {\n\t\t\t\tif ( false === $this->can_plugin_activate( $slug ) ) {\n\t\t\t\t\tadd_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_activate' ), 20 );\n\t\t\t\t}\n\n\t\t\t\tif ( true === $plugin['force_activation'] ) {\n\t\t\t\t\tadd_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_deactivate' ), 20 );\n\t\t\t\t}\n\n\t\t\t\tif ( false !== $this->does_plugin_require_update( $slug ) ) {\n\t\t\t\t\tadd_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_update' ), 20 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Remove the 'Activate' link on the WP native plugins page if the plugin does not meet the\n\t\t * minimum version requirements.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param array $actions Action links.\n\t\t * @return array\n\t\t */\n\t\tpublic function filter_plugin_action_links_activate( $actions ) {\n\t\t\tunset( $actions['activate'] );\n\n\t\t\treturn $actions;\n\t\t}\n\n\t\t/**\n\t\t * Remove the 'Deactivate' link on the WP native plugins page if the plugin has been set to force activate.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param array $actions Action links.\n\t\t * @return array\n\t\t */\n\t\tpublic function filter_plugin_action_links_deactivate( $actions ) {\n\t\t\tunset( $actions['deactivate'] );\n\n\t\t\treturn $actions;\n\t\t}\n\n\t\t/**\n\t\t * Add a 'Requires update' link on the WP native plugins page if the plugin does not meet the\n\t\t * minimum version requirements.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param array $actions Action links.\n\t\t * @return array\n\t\t */\n\t\tpublic function filter_plugin_action_links_update( $actions ) {\n\t\t\t$actions['update'] = sprintf(\n\t\t\t\t'<a href=\"%1$s\" title=\"%2$s\" class=\"edit\">%3$s</a>',\n\t\t\t\tesc_url( $this->get_tgmpa_status_url( 'update' ) ),\n\t\t\t\tesc_attr__( 'This plugin needs to be updated to be compatible with your theme.', 'tgmpa' ),\n\t\t\t\tesc_html__( 'Update Required', 'tgmpa' )\n\t\t\t);\n\n\t\t\treturn $actions;\n\t\t}\n\n\t\t/**\n\t\t * Handles calls to show plugin information via links in the notices.\n\t\t *\n\t\t * We get the links in the admin notices to point to the TGMPA page, rather\n\t\t * than the typical plugin-install.php file, so we can prepare everything\n\t\t * beforehand.\n\t\t *\n\t\t * WP does not make it easy to show the plugin information in the thickbox -\n\t\t * here we have to require a file that includes a function that does the\n\t\t * main work of displaying it, enqueue some styles, set up some globals and\n\t\t * finally call that function before exiting.\n\t\t *\n\t\t * Down right easy once you know how...\n\t\t *\n\t\t * Returns early if not the TGMPA page.\n\t\t *\n\t\t * @since 2.1.0\n\t\t *\n\t\t * @global string $tab Used as iframe div class names, helps with styling\n\t\t * @global string $body_id Used as the iframe body ID, helps with styling\n\t\t *\n\t\t * @return null Returns early if not the TGMPA page.\n\t\t */\n\t\tpublic function admin_init() {\n\t\t\tif ( ! $this->is_tgmpa_page() ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isset( $_REQUEST['tab'] ) && 'plugin-information' === $_REQUEST['tab'] ) {\n\t\t\t\t// Needed for install_plugin_information().\n\t\t\t\trequire_once ABSPATH . 'wp-admin/includes/plugin-install.php';\n\n\t\t\t\twp_enqueue_style( 'plugin-install' );\n\n\t\t\t\tglobal $tab, $body_id;\n\t\t\t\t$body_id = 'plugin-information';\n\t\t\t\t// @codingStandardsIgnoreStart\n\t\t\t\t$tab     = 'plugin-information';\n\t\t\t\t// @codingStandardsIgnoreEnd\n\n\t\t\t\tinstall_plugin_information();\n\n\t\t\t\texit;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Enqueue thickbox scripts/styles for plugin info.\n\t\t *\n\t\t * Thickbox is not automatically included on all admin pages, so we must\n\t\t * manually enqueue it for those pages.\n\t\t *\n\t\t * Thickbox is only loaded if the user has not dismissed the admin\n\t\t * notice or if there are any plugins left to install and activate.\n\t\t *\n\t\t * @since 2.1.0\n\t\t */\n\t\tpublic function thickbox() {\n\t\t\tif ( ! get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) ) {\n\t\t\t\tadd_thickbox();\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Adds submenu page if there are plugin actions to take.\n\t\t *\n\t\t * This method adds the submenu page letting users know that a required\n\t\t * plugin needs to be installed.\n\t\t *\n\t\t * This page disappears once the plugin has been installed and activated.\n\t\t *\n\t\t * @since 1.0.0\n\t\t *\n\t\t * @see TGM_Plugin_Activation::init()\n\t\t * @see TGM_Plugin_Activation::install_plugins_page()\n\t\t *\n\t\t * @return null Return early if user lacks capability to install a plugin.\n\t\t */\n\t\tpublic function admin_menu() {\n\t\t\t// Make sure privileges are correct to see the page.\n\t\t\tif ( ! current_user_can( 'install_plugins' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t$args = apply_filters(\n\t\t\t\t'tgmpa_admin_menu_args',\n\t\t\t\tarray(\n\t\t\t\t\t'parent_slug' => $this->parent_slug,                     // Parent Menu slug.\n\t\t\t\t\t'page_title'  => $this->strings['page_title'],           // Page title.\n\t\t\t\t\t'menu_title'  => $this->strings['menu_title'],           // Menu title.\n\t\t\t\t\t'capability'  => $this->capability,                      // Capability.\n\t\t\t\t\t'menu_slug'   => $this->menu,                            // Menu slug.\n\t\t\t\t\t'function'    => array( $this, 'install_plugins_page' ), // Callback.\n\t\t\t\t)\n\t\t\t);\n\n\t\t\t$this->add_admin_menu( $args );\n\t\t}\n\n\t\t/**\n\t\t * Add the menu item.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param array $args Menu item configuration.\n\t\t */\n\t\tprotected function add_admin_menu( array $args ) {\n\t\t\tif ( has_filter( 'tgmpa_admin_menu_use_add_theme_page' ) ) {\n\t\t\t\t_deprecated_function( 'The \"tgmpa_admin_menu_use_add_theme_page\" filter', '2.5.0', esc_html__( 'Set the parent_slug config variable instead.', 'tgmpa' ) );\n\t\t\t}\n\n\t\t\tif ( 'themes.php' === $this->parent_slug ) {\n\t\t\t\t$this->page_hook = call_user_func( 'add_theme_page', $args['page_title'], $args['menu_title'], $args['capability'], $args['menu_slug'], $args['function'] );\n\t\t\t} else {\n\t\t\t\t$this->page_hook = call_user_func( 'add_submenu_page', $args['parent_slug'], $args['page_title'], $args['menu_title'], $args['capability'], $args['menu_slug'], $args['function'] );\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Echoes plugin installation form.\n\t\t *\n\t\t * This method is the callback for the admin_menu method function.\n\t\t * This displays the admin page and form area where the user can select to install and activate the plugin.\n\t\t * Aborts early if we're processing a plugin installation action.\n\t\t *\n\t\t * @since 1.0.0\n\t\t *\n\t\t * @return null Aborts early if we're processing a plugin installation action.\n\t\t */\n\t\tpublic function install_plugins_page() {\n\t\t\t// Store new instance of plugin table in object.\n\t\t\t$plugin_table = new TGMPA_List_Table;\n\n\t\t\t// Return early if processing a plugin installation action.\n\t\t\tif ( ( ( 'tgmpa-bulk-install' === $plugin_table->current_action() || 'tgmpa-bulk-update' === $plugin_table->current_action() ) && $plugin_table->process_bulk_actions() ) || $this->do_plugin_install() ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Force refresh of available plugin information so we'll know about manual updates/deletes.\n\t\t\twp_clean_plugins_cache( false );\n\n\t\t\t?>\n\t\t\t<div class=\"tgmpa wrap\">\n\t\t\t\t<h2><?php echo esc_html( get_admin_page_title() ); ?></h2>\n\t\t\t\t<?php $plugin_table->prepare_items(); ?>\n\n\t\t\t\t<?php\n\t\t\t\tif ( ! empty( $this->message ) && is_string( $this->message ) ) {\n\t\t\t\t\techo wp_kses_post( $this->message );\n\t\t\t\t}\n\t\t\t\t?>\n\t\t\t\t<?php $plugin_table->views(); ?>\n\n\t\t\t\t<form id=\"tgmpa-plugins\" action=\"\" method=\"post\">\n\t\t\t\t\t<input type=\"hidden\" name=\"tgmpa-page\" value=\"<?php echo esc_attr( $this->menu ); ?>\" />\n\t\t\t\t\t<input type=\"hidden\" name=\"plugin_status\" value=\"<?php echo esc_attr( $plugin_table->view_context ); ?>\" />\n\t\t\t\t\t<?php $plugin_table->display(); ?>\n\t\t\t\t</form>\n\t\t\t</div>\n\t\t\t<?php\n\t\t}\n\n\t\t/**\n\t\t * Installs, updates or activates a plugin depending on the action link clicked by the user.\n\t\t *\n\t\t * Checks the $_GET variable to see which actions have been\n\t\t * passed and responds with the appropriate method.\n\t\t *\n\t\t * Uses WP_Filesystem to process and handle the plugin installation\n\t\t * method.\n\t\t *\n\t\t * @since 1.0.0\n\t\t *\n\t\t * @uses WP_Filesystem\n\t\t * @uses WP_Error\n\t\t * @uses WP_Upgrader\n\t\t * @uses Plugin_Upgrader\n\t\t * @uses Plugin_Installer_Skin\n\t\t * @uses Plugin_Upgrader_Skin\n\t\t *\n\t\t * @return boolean True on success, false on failure.\n\t\t */\n\t\tprotected function do_plugin_install() {\n\t\t\tif ( empty( $_GET['plugin'] ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// All plugin information will be stored in an array for processing.\n\t\t\t$slug = $this->sanitize_key( urldecode( $_GET['plugin'] ) );\n\n\t\t\tif ( ! isset( $this->plugins[ $slug ] ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Was an install or upgrade action link clicked?\n\t\t\tif ( ( isset( $_GET['tgmpa-install'] ) && 'install-plugin' === $_GET['tgmpa-install'] ) || ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) ) {\n\n\t\t\t\t$install_type = 'install';\n\t\t\t\tif ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) {\n\t\t\t\t\t$install_type = 'update';\n\t\t\t\t}\n\n\t\t\t\tcheck_admin_referer( 'tgmpa-' . $install_type, 'tgmpa-nonce' );\n\n\t\t\t\t// Pass necessary information via URL if WP_Filesystem is needed.\n\t\t\t\t$url = wp_nonce_url(\n\t\t\t\t\tadd_query_arg(\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'plugin'                 => urlencode( $slug ),\n\t\t\t\t\t\t\t'tgmpa-' . $install_type => $install_type . '-plugin',\n\t\t\t\t\t\t),\n\t\t\t\t\t\t$this->get_tgmpa_url()\n\t\t\t\t\t),\n\t\t\t\t\t'tgmpa-' . $install_type,\n\t\t\t\t\t'tgmpa-nonce'\n\t\t\t\t);\n\n\t\t\t\t$method = ''; // Leave blank so WP_Filesystem can populate it as necessary.\n\n\t\t\t\tif ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, array() ) ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tif ( ! WP_Filesystem( $creds ) ) {\n\t\t\t\t\trequest_filesystem_credentials( esc_url_raw( $url ), $method, true, false, array() ); // Setup WP_Filesystem.\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t/* If we arrive here, we have the filesystem. */\n\n\t\t\t\t// Prep variables for Plugin_Installer_Skin class.\n\t\t\t\t$extra         = array();\n\t\t\t\t$extra['slug'] = $slug; // Needed for potentially renaming of directory name.\n\t\t\t\t$source        = $this->get_download_url( $slug );\n\t\t\t\t$api           = ( 'repo' === $this->plugins[ $slug ]['source_type'] ) ? $this->get_plugins_api( $slug ) : null;\n\t\t\t\t$api           = ( false !== $api ) ? $api : null;\n\n\t\t\t\t$url = add_query_arg(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'action' => $install_type . '-plugin',\n\t\t\t\t\t\t'plugin' => urlencode( $slug ),\n\t\t\t\t\t),\n\t\t\t\t\t'update.php'\n\t\t\t\t);\n\n\t\t\t\tif ( ! class_exists( 'Plugin_Upgrader', false ) ) {\n\t\t\t\t\trequire_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';\n\t\t\t\t}\n\n\t\t\t\t$skin_args = array(\n\t\t\t\t\t'type'   => ( 'bundled' !== $this->plugins[ $slug ]['source_type'] ) ? 'web' : 'upload',\n\t\t\t\t\t'title'  => sprintf( $this->strings['installing'], $this->plugins[ $slug ]['name'] ),\n\t\t\t\t\t'url'    => esc_url_raw( $url ),\n\t\t\t\t\t'nonce'  => $install_type . '-plugin_' . $slug,\n\t\t\t\t\t'plugin' => '',\n\t\t\t\t\t'api'    => $api,\n\t\t\t\t\t'extra'  => $extra,\n\t\t\t\t);\n\n\t\t\t\tif ( 'update' === $install_type ) {\n\t\t\t\t\t$skin_args['plugin'] = $this->plugins[ $slug ]['file_path'];\n\t\t\t\t\t$skin                = new Plugin_Upgrader_Skin( $skin_args );\n\t\t\t\t} else {\n\t\t\t\t\t$skin = new Plugin_Installer_Skin( $skin_args );\n\t\t\t\t}\n\n\t\t\t\t// Create a new instance of Plugin_Upgrader.\n\t\t\t\t$upgrader = new Plugin_Upgrader( $skin );\n\n\t\t\t\t// Perform the action and install the plugin from the $source urldecode().\n\t\t\t\tadd_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1, 3 );\n\n\t\t\t\tif ( 'update' === $install_type ) {\n\t\t\t\t\t// Inject our info into the update transient.\n\t\t\t\t\t$to_inject                    = array( $slug => $this->plugins[ $slug ] );\n\t\t\t\t\t$to_inject[ $slug ]['source'] = $source;\n\t\t\t\t\t$this->inject_update_info( $to_inject );\n\n\t\t\t\t\t$upgrader->upgrade( $this->plugins[ $slug ]['file_path'] );\n\t\t\t\t} else {\n\t\t\t\t\t$upgrader->install( $source );\n\t\t\t\t}\n\n\t\t\t\tremove_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1, 3 );\n\n\t\t\t\t// Make sure we have the correct file path now the plugin is installed/updated.\n\t\t\t\t$this->populate_file_path( $slug );\n\n\t\t\t\t// Only activate plugins if the config option is set to true and the plugin isn't\n\t\t\t\t// already active (upgrade).\n\t\t\t\tif ( $this->is_automatic && ! $this->is_plugin_active( $slug ) ) {\n\t\t\t\t\t$plugin_activate = $upgrader->plugin_info(); // Grab the plugin info from the Plugin_Upgrader method.\n\t\t\t\t\tif ( false === $this->activate_single_plugin( $plugin_activate, $slug, true ) ) {\n\t\t\t\t\t\treturn true; // Finish execution of the function early as we encountered an error.\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$this->show_tgmpa_version();\n\n\t\t\t\t// Display message based on if all plugins are now active or not.\n\t\t\t\tif ( $this->is_tgmpa_complete() ) {\n\t\t\t\t\techo '<p>', sprintf( esc_html( $this->strings['complete'] ), '<a href=\"' . esc_url( self_admin_url() ) . '\">' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '</a>' ), '</p>';\n\t\t\t\t\techo '<style type=\"text/css\">#adminmenu .wp-submenu li.current { display: none !important; }</style>';\n\t\t\t\t} else {\n\t\t\t\t\techo '<p><a href=\"', esc_url( $this->get_tgmpa_url() ), '\" target=\"_parent\">', esc_html( $this->strings['return'] ), '</a></p>';\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t} elseif ( isset( $this->plugins[ $slug ]['file_path'], $_GET['tgmpa-activate'] ) && 'activate-plugin' === $_GET['tgmpa-activate'] ) {\n\t\t\t\t// Activate action link was clicked.\n\t\t\t\tcheck_admin_referer( 'tgmpa-activate', 'tgmpa-nonce' );\n\n\t\t\t\tif ( false === $this->activate_single_plugin( $this->plugins[ $slug ]['file_path'], $slug ) ) {\n\t\t\t\t\treturn true; // Finish execution of the function early as we encountered an error.\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t/**\n\t\t * Inject information into the 'update_plugins' site transient as WP checks that before running an update.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param array $plugins The plugin information for the plugins which are to be updated.\n\t\t */\n\t\tpublic function inject_update_info( $plugins ) {\n\t\t\t$repo_updates = get_site_transient( 'update_plugins' );\n\n\t\t\tif ( ! is_object( $repo_updates ) ) {\n\t\t\t\t$repo_updates = new stdClass;\n\t\t\t}\n\n\t\t\tforeach ( $plugins as $slug => $plugin ) {\n\t\t\t\t$file_path = $plugin['file_path'];\n\n\t\t\t\tif ( empty( $repo_updates->response[ $file_path ] ) ) {\n\t\t\t\t\t$repo_updates->response[ $file_path ] = new stdClass;\n\t\t\t\t}\n\n\t\t\t\t// We only really need to set package, but let's do all we can in case WP changes something.\n\t\t\t\t$repo_updates->response[ $file_path ]->slug        = $slug;\n\t\t\t\t$repo_updates->response[ $file_path ]->plugin      = $file_path;\n\t\t\t\t$repo_updates->response[ $file_path ]->new_version = $plugin['version'];\n\t\t\t\t$repo_updates->response[ $file_path ]->package     = $plugin['source'];\n\t\t\t\tif ( empty( $repo_updates->response[ $file_path ]->url ) && ! empty( $plugin['external_url'] ) ) {\n\t\t\t\t\t$repo_updates->response[ $file_path ]->url = $plugin['external_url'];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tset_site_transient( 'update_plugins', $repo_updates );\n\t\t}\n\n\t\t/**\n\t\t * Adjust the plugin directory name if necessary.\n\t\t *\n\t\t * The final destination directory of a plugin is based on the subdirectory name found in the\n\t\t * (un)zipped source. In some cases - most notably GitHub repository plugin downloads -, this\n\t\t * subdirectory name is not the same as the expected slug and the plugin will not be recognized\n\t\t * as installed. This is fixed by adjusting the temporary unzipped source subdirectory name to\n\t\t * the expected plugin slug.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string       $source        Path to upgrade/zip-file-name.tmp/subdirectory/.\n\t\t * @param string       $remote_source Path to upgrade/zip-file-name.tmp.\n\t\t * @param \\WP_Upgrader $upgrader      Instance of the upgrader which installs the plugin.\n\t\t * @return string $source\n\t\t */\n\t\tpublic function maybe_adjust_source_dir( $source, $remote_source, $upgrader ) {\n\t\t\tif ( ! $this->is_tgmpa_page() || ! is_object( $GLOBALS['wp_filesystem'] ) ) {\n\t\t\t\treturn $source;\n\t\t\t}\n\n\t\t\t// Check for single file plugins.\n\t\t\t$source_files = array_keys( $GLOBALS['wp_filesystem']->dirlist( $remote_source ) );\n\t\t\tif ( 1 === count( $source_files ) && false === $GLOBALS['wp_filesystem']->is_dir( $source ) ) {\n\t\t\t\treturn $source;\n\t\t\t}\n\n\t\t\t// Multi-file plugin, let's see if the directory is correctly named.\n\t\t\t$desired_slug = '';\n\n\t\t\t// Figure out what the slug is supposed to be.\n\t\t\tif ( false === $upgrader->bulk && ! empty( $upgrader->skin->options['extra']['slug'] ) ) {\n\t\t\t\t$desired_slug = $upgrader->skin->options['extra']['slug'];\n\t\t\t} else {\n\t\t\t\t// Bulk installer contains less info, so fall back on the info registered here.\n\t\t\t\tforeach ( $this->plugins as $slug => $plugin ) {\n\t\t\t\t\tif ( ! empty( $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) && $plugin['name'] === $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) {\n\t\t\t\t\t\t$desired_slug = $slug;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tunset( $slug, $plugin );\n\t\t\t}\n\n\t\t\tif ( ! empty( $desired_slug ) ) {\n\t\t\t\t$subdir_name = untrailingslashit( str_replace( trailingslashit( $remote_source ), '', $source ) );\n\n\t\t\t\tif ( ! empty( $subdir_name ) && $subdir_name !== $desired_slug ) {\n\t\t\t\t\t$from = untrailingslashit( $source );\n\t\t\t\t\t$to   = trailingslashit( $remote_source ) . $desired_slug;\n\n\t\t\t\t\tif ( true === $GLOBALS['wp_filesystem']->move( $from, $to ) ) {\n\t\t\t\t\t\treturn trailingslashit( $to );\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn new WP_Error( 'rename_failed', esc_html__( 'The remote plugin package does not contain a folder with the desired slug and renaming did not work.', 'tgmpa' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'tgmpa' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) );\n\t\t\t\t\t}\n\t\t\t\t} elseif ( empty( $subdir_name ) ) {\n\t\t\t\t\treturn new WP_Error( 'packaged_wrong', esc_html__( 'The remote plugin package consists of more than one file, but the files are not packaged in a folder.', 'tgmpa' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'tgmpa' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $source;\n\t\t}\n\n\t\t/**\n\t\t * Activate a single plugin and send feedback about the result to the screen.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $file_path Path within wp-plugins/ to main plugin file.\n\t\t * @param string $slug      Plugin slug.\n\t\t * @param bool   $automatic Whether this is an automatic activation after an install. Defaults to false.\n\t\t *                          This determines the styling of the output messages.\n\t\t * @return bool False if an error was encountered, true otherwise.\n\t\t */\n\t\tprotected function activate_single_plugin( $file_path, $slug, $automatic = false ) {\n\t\t\tif ( $this->can_plugin_activate( $slug ) ) {\n\t\t\t\t$activate = activate_plugin( $file_path );\n\n\t\t\t\tif ( is_wp_error( $activate ) ) {\n\t\t\t\t\techo '<div id=\"message\" class=\"error\"><p>', wp_kses_post( $activate->get_error_message() ), '</p></div>',\n\t\t\t\t\t\t'<p><a href=\"', esc_url( $this->get_tgmpa_url() ), '\" target=\"_parent\">', esc_html( $this->strings['return'] ), '</a></p>';\n\n\t\t\t\t\treturn false; // End it here if there is an error with activation.\n\t\t\t\t} else {\n\t\t\t\t\tif ( ! $automatic ) {\n\t\t\t\t\t\t// Make sure message doesn't display again if bulk activation is performed\n\t\t\t\t\t\t// immediately after a single activation.\n\t\t\t\t\t\tif ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK.\n\t\t\t\t\t\t\techo '<div id=\"message\" class=\"updated\"><p>', esc_html( $this->strings['activated_successfully'] ), ' <strong>', esc_html( $this->plugins[ $slug ]['name'] ), '.</strong></p></div>';\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Simpler message layout for use on the plugin install page.\n\t\t\t\t\t\techo '<p>', esc_html( $this->strings['plugin_activated'] ), '</p>';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} elseif ( $this->is_plugin_active( $slug ) ) {\n\t\t\t\t// No simpler message format provided as this message should never be encountered\n\t\t\t\t// on the plugin install page.\n\t\t\t\techo '<div id=\"message\" class=\"error\"><p>',\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\tesc_html( $this->strings['plugin_already_active'] ),\n\t\t\t\t\t\t'<strong>' . esc_html( $this->plugins[ $slug ]['name'] ) . '</strong>'\n\t\t\t\t\t),\n\t\t\t\t\t'</p></div>';\n\t\t\t} elseif ( $this->does_plugin_require_update( $slug ) ) {\n\t\t\t\tif ( ! $automatic ) {\n\t\t\t\t\t// Make sure message doesn't display again if bulk activation is performed\n\t\t\t\t\t// immediately after a single activation.\n\t\t\t\t\tif ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK.\n\t\t\t\t\t\techo '<div id=\"message\" class=\"error\"><p>',\n\t\t\t\t\t\t\tsprintf(\n\t\t\t\t\t\t\t\tesc_html( $this->strings['plugin_needs_higher_version'] ),\n\t\t\t\t\t\t\t\t'<strong>' . esc_html( $this->plugins[ $slug ]['name'] ) . '</strong>'\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'</p></div>';\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Simpler message layout for use on the plugin install page.\n\t\t\t\t\techo '<p>', sprintf( esc_html( $this->strings['plugin_needs_higher_version'] ), esc_html( $this->plugins[ $slug ]['name'] ) ), '</p>';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\t/**\n\t\t * Echoes required plugin notice.\n\t\t *\n\t\t * Outputs a message telling users that a specific plugin is required for\n\t\t * their theme. If appropriate, it includes a link to the form page where\n\t\t * users can install and activate the plugin.\n\t\t *\n\t\t * Returns early if we're on the Install page.\n\t\t *\n\t\t * @since 1.0.0\n\t\t *\n\t\t * @global object $current_screen\n\t\t *\n\t\t * @return null Returns early if we're on the Install page.\n\t\t */\n\t\tpublic function notices() {\n\t\t\t// Remove nag on the install page / Return early if the nag message has been dismissed.\n\t\t\tif ( $this->is_tgmpa_page() || get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Store for the plugin slugs by message type.\n\t\t\t$message = array();\n\n\t\t\t// Initialize counters used to determine plurality of action link texts.\n\t\t\t$install_link_count  = 0;\n\t\t\t$update_link_count   = 0;\n\t\t\t$activate_link_count = 0;\n\n\t\t\tforeach ( $this->plugins as $slug => $plugin ) {\n\t\t\t\tif ( $this->is_plugin_active( $slug ) && false === $this->does_plugin_have_update( $slug ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( ! $this->is_plugin_installed( $slug ) ) {\n\t\t\t\t\tif ( current_user_can( 'install_plugins' ) ) {\n\t\t\t\t\t\t$install_link_count++;\n\n\t\t\t\t\t\tif ( true === $plugin['required'] ) {\n\t\t\t\t\t\t\t$message['notice_can_install_required'][] = $slug;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$message['notice_can_install_recommended'][] = $slug;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Need higher privileges to install the plugin.\n\t\t\t\t\t\t$message['notice_cannot_install'][] = $slug;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( ! $this->is_plugin_active( $slug ) && $this->can_plugin_activate( $slug ) ) {\n\t\t\t\t\t\tif ( current_user_can( 'activate_plugins' ) ) {\n\t\t\t\t\t\t\t$activate_link_count++;\n\n\t\t\t\t\t\t\tif ( true === $plugin['required'] ) {\n\t\t\t\t\t\t\t\t$message['notice_can_activate_required'][] = $slug;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$message['notice_can_activate_recommended'][] = $slug;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Need higher privileges to activate the plugin.\n\t\t\t\t\t\t\t$message['notice_cannot_activate'][] = $slug;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( $this->does_plugin_require_update( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) {\n\n\t\t\t\t\t\tif ( current_user_can( 'install_plugins' ) ) {\n\t\t\t\t\t\t\t$update_link_count++;\n\n\t\t\t\t\t\t\tif ( $this->does_plugin_require_update( $slug ) ) {\n\t\t\t\t\t\t\t\t$message['notice_ask_to_update'][] = $slug;\n\t\t\t\t\t\t\t} elseif ( false !== $this->does_plugin_have_update( $slug ) ) {\n\t\t\t\t\t\t\t\t$message['notice_ask_to_update_maybe'][] = $slug;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Need higher privileges to update the plugin.\n\t\t\t\t\t\t\t$message['notice_cannot_update'][] = $slug;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tunset( $slug, $plugin );\n\n\t\t\t// If we have notices to display, we move forward.\n\t\t\tif ( ! empty( $message ) ) {\n\t\t\t\tkrsort( $message ); // Sort messages.\n\t\t\t\t$rendered = '';\n\n\t\t\t\t// As add_settings_error() wraps the final message in a <p> and as the final message can't be\n\t\t\t\t// filtered, using <p>'s in our html would render invalid html output.\n\t\t\t\t$line_template = '<span style=\"display: block; margin: 0.5em 0.5em 0 0; clear: both;\">%s</span>' . \"\\n\";\n\n\t\t\t\t// If dismissable is false and a message is set, output it now.\n\t\t\t\tif ( ! $this->dismissable && ! empty( $this->dismiss_msg ) ) {\n\t\t\t\t\t$rendered .= sprintf( $line_template, wp_kses_post( $this->dismiss_msg ) );\n\t\t\t\t}\n\n\t\t\t\t// Render the individual message lines for the notice.\n\t\t\t\tforeach ( $message as $type => $plugin_group ) {\n\t\t\t\t\t$linked_plugins = array();\n\n\t\t\t\t\t// Get the external info link for a plugin if one is available.\n\t\t\t\t\tforeach ( $plugin_group as $plugin_slug ) {\n\t\t\t\t\t\t$linked_plugins[] = $this->get_info_link( $plugin_slug );\n\t\t\t\t\t}\n\t\t\t\t\tunset( $plugin_slug );\n\n\t\t\t\t\t$count          = count( $plugin_group );\n\t\t\t\t\t$linked_plugins = array_map( array( 'TGMPA_Utils', 'wrap_in_em' ), $linked_plugins );\n\t\t\t\t\t$last_plugin    = array_pop( $linked_plugins ); // Pop off last name to prep for readability.\n\t\t\t\t\t$imploded       = empty( $linked_plugins ) ? $last_plugin : ( implode( ', ', $linked_plugins ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'tgmpa' ) . ' ' . $last_plugin );\n\n\t\t\t\t\t$rendered .= sprintf(\n\t\t\t\t\t\t$line_template,\n\t\t\t\t\t\tsprintf(\n\t\t\t\t\t\t\ttranslate_nooped_plural( $this->strings[ $type ], $count, 'tgmpa' ),\n\t\t\t\t\t\t\t$imploded,\n\t\t\t\t\t\t\t$count\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( 0 === strpos( $type, 'notice_cannot' ) ) {\n\t\t\t\t\t\t$rendered .= $this->strings['contact_admin'];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tunset( $type, $plugin_group, $linked_plugins, $count, $last_plugin, $imploded );\n\n\t\t\t\t// Setup action links.\n\t\t\t\t$action_links = array(\n\t\t\t\t\t'install'  => '',\n\t\t\t\t\t'update'   => '',\n\t\t\t\t\t'activate' => '',\n\t\t\t\t\t'dismiss'  => $this->dismissable ? '<a href=\"' . esc_url( add_query_arg( 'tgmpa-dismiss', 'dismiss_admin_notices' ) ) . '\" class=\"dismiss-notice\" target=\"_parent\">' . esc_html( $this->strings['dismiss'] ) . '</a>' : '',\n\t\t\t\t);\n\n\t\t\t\t$link_template = '<a href=\"%2$s\">%1$s</a>';\n\n\t\t\t\tif ( current_user_can( 'install_plugins' ) ) {\n\t\t\t\t\tif ( $install_link_count > 0 ) {\n\t\t\t\t\t\t$action_links['install'] = sprintf(\n\t\t\t\t\t\t\t$link_template,\n\t\t\t\t\t\t\ttranslate_nooped_plural( $this->strings['install_link'], $install_link_count, 'tgmpa' ),\n\t\t\t\t\t\t\tesc_url( $this->get_tgmpa_status_url( 'install' ) )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif ( $update_link_count > 0 ) {\n\t\t\t\t\t\t$action_links['update'] = sprintf(\n\t\t\t\t\t\t\t$link_template,\n\t\t\t\t\t\t\ttranslate_nooped_plural( $this->strings['update_link'], $update_link_count, 'tgmpa' ),\n\t\t\t\t\t\t\tesc_url( $this->get_tgmpa_status_url( 'update' ) )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( current_user_can( 'activate_plugins' ) && $activate_link_count > 0 ) {\n\t\t\t\t\t$action_links['activate'] = sprintf(\n\t\t\t\t\t\t$link_template,\n\t\t\t\t\t\ttranslate_nooped_plural( $this->strings['activate_link'], $activate_link_count, 'tgmpa' ),\n\t\t\t\t\t\tesc_url( $this->get_tgmpa_status_url( 'activate' ) )\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t$action_links = apply_filters( 'tgmpa_notice_action_links', $action_links );\n\n\t\t\t\t$action_links = array_filter( (array) $action_links ); // Remove any empty array items.\n\n\t\t\t\tif ( ! empty( $action_links ) && is_array( $action_links ) ) {\n\t\t\t\t\t$action_links = sprintf( $line_template, implode( ' | ', $action_links ) );\n\t\t\t\t\t$rendered    .= apply_filters( 'tgmpa_notice_rendered_action_links', $action_links );\n\t\t\t\t}\n\n\t\t\t\t// Register the nag messages and prepare them to be processed.\n\t\t\t\tif ( ! empty( $this->strings['nag_type'] ) ) {\n\t\t\t\t\tadd_settings_error( 'tgmpa', 'tgmpa', $rendered, sanitize_html_class( strtolower( $this->strings['nag_type'] ) ) );\n\t\t\t\t} else {\n\t\t\t\t\t$nag_class = version_compare( $this->wp_version, '3.8', '<' ) ? 'updated' : 'update-nag';\n\t\t\t\t\tadd_settings_error( 'tgmpa', 'tgmpa', $rendered, $nag_class );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Admin options pages already output settings_errors, so this is to avoid duplication.\n\t\t\tif ( 'options-general' !== $GLOBALS['current_screen']->parent_base ) {\n\t\t\t\t$this->display_settings_errors();\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Display settings errors and remove those which have been displayed to avoid duplicate messages showing\n\t\t *\n\t\t * @since 2.5.0\n\t\t */\n\t\tprotected function display_settings_errors() {\n\t\t\tglobal $wp_settings_errors;\n\n\t\t\tsettings_errors( 'tgmpa' );\n\n\t\t\tforeach ( (array) $wp_settings_errors as $key => $details ) {\n\t\t\t\tif ( 'tgmpa' === $details['setting'] ) {\n\t\t\t\t\tunset( $wp_settings_errors[ $key ] );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Add dismissable admin notices.\n\t\t *\n\t\t * Appends a link to the admin nag messages. If clicked, the admin notice disappears and no longer is visible to users.\n\t\t *\n\t\t * @since 2.1.0\n\t\t */\n\t\tpublic function dismiss() {\n\t\t\tif ( isset( $_GET['tgmpa-dismiss'] ) ) {\n\t\t\t\tupdate_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, 1 );\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Add individual plugin to our collection of plugins.\n\t\t *\n\t\t * If the required keys are not set or the plugin has already\n\t\t * been registered, the plugin is not added.\n\t\t *\n\t\t * @since 2.0.0\n\t\t *\n\t\t * @param array|null $plugin Array of plugin arguments or null if invalid argument.\n\t\t * @return null Return early if incorrect argument.\n\t\t */\n\t\tpublic function register( $plugin ) {\n\t\t\tif ( empty( $plugin['slug'] ) || empty( $plugin['name'] ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( empty( $plugin['slug'] ) || ! is_string( $plugin['slug'] ) || isset( $this->plugins[ $plugin['slug'] ] ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t$defaults = array(\n\t\t\t\t'name'               => '',      // String\n\t\t\t\t'slug'               => '',      // String\n\t\t\t\t'source'             => 'repo',  // String\n\t\t\t\t'required'           => false,   // Boolean\n\t\t\t\t'version'            => '',      // String\n\t\t\t\t'force_activation'   => false,   // Boolean\n\t\t\t\t'force_deactivation' => false,   // Boolean\n\t\t\t\t'external_url'       => '',      // String\n\t\t\t\t'is_callable'        => '',      // String|Array.\n\t\t\t);\n\n\t\t\t// Prepare the received data.\n\t\t\t$plugin = wp_parse_args( $plugin, $defaults );\n\n\t\t\t// Standardize the received slug.\n\t\t\t$plugin['slug'] = $this->sanitize_key( $plugin['slug'] );\n\n\t\t\t// Forgive users for using string versions of booleans or floats for version number.\n\t\t\t$plugin['version']            = (string) $plugin['version'];\n\t\t\t$plugin['source']             = empty( $plugin['source'] ) ? 'repo' : $plugin['source'];\n\t\t\t$plugin['required']           = TGMPA_Utils::validate_bool( $plugin['required'] );\n\t\t\t$plugin['force_activation']   = TGMPA_Utils::validate_bool( $plugin['force_activation'] );\n\t\t\t$plugin['force_deactivation'] = TGMPA_Utils::validate_bool( $plugin['force_deactivation'] );\n\n\t\t\t// Enrich the received data.\n\t\t\t$plugin['file_path']   = $this->_get_plugin_basename_from_slug( $plugin['slug'] );\n\t\t\t$plugin['source_type'] = $this->get_plugin_source_type( $plugin['source'] );\n\n\t\t\t// Set the class properties.\n\t\t\t$this->plugins[ $plugin['slug'] ]    = $plugin;\n\t\t\t$this->sort_order[ $plugin['slug'] ] = $plugin['name'];\n\n\t\t\t// Should we add the force activation hook ?\n\t\t\tif ( true === $plugin['force_activation'] ) {\n\t\t\t\t$this->has_forced_activation = true;\n\t\t\t}\n\n\t\t\t// Should we add the force deactivation hook ?\n\t\t\tif ( true === $plugin['force_deactivation'] ) {\n\t\t\t\t$this->has_forced_deactivation = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Determine what type of source the plugin comes from.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $source The source of the plugin as provided, either empty (= WP repo), a file path\n\t\t *                       (= bundled) or an external URL.\n\t\t * @return string 'repo', 'external', or 'bundled'\n\t\t */\n\t\tprotected function get_plugin_source_type( $source ) {\n\t\t\tif ( 'repo' === $source || preg_match( self::WP_REPO_REGEX, $source ) ) {\n\t\t\t\treturn 'repo';\n\t\t\t} elseif ( preg_match( self::IS_URL_REGEX, $source ) ) {\n\t\t\t\treturn 'external';\n\t\t\t} else {\n\t\t\t\treturn 'bundled';\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Sanitizes a string key.\n\t\t *\n\t\t * Near duplicate of WP Core `sanitize_key()`. The difference is that uppercase characters *are*\n\t\t * allowed, so as not to break upgrade paths from non-standard bundled plugins using uppercase\n\t\t * characters in the plugin directory path/slug. Silly them.\n\t\t *\n\t\t * @see https://developer.wordpress.org/reference/hooks/sanitize_key/\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $key String key.\n\t\t * @return string Sanitized key\n\t\t */\n\t\tpublic function sanitize_key( $key ) {\n\t\t\t$raw_key = $key;\n\t\t\t$key     = preg_replace( '`[^A-Za-z0-9_-]`', '', $key );\n\n\t\t\t/**\n\t\t\t* Filter a sanitized key string.\n\t\t\t*\n\t\t\t* @since 3.0.0\n\t\t\t*\n\t\t\t* @param string $key     Sanitized key.\n\t\t\t* @param string $raw_key The key prior to sanitization.\n\t\t\t*/\n\t\t\treturn apply_filters( 'tgmpa_sanitize_key', $key, $raw_key );\n\t\t}\n\n\t\t/**\n\t\t * Amend default configuration settings.\n\t\t *\n\t\t * @since 2.0.0\n\t\t *\n\t\t * @param array $config Array of config options to pass as class properties.\n\t\t */\n\t\tpublic function config( $config ) {\n\t\t\t$keys = array(\n\t\t\t\t'id',\n\t\t\t\t'default_path',\n\t\t\t\t'has_notices',\n\t\t\t\t'dismissable',\n\t\t\t\t'dismiss_msg',\n\t\t\t\t'menu',\n\t\t\t\t'parent_slug',\n\t\t\t\t'capability',\n\t\t\t\t'is_automatic',\n\t\t\t\t'message',\n\t\t\t\t'strings',\n\t\t\t);\n\n\t\t\tforeach ( $keys as $key ) {\n\t\t\t\tif ( isset( $config[ $key ] ) ) {\n\t\t\t\t\tif ( is_array( $config[ $key ] ) ) {\n\t\t\t\t\t\t$this->$key = array_merge( $this->$key, $config[ $key ] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$this->$key = $config[ $key ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Amend action link after plugin installation.\n\t\t *\n\t\t * @since 2.0.0\n\t\t *\n\t\t * @param array $install_actions Existing array of actions.\n\t\t * @return array Amended array of actions.\n\t\t */\n\t\tpublic function actions( $install_actions ) {\n\t\t\t// Remove action links on the TGMPA install page.\n\t\t\tif ( $this->is_tgmpa_page() ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn $install_actions;\n\t\t}\n\n\t\t/**\n\t\t * Flushes the plugins cache on theme switch to prevent stale entries\n\t\t * from remaining in the plugin table.\n\t\t *\n\t\t * @since 2.4.0\n\t\t *\n\t\t * @param bool $clear_update_cache Optional. Whether to clear the Plugin updates cache.\n\t\t *                                 Parameter added in v2.5.0.\n\t\t */\n\t\tpublic function flush_plugins_cache( $clear_update_cache = true ) {\n\t\t\twp_clean_plugins_cache( $clear_update_cache );\n\t\t}\n\n\t\t/**\n\t\t * Set file_path key for each installed plugin.\n\t\t *\n\t\t * @since 2.1.0\n\t\t *\n\t\t * @param string $plugin_slug Optional. If set, only (re-)populates the file path for that specific plugin.\n\t\t *                            Parameter added in v2.5.0.\n\t\t */\n\t\tpublic function populate_file_path( $plugin_slug = '' ) {\n\t\t\tif ( ! empty( $plugin_slug ) && is_string( $plugin_slug ) && isset( $this->plugins[ $plugin_slug ] ) ) {\n\t\t\t\t$this->plugins[ $plugin_slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $plugin_slug );\n\t\t\t} else {\n\t\t\t\t// Add file_path key for all plugins.\n\t\t\t\tforeach ( $this->plugins as $slug => $values ) {\n\t\t\t\t\t$this->plugins[ $slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $slug );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Helper function to extract the file path of the plugin file from the\n\t\t * plugin slug, if the plugin is installed.\n\t\t *\n\t\t * @since 2.0.0\n\t\t *\n\t\t * @param string $slug Plugin slug (typically folder name) as provided by the developer.\n\t\t * @return string Either file path for plugin if installed, or just the plugin slug.\n\t\t */\n\t\tprotected function _get_plugin_basename_from_slug( $slug ) {\n\t\t\t$keys = array_keys( $this->get_plugins() );\n\n\t\t\tforeach ( $keys as $key ) {\n\t\t\t\tif ( preg_match( '|^' . $slug . '/|', $key ) ) {\n\t\t\t\t\treturn $key;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $slug;\n\t\t}\n\n\t\t/**\n\t\t * Retrieve plugin data, given the plugin name.\n\t\t *\n\t\t * Loops through the registered plugins looking for $name. If it finds it,\n\t\t * it returns the $data from that plugin. Otherwise, returns false.\n\t\t *\n\t\t * @since 2.1.0\n\t\t *\n\t\t * @param string $name Name of the plugin, as it was registered.\n\t\t * @param string $data Optional. Array key of plugin data to return. Default is slug.\n\t\t * @return string|boolean Plugin slug if found, false otherwise.\n\t\t */\n\t\tpublic function _get_plugin_data_from_name( $name, $data = 'slug' ) {\n\t\t\tforeach ( $this->plugins as $values ) {\n\t\t\t\tif ( $name === $values['name'] && isset( $values[ $data ] ) ) {\n\t\t\t\t\treturn $values[ $data ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t/**\n\t\t * Retrieve the download URL for a package.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return string Plugin download URL or path to local file or empty string if undetermined.\n\t\t */\n\t\tpublic function get_download_url( $slug ) {\n\t\t\t$dl_source = '';\n\n\t\t\tswitch ( $this->plugins[ $slug ]['source_type'] ) {\n\t\t\t\tcase 'repo':\n\t\t\t\t\treturn $this->get_wp_repo_download_url( $slug );\n\t\t\t\tcase 'external':\n\t\t\t\t\treturn $this->plugins[ $slug ]['source'];\n\t\t\t\tcase 'bundled':\n\t\t\t\t\treturn $this->default_path . $this->plugins[ $slug ]['source'];\n\t\t\t}\n\n\t\t\treturn $dl_source; // Should never happen.\n\t\t}\n\n\t\t/**\n\t\t * Retrieve the download URL for a WP repo package.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return string Plugin download URL.\n\t\t */\n\t\tprotected function get_wp_repo_download_url( $slug ) {\n\t\t\t$source = '';\n\t\t\t$api    = $this->get_plugins_api( $slug );\n\n\t\t\tif ( false !== $api && isset( $api->download_link ) ) {\n\t\t\t\t$source = $api->download_link;\n\t\t\t}\n\n\t\t\treturn $source;\n\t\t}\n\n\t\t/**\n\t\t * Try to grab information from WordPress API.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return object Plugins_api response object on success, WP_Error on failure.\n\t\t */\n\t\tprotected function get_plugins_api( $slug ) {\n\t\t\tstatic $api = array(); // Cache received responses.\n\n\t\t\tif ( ! isset( $api[ $slug ] ) ) {\n\t\t\t\tif ( ! function_exists( 'plugins_api' ) ) {\n\t\t\t\t\trequire_once ABSPATH . 'wp-admin/includes/plugin-install.php';\n\t\t\t\t}\n\n\t\t\t\t$response = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false ) ) );\n\n\t\t\t\t$api[ $slug ] = false;\n\n\t\t\t\tif ( is_wp_error( $response ) ) {\n\t\t\t\t\twp_die( esc_html( $this->strings['oops'] ) );\n\t\t\t\t} else {\n\t\t\t\t\t$api[ $slug ] = $response;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $api[ $slug ];\n\t\t}\n\n\t\t/**\n\t\t * Retrieve a link to a plugin information page.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return string Fully formed html link to a plugin information page if available\n\t\t *                or the plugin name if not.\n\t\t */\n\t\tpublic function get_info_link( $slug ) {\n\t\t\tif ( ! empty( $this->plugins[ $slug ]['external_url'] ) && preg_match( self::IS_URL_REGEX, $this->plugins[ $slug ]['external_url'] ) ) {\n\t\t\t\t$link = sprintf(\n\t\t\t\t\t'<a href=\"%1$s\" target=\"_blank\">%2$s</a>',\n\t\t\t\t\tesc_url( $this->plugins[ $slug ]['external_url'] ),\n\t\t\t\t\tesc_html( $this->plugins[ $slug ]['name'] )\n\t\t\t\t);\n\t\t\t} elseif ( 'repo' === $this->plugins[ $slug ]['source_type'] ) {\n\t\t\t\t$url = add_query_arg(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'tab'       => 'plugin-information',\n\t\t\t\t\t\t'plugin'    => urlencode( $slug ),\n\t\t\t\t\t\t'TB_iframe' => 'true',\n\t\t\t\t\t\t'width'     => '640',\n\t\t\t\t\t\t'height'    => '500',\n\t\t\t\t\t),\n\t\t\t\t\tself_admin_url( 'plugin-install.php' )\n\t\t\t\t);\n\n\t\t\t\t$link = sprintf(\n\t\t\t\t\t'<a href=\"%1$s\" class=\"thickbox\">%2$s</a>',\n\t\t\t\t\tesc_url( $url ),\n\t\t\t\t\tesc_html( $this->plugins[ $slug ]['name'] )\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t$link = esc_html( $this->plugins[ $slug ]['name'] ); // No hyperlink.\n\t\t\t}\n\n\t\t\treturn $link;\n\t\t}\n\n\t\t/**\n\t\t * Determine if we're on the TGMPA Install page.\n\t\t *\n\t\t * @since 2.1.0\n\t\t *\n\t\t * @return boolean True when on the TGMPA page, false otherwise.\n\t\t */\n\t\tprotected function is_tgmpa_page() {\n\t\t\treturn isset( $_GET['page'] ) && $this->menu === $_GET['page'];\n\t\t}\n\n\t\t/**\n\t\t * Retrieve the URL to the TGMPA Install page.\n\t\t *\n\t\t * I.e. depending on the config settings passed something along the lines of:\n\t\t * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @return string Properly encoded URL (not escaped).\n\t\t */\n\t\tpublic function get_tgmpa_url() {\n\t\t\tstatic $url;\n\n\t\t\tif ( ! isset( $url ) ) {\n\t\t\t\t$parent = $this->parent_slug;\n\t\t\t\tif ( false === strpos( $parent, '.php' ) ) {\n\t\t\t\t\t$parent = 'admin.php';\n\t\t\t\t}\n\t\t\t\t$url = add_query_arg(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'page' => urlencode( $this->menu ),\n\t\t\t\t\t),\n\t\t\t\t\tself_admin_url( $parent )\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn $url;\n\t\t}\n\n\t\t/**\n\t\t * Retrieve the URL to the TGMPA Install page for a specific plugin status (view).\n\t\t *\n\t\t * I.e. depending on the config settings passed something along the lines of:\n\t\t * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins&plugin_status=install\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $status Plugin status - either 'install', 'update' or 'activate'.\n\t\t * @return string Properly encoded URL (not escaped).\n\t\t */\n\t\tpublic function get_tgmpa_status_url( $status ) {\n\t\t\treturn add_query_arg(\n\t\t\t\tarray(\n\t\t\t\t\t'plugin_status' => urlencode( $status ),\n\t\t\t\t),\n\t\t\t\t$this->get_tgmpa_url()\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Determine whether there are open actions for plugins registered with TGMPA.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @return bool True if complete, i.e. no outstanding actions. False otherwise.\n\t\t */\n\t\tpublic function is_tgmpa_complete() {\n\t\t\t$complete = true;\n\t\t\tforeach ( $this->plugins as $slug => $plugin ) {\n\t\t\t\tif ( ! $this->is_plugin_active( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) {\n\t\t\t\t\t$complete = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $complete;\n\t\t}\n\n\t\t/**\n\t\t * Check if a plugin is installed. Does not take must-use plugins into account.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return bool True if installed, false otherwise.\n\t\t */\n\t\tpublic function is_plugin_installed( $slug ) {\n\t\t\t$installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached).\n\n\t\t\treturn ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ] ) );\n\t\t}\n\n\t\t/**\n\t\t * Check if a plugin is active.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return bool True if active, false otherwise.\n\t\t */\n\t\tpublic function is_plugin_active( $slug ) {\n\t\t\treturn ( ( ! empty( $this->plugins[ $slug ]['is_callable'] ) && is_callable( $this->plugins[ $slug ]['is_callable'] ) ) || is_plugin_active( $this->plugins[ $slug ]['file_path'] ) );\n\t\t}\n\n\t\t/**\n\t\t * Check if a plugin can be updated, i.e. if we have information on the minimum WP version required\n\t\t * available, check whether the current install meets them.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return bool True if OK to update, false otherwise.\n\t\t */\n\t\tpublic function can_plugin_update( $slug ) {\n\t\t\t// We currently can't get reliable info on non-WP-repo plugins - issue #380.\n\t\t\tif ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t$api = $this->get_plugins_api( $slug );\n\n\t\t\tif ( false !== $api && isset( $api->requires ) ) {\n\t\t\t\treturn version_compare( $GLOBALS['wp_version'], $api->requires, '>=' );\n\t\t\t}\n\n\t\t\t// No usable info received from the plugins API, presume we can update.\n\t\t\treturn true;\n\t\t}\n\n\t\t/**\n\t\t * Check if a plugin can be activated, i.e. is not currently active and meets the minimum\n\t\t * plugin version requirements set in TGMPA (if any).\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return bool True if OK to activate, false otherwise.\n\t\t */\n\t\tpublic function can_plugin_activate( $slug ) {\n\t\t\treturn ( ! $this->is_plugin_active( $slug ) && ! $this->does_plugin_require_update( $slug ) );\n\t\t}\n\n\t\t/**\n\t\t * Retrieve the version number of an installed plugin.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return string Version number as string or an empty string if the plugin is not installed\n\t\t *                or version unknown (plugins which don't comply with the plugin header standard).\n\t\t */\n\t\tpublic function get_installed_version( $slug ) {\n\t\t\t$installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached).\n\n\t\t\tif ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version'] ) ) {\n\t\t\t\treturn $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version'];\n\t\t\t}\n\n\t\t\treturn '';\n\t\t}\n\n\t\t/**\n\t\t * Check whether a plugin complies with the minimum version requirements.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return bool True when a plugin needs to be updated, otherwise false.\n\t\t */\n\t\tpublic function does_plugin_require_update( $slug ) {\n\t\t\t$installed_version = $this->get_installed_version( $slug );\n\t\t\t$minimum_version   = $this->plugins[ $slug ]['version'];\n\n\t\t\treturn version_compare( $minimum_version, $installed_version, '>' );\n\t\t}\n\n\t\t/**\n\t\t * Check whether there is an update available for a plugin.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return false|string Version number string of the available update or false if no update available.\n\t\t */\n\t\tpublic function does_plugin_have_update( $slug ) {\n\t\t\t// Presume bundled and external plugins will point to a package which meets the minimum required version.\n\t\t\tif ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) {\n\t\t\t\tif ( $this->does_plugin_require_update( $slug ) ) {\n\t\t\t\t\treturn $this->plugins[ $slug ]['version'];\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t$repo_updates = get_site_transient( 'update_plugins' );\n\n\t\t\tif ( isset( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version ) ) {\n\t\t\t\treturn $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t/**\n\t\t * Retrieve potential upgrade notice for a plugin.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return string The upgrade notice or an empty string if no message was available or provided.\n\t\t */\n\t\tpublic function get_upgrade_notice( $slug ) {\n\t\t\t// We currently can't get reliable info on non-WP-repo plugins - issue #380.\n\t\t\tif ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) {\n\t\t\t\treturn '';\n\t\t\t}\n\n\t\t\t$repo_updates = get_site_transient( 'update_plugins' );\n\n\t\t\tif ( ! empty( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice ) ) {\n\t\t\t\treturn $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice;\n\t\t\t}\n\n\t\t\treturn '';\n\t\t}\n\n\t\t/**\n\t\t * Wrapper around the core WP get_plugins function, making sure it's actually available.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $plugin_folder Optional. Relative path to single plugin folder.\n\t\t * @return array Array of installed plugins with plugin information.\n\t\t */\n\t\tpublic function get_plugins( $plugin_folder = '' ) {\n\t\t\tif ( ! function_exists( 'get_plugins' ) ) {\n\t\t\t\trequire_once ABSPATH . 'wp-admin/includes/plugin.php';\n\t\t\t}\n\n\t\t\treturn get_plugins( $plugin_folder );\n\t\t}\n\n\t\t/**\n\t\t * Delete dismissable nag option when theme is switched.\n\t\t *\n\t\t * This ensures that the user(s) is/are again reminded via nag of required\n\t\t * and/or recommended plugins if they re-activate the theme.\n\t\t *\n\t\t * @since 2.1.1\n\t\t */\n\t\tpublic function update_dismiss() {\n\t\t\tdelete_metadata( 'user', null, 'tgmpa_dismissed_notice_' . $this->id, null, true );\n\t\t}\n\n\t\t/**\n\t\t * Forces plugin activation if the parameter 'force_activation' is\n\t\t * set to true.\n\t\t *\n\t\t * This allows theme authors to specify certain plugins that must be\n\t\t * active at all times while using the current theme.\n\t\t *\n\t\t * Please take special care when using this parameter as it has the\n\t\t * potential to be harmful if not used correctly. Setting this parameter\n\t\t * to true will not allow the specified plugin to be deactivated unless\n\t\t * the user switches themes.\n\t\t *\n\t\t * @since 2.2.0\n\t\t */\n\t\tpublic function force_activation() {\n\t\t\tforeach ( $this->plugins as $slug => $plugin ) {\n\t\t\t\tif ( true === $plugin['force_activation'] ) {\n\t\t\t\t\tif ( ! $this->is_plugin_installed( $slug ) ) {\n\t\t\t\t\t\t// Oops, plugin isn't there so iterate to next condition.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} elseif ( $this->can_plugin_activate( $slug ) ) {\n\t\t\t\t\t\t// There we go, activate the plugin.\n\t\t\t\t\t\tactivate_plugin( $plugin['file_path'] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Forces plugin deactivation if the parameter 'force_deactivation'\n\t\t * is set to true.\n\t\t *\n\t\t * This allows theme authors to specify certain plugins that must be\n\t\t * deactivated upon switching from the current theme to another.\n\t\t *\n\t\t * Please take special care when using this parameter as it has the\n\t\t * potential to be harmful if not used correctly.\n\t\t *\n\t\t * @since 2.2.0\n\t\t */\n\t\tpublic function force_deactivation() {\n\t\t\tforeach ( $this->plugins as $slug => $plugin ) {\n\t\t\t\t// Only proceed forward if the parameter is set to true and plugin is active.\n\t\t\t\tif ( true === $plugin['force_deactivation'] && $this->is_plugin_active( $slug ) ) {\n\t\t\t\t\tdeactivate_plugins( $plugin['file_path'] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Echo the current TGMPA version number to the page.\n\t\t */\n\t\tpublic function show_tgmpa_version() {\n\t\t\techo '<p style=\"float: right; padding: 0em 1.5em 0.5em 0;\"><strong><small>',\n\t\t\t\tesc_html( sprintf( _x( 'TGMPA v%s', '%s = version number', 'tgmpa' ), self::TGMPA_VERSION ) ),\n\t\t\t\t'</small></strong></p>';\n\t\t}\n\n\t\t/**\n\t\t * Returns the singleton instance of the class.\n\t\t *\n\t\t * @since 2.4.0\n\t\t *\n\t\t * @return object The TGM_Plugin_Activation object.\n\t\t */\n\t\tpublic static function get_instance() {\n\t\t\tif ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) {\n\t\t\t\tself::$instance = new self();\n\t\t\t}\n\n\t\t\treturn self::$instance;\n\t\t}\n\t}\n\n\tif ( ! function_exists( 'load_tgm_plugin_activation' ) ) {\n\t\t/**\n\t\t * Ensure only one instance of the class is ever invoked.\n\t\t */\n\t\tfunction load_tgm_plugin_activation() {\n\t\t\t$GLOBALS['tgmpa'] = TGM_Plugin_Activation::get_instance();\n\t\t}\n\t}\n\n\tif ( did_action( 'plugins_loaded' ) ) {\n\t\tload_tgm_plugin_activation();\n\t} else {\n\t\tadd_action( 'plugins_loaded', 'load_tgm_plugin_activation' );\n\t}\n}\n\nif ( ! function_exists( 'tgmpa' ) ) {\n\t/**\n\t * Helper function to register a collection of required plugins.\n\t *\n\t * @since 2.0.0\n\t * @api\n\t *\n\t * @param array $plugins An array of plugin arrays.\n\t * @param array $config  Optional. An array of configuration values.\n\t */\n\tfunction tgmpa( $plugins, $config = array() ) {\n\t\t$instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) );\n\n\t\tforeach ( $plugins as $plugin ) {\n\t\t\tcall_user_func( array( $instance, 'register' ), $plugin );\n\t\t}\n\n\t\tif ( ! empty( $config ) && is_array( $config ) ) {\n\t\t\t// Send out notices for deprecated arguments passed.\n\t\t\tif ( isset( $config['notices'] ) ) {\n\t\t\t\t_deprecated_argument( __FUNCTION__, '2.2.0', 'The `notices` config parameter was renamed to `has_notices` in TGMPA 2.2.0. Please adjust your configuration.' );\n\t\t\t\tif ( ! isset( $config['has_notices'] ) ) {\n\t\t\t\t\t$config['has_notices'] = $config['notices'];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( isset( $config['parent_menu_slug'] ) ) {\n\t\t\t\t_deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_menu_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' );\n\t\t\t}\n\t\t\tif ( isset( $config['parent_url_slug'] ) ) {\n\t\t\t\t_deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_url_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' );\n\t\t\t}\n\n\t\t\tcall_user_func( array( $instance, 'config' ), $config );\n\t\t}\n\t}\n}\n\n/**\n * WP_List_Table isn't always available. If it isn't available,\n * we load it here.\n *\n * @since 2.2.0\n */\nif ( ! class_exists( 'WP_List_Table' ) ) {\n\trequire_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';\n}\n\nif ( ! class_exists( 'TGMPA_List_Table' ) ) {\n\n\t/**\n\t * List table class for handling plugins.\n\t *\n\t * Extends the WP_List_Table class to provide a future-compatible\n\t * way of listing out all required/recommended plugins.\n\t *\n\t * Gives users an interface similar to the Plugin Administration\n\t * area with similar (albeit stripped down) capabilities.\n\t *\n\t * This class also allows for the bulk install of plugins.\n\t *\n\t * @since 2.2.0\n\t *\n\t * @package TGM-Plugin-Activation\n\t * @author  Thomas Griffin\n\t * @author  Gary Jones\n\t */\n\tclass TGMPA_List_Table extends WP_List_Table {\n\t\t/**\n\t\t * TGMPA instance.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @var object\n\t\t */\n\t\tprotected $tgmpa;\n\n\t\t/**\n\t\t * The currently chosen view.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @var string One of: 'all', 'install', 'update', 'activate'\n\t\t */\n\t\tpublic $view_context = 'all';\n\n\t\t/**\n\t\t * The plugin counts for the various views.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @var array\n\t\t */\n\t\tprotected $view_totals = array(\n\t\t\t'all'      => 0,\n\t\t\t'install'  => 0,\n\t\t\t'update'   => 0,\n\t\t\t'activate' => 0,\n\t\t);\n\n\t\t/**\n\t\t * References parent constructor and sets defaults for class.\n\t\t *\n\t\t * @since 2.2.0\n\t\t */\n\t\tpublic function __construct() {\n\t\t\t$this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) );\n\n\t\t\tparent::__construct(\n\t\t\t\tarray(\n\t\t\t\t\t'singular' => 'plugin',\n\t\t\t\t\t'plural'   => 'plugins',\n\t\t\t\t\t'ajax'     => false,\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tif ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'install', 'update', 'activate' ), true ) ) {\n\t\t\t\t$this->view_context = sanitize_key( $_REQUEST['plugin_status'] );\n\t\t\t}\n\n\t\t\tadd_filter( 'tgmpa_table_data_items', array( $this, 'sort_table_items' ) );\n\t\t}\n\n\t\t/**\n\t\t * Get a list of CSS classes for the <table> tag.\n\t\t *\n\t\t * Overruled to prevent the 'plural' argument from being added.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @return array CSS classnames.\n\t\t */\n\t\tpublic function get_table_classes() {\n\t\t\treturn array( 'widefat', 'fixed' );\n\t\t}\n\n\t\t/**\n\t\t * Gathers and renames all of our plugin information to be used by WP_List_Table to create our table.\n\t\t *\n\t\t * @since 2.2.0\n\t\t *\n\t\t * @return array $table_data Information for use in table.\n\t\t */\n\t\tprotected function _gather_plugin_data() {\n\t\t\t// Load thickbox for plugin links.\n\t\t\t$this->tgmpa->admin_init();\n\t\t\t$this->tgmpa->thickbox();\n\n\t\t\t// Categorize the plugins which have open actions.\n\t\t\t$plugins = $this->categorize_plugins_to_views();\n\n\t\t\t// Set the counts for the view links.\n\t\t\t$this->set_view_totals( $plugins );\n\n\t\t\t// Prep variables for use and grab list of all installed plugins.\n\t\t\t$table_data = array();\n\t\t\t$i          = 0;\n\n\t\t\t// Redirect to the 'all' view if no plugins were found for the selected view context.\n\t\t\tif ( empty( $plugins[ $this->view_context ] ) ) {\n\t\t\t\t$this->view_context = 'all';\n\t\t\t}\n\n\t\t\tforeach ( $plugins[ $this->view_context ] as $slug => $plugin ) {\n\t\t\t\t$table_data[ $i ]['sanitized_plugin']  = $plugin['name'];\n\t\t\t\t$table_data[ $i ]['slug']              = $slug;\n\t\t\t\t$table_data[ $i ]['plugin']            = '<strong>' . $this->tgmpa->get_info_link( $slug ) . '</strong>';\n\t\t\t\t$table_data[ $i ]['source']            = $this->get_plugin_source_type_text( $plugin['source_type'] );\n\t\t\t\t$table_data[ $i ]['type']              = $this->get_plugin_advise_type_text( $plugin['required'] );\n\t\t\t\t$table_data[ $i ]['status']            = $this->get_plugin_status_text( $slug );\n\t\t\t\t$table_data[ $i ]['installed_version'] = $this->tgmpa->get_installed_version( $slug );\n\t\t\t\t$table_data[ $i ]['minimum_version']   = $plugin['version'];\n\t\t\t\t$table_data[ $i ]['available_version'] = $this->tgmpa->does_plugin_have_update( $slug );\n\n\t\t\t\t// Prep the upgrade notice info.\n\t\t\t\t$upgrade_notice = $this->tgmpa->get_upgrade_notice( $slug );\n\t\t\t\tif ( ! empty( $upgrade_notice ) ) {\n\t\t\t\t\t$table_data[ $i ]['upgrade_notice'] = $upgrade_notice;\n\n\t\t\t\t\tadd_action( \"tgmpa_after_plugin_row_$slug\", array( $this, 'wp_plugin_update_row' ), 10, 2 );\n\t\t\t\t}\n\n\t\t\t\t$table_data[ $i ] = apply_filters( 'tgmpa_table_data_item', $table_data[ $i ], $plugin );\n\n\t\t\t\t$i++;\n\t\t\t}\n\n\t\t\treturn $table_data;\n\t\t}\n\n\t\t/**\n\t\t * Categorize the plugins which have open actions into views for the TGMPA page.\n\t\t *\n\t\t * @since 2.5.0\n\t\t */\n\t\tprotected function categorize_plugins_to_views() {\n\t\t\t$plugins = array(\n\t\t\t\t'all'      => array(), // Meaning: all plugins which still have open actions.\n\t\t\t\t'install'  => array(),\n\t\t\t\t'update'   => array(),\n\t\t\t\t'activate' => array(),\n\t\t\t);\n\n\t\t\tforeach ( $this->tgmpa->plugins as $slug => $plugin ) {\n\t\t\t\tif ( $this->tgmpa->is_plugin_active( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) {\n\t\t\t\t\t// No need to display plugins if they are installed, up-to-date and active.\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\t$plugins['all'][ $slug ] = $plugin;\n\n\t\t\t\t\tif ( ! $this->tgmpa->is_plugin_installed( $slug ) ) {\n\t\t\t\t\t\t$plugins['install'][ $slug ] = $plugin;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) {\n\t\t\t\t\t\t\t$plugins['update'][ $slug ] = $plugin;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( $this->tgmpa->can_plugin_activate( $slug ) ) {\n\t\t\t\t\t\t\t$plugins['activate'][ $slug ] = $plugin;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $plugins;\n\t\t}\n\n\t\t/**\n\t\t * Set the counts for the view links.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param array $plugins Plugins order by view.\n\t\t */\n\t\tprotected function set_view_totals( $plugins ) {\n\t\t\tforeach ( $plugins as $type => $list ) {\n\t\t\t\t$this->view_totals[ $type ] = count( $list );\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Get the plugin required/recommended text string.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $required Plugin required setting.\n\t\t * @return string\n\t\t */\n\t\tprotected function get_plugin_advise_type_text( $required ) {\n\t\t\tif ( true === $required ) {\n\t\t\t\treturn __( 'Required', 'tgmpa' );\n\t\t\t}\n\n\t\t\treturn __( 'Recommended', 'tgmpa' );\n\t\t}\n\n\t\t/**\n\t\t * Get the plugin source type text string.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $type Plugin type.\n\t\t * @return string\n\t\t */\n\t\tprotected function get_plugin_source_type_text( $type ) {\n\t\t\t$string = '';\n\n\t\t\tswitch ( $type ) {\n\t\t\t\tcase 'repo':\n\t\t\t\t\t$string = __( 'WordPress Repository', 'tgmpa' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'external':\n\t\t\t\t\t$string = __( 'External Source', 'tgmpa' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'bundled':\n\t\t\t\t\t$string = __( 'Pre-Packaged', 'tgmpa' );\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn $string;\n\t\t}\n\n\t\t/**\n\t\t * Determine the plugin status message.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @return string\n\t\t */\n\t\tprotected function get_plugin_status_text( $slug ) {\n\t\t\tif ( ! $this->tgmpa->is_plugin_installed( $slug ) ) {\n\t\t\t\treturn __( 'Not Installed', 'tgmpa' );\n\t\t\t}\n\n\t\t\tif ( ! $this->tgmpa->is_plugin_active( $slug ) ) {\n\t\t\t\t$install_status = __( 'Installed But Not Activated', 'tgmpa' );\n\t\t\t} else {\n\t\t\t\t$install_status = __( 'Active', 'tgmpa' );\n\t\t\t}\n\n\t\t\t$update_status = '';\n\n\t\t\tif ( $this->tgmpa->does_plugin_require_update( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) {\n\t\t\t\t$update_status = __( 'Required Update not Available', 'tgmpa' );\n\n\t\t\t} elseif ( $this->tgmpa->does_plugin_require_update( $slug ) ) {\n\t\t\t\t$update_status = __( 'Requires Update', 'tgmpa' );\n\n\t\t\t} elseif ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) {\n\t\t\t\t$update_status = __( 'Update recommended', 'tgmpa' );\n\t\t\t}\n\n\t\t\tif ( '' === $update_status ) {\n\t\t\t\treturn $install_status;\n\t\t\t}\n\n\t\t\treturn sprintf(\n\t\t\t\t_x( '%1$s, %2$s', '%1$s = install status, %2$s = update status', 'tgmpa' ),\n\t\t\t\t$install_status,\n\t\t\t\t$update_status\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Sort plugins by Required/Recommended type and by alphabetical plugin name within each type.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param array $items Prepared table items.\n\t\t * @return array Sorted table items.\n\t\t */\n\t\tpublic function sort_table_items( $items ) {\n\t\t\t$type = array();\n\t\t\t$name = array();\n\n\t\t\tforeach ( $items as $i => $plugin ) {\n\t\t\t\t$type[ $i ] = $plugin['type']; // Required / recommended.\n\t\t\t\t$name[ $i ] = $plugin['sanitized_plugin'];\n\t\t\t}\n\n\t\t\tarray_multisort( $type, SORT_DESC, $name, SORT_ASC, $items );\n\n\t\t\treturn $items;\n\t\t}\n\n\t\t/**\n\t\t * Get an associative array ( id => link ) of the views available on this table.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @return array\n\t\t */\n\t\tpublic function get_views() {\n\t\t\t$status_links = array();\n\n\t\t\tforeach ( $this->view_totals as $type => $count ) {\n\t\t\t\tif ( $count < 1 ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tswitch ( $type ) {\n\t\t\t\t\tcase 'all':\n\t\t\t\t\t\t$text = _nx( 'All <span class=\"count\">(%s)</span>', 'All <span class=\"count\">(%s)</span>', $count, 'plugins', 'tgmpa' );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'install':\n\t\t\t\t\t\t$text = _n( 'To Install <span class=\"count\">(%s)</span>', 'To Install <span class=\"count\">(%s)</span>', $count, 'tgmpa' );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'update':\n\t\t\t\t\t\t$text = _n( 'Update Available <span class=\"count\">(%s)</span>', 'Update Available <span class=\"count\">(%s)</span>', $count, 'tgmpa' );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'activate':\n\t\t\t\t\t\t$text = _n( 'To Activate <span class=\"count\">(%s)</span>', 'To Activate <span class=\"count\">(%s)</span>', $count, 'tgmpa' );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t$text = '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( ! empty( $text ) ) {\n\n\t\t\t\t\t$status_links[ $type ] = sprintf(\n\t\t\t\t\t\t'<a href=\"%s\"%s>%s</a>',\n\t\t\t\t\t\tesc_url( $this->tgmpa->get_tgmpa_status_url( $type ) ),\n\t\t\t\t\t\t( $type === $this->view_context ) ? ' class=\"current\"' : '',\n\t\t\t\t\t\tsprintf( $text, number_format_i18n( $count ) )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $status_links;\n\t\t}\n\n\t\t/**\n\t\t * Create default columns to display important plugin information\n\t\t * like type, action and status.\n\t\t *\n\t\t * @since 2.2.0\n\t\t *\n\t\t * @param array  $item        Array of item data.\n\t\t * @param string $column_name The name of the column.\n\t\t * @return string\n\t\t */\n\t\tpublic function column_default( $item, $column_name ) {\n\t\t\treturn $item[ $column_name ];\n\t\t}\n\n\t\t/**\n\t\t * Required for bulk installing.\n\t\t *\n\t\t * Adds a checkbox for each plugin.\n\t\t *\n\t\t * @since 2.2.0\n\t\t *\n\t\t * @param array $item Array of item data.\n\t\t * @return string The input checkbox with all necessary info.\n\t\t */\n\t\tpublic function column_cb( $item ) {\n\t\t\treturn sprintf(\n\t\t\t\t'<input type=\"checkbox\" name=\"%1$s[]\" value=\"%2$s\" id=\"%3$s\" />',\n\t\t\t\tesc_attr( $this->_args['singular'] ),\n\t\t\t\tesc_attr( $item['slug'] ),\n\t\t\t\tesc_attr( $item['sanitized_plugin'] )\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Create default title column along with the action links.\n\t\t *\n\t\t * @since 2.2.0\n\t\t *\n\t\t * @param array $item Array of item data.\n\t\t * @return string The plugin name and action links.\n\t\t */\n\t\tpublic function column_plugin( $item ) {\n\t\t\treturn sprintf(\n\t\t\t\t'%1$s %2$s',\n\t\t\t\t$item['plugin'],\n\t\t\t\t$this->row_actions( $this->get_row_actions( $item ), true )\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Create version information column.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param array $item Array of item data.\n\t\t * @return string HTML-formatted version information.\n\t\t */\n\t\tpublic function column_version( $item ) {\n\t\t\t$output = array();\n\n\t\t\tif ( $this->tgmpa->is_plugin_installed( $item['slug'] ) ) {\n\t\t\t\t$installed = ! empty( $item['installed_version'] ) ? $item['installed_version'] : _x( 'unknown', 'as in: \"version nr unknown\"', 'tgmpa' );\n\n\t\t\t\t$color = '';\n\t\t\t\tif ( ! empty( $item['minimum_version'] ) && $this->tgmpa->does_plugin_require_update( $item['slug'] ) ) {\n\t\t\t\t\t$color = ' color: #ff0000; font-weight: bold;';\n\t\t\t\t}\n\n\t\t\t\t$output[] = sprintf(\n\t\t\t\t\t'<p><span style=\"min-width: 32px; text-align: right; float: right;%1$s\">%2$s</span>' . __( 'Installed version:', 'tgmpa' ) . '</p>',\n\t\t\t\t\t$color,\n\t\t\t\t\t$installed\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( ! empty( $item['minimum_version'] ) ) {\n\t\t\t\t$output[] = sprintf(\n\t\t\t\t\t'<p><span style=\"min-width: 32px; text-align: right; float: right;\">%1$s</span>' . __( 'Minimum required version:', 'tgmpa' ) . '</p>',\n\t\t\t\t\t$item['minimum_version']\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( ! empty( $item['available_version'] ) ) {\n\t\t\t\t$color = '';\n\t\t\t\tif ( ! empty( $item['minimum_version'] ) && version_compare( $item['available_version'], $item['minimum_version'], '>=' ) ) {\n\t\t\t\t\t$color = ' color: #71C671; font-weight: bold;';\n\t\t\t\t}\n\n\t\t\t\t$output[] = sprintf(\n\t\t\t\t\t'<p><span style=\"min-width: 32px; text-align: right; float: right;%1$s\">%2$s</span>' . __( 'Available version:', 'tgmpa' ) . '</p>',\n\t\t\t\t\t$color,\n\t\t\t\t\t$item['available_version']\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( empty( $output ) ) {\n\t\t\t\treturn '&nbsp;'; // Let's not break the table layout.\n\t\t\t} else {\n\t\t\t\treturn implode( \"\\n\", $output );\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Sets default message within the plugins table if no plugins\n\t\t * are left for interaction.\n\t\t *\n\t\t * Hides the menu item to prevent the user from clicking and\n\t\t * getting a permissions error.\n\t\t *\n\t\t * @since 2.2.0\n\t\t */\n\t\tpublic function no_items() {\n\t\t\tprintf( wp_kses_post( __( 'No plugins to install, update or activate. <a href=\"%1$s\">Return to the Dashboard</a>', 'tgmpa' ) ), esc_url( self_admin_url() ) );\n\t\t\techo '<style type=\"text/css\">#adminmenu .wp-submenu li.current { display: none !important; }</style>';\n\t\t}\n\n\t\t/**\n\t\t * Output all the column information within the table.\n\t\t *\n\t\t * @since 2.2.0\n\t\t *\n\t\t * @return array $columns The column names.\n\t\t */\n\t\tpublic function get_columns() {\n\t\t\t$columns = array(\n\t\t\t\t'cb'     => '<input type=\"checkbox\" />',\n\t\t\t\t'plugin' => __( 'Plugin', 'tgmpa' ),\n\t\t\t\t'source' => __( 'Source', 'tgmpa' ),\n\t\t\t\t'type'   => __( 'Type', 'tgmpa' ),\n\t\t\t);\n\n\t\t\tif ( 'all' === $this->view_context || 'update' === $this->view_context ) {\n\t\t\t\t$columns['version'] = __( 'Version', 'tgmpa' );\n\t\t\t\t$columns['status']  = __( 'Status', 'tgmpa' );\n\t\t\t}\n\n\t\t\treturn apply_filters( 'tgmpa_table_columns', $columns );\n\t\t}\n\n\t\t/**\n\t\t * Get name of default primary column\n\t\t *\n\t\t * @since 2.5.0 / WP 4.3+ compatibility\n\t\t * @access protected\n\t\t *\n\t\t * @return string\n\t\t */\n\t\tprotected function get_default_primary_column_name() {\n\t\t\treturn 'plugin';\n\t\t}\n\n\t\t/**\n\t\t * Get the name of the primary column.\n\t\t *\n\t\t * @since 2.5.0 / WP 4.3+ compatibility\n\t\t * @access protected\n\t\t *\n\t\t * @return string The name of the primary column.\n\t\t */\n\t\tprotected function get_primary_column_name() {\n\t\t\tif ( method_exists( 'WP_List_Table', 'get_primary_column_name' ) ) {\n\t\t\t\treturn parent::get_primary_column_name();\n\t\t\t} else {\n\t\t\t\treturn $this->get_default_primary_column_name();\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Get the actions which are relevant for a specific plugin row.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param array $item Array of item data.\n\t\t * @return array Array with relevant action links.\n\t\t */\n\t\tprotected function get_row_actions( $item ) {\n\t\t\t$actions      = array();\n\t\t\t$action_links = array();\n\n\t\t\t// Display the 'Install' action link if the plugin is not yet available.\n\t\t\tif ( ! $this->tgmpa->is_plugin_installed( $item['slug'] ) ) {\n\t\t\t\t$actions['install'] = _x( 'Install %2$s', '%2$s = plugin name in screen reader markup', 'tgmpa' );\n\t\t\t} else {\n\t\t\t\t// Display the 'Update' action link if an update is available and WP complies with plugin minimum.\n\t\t\t\tif ( false !== $this->tgmpa->does_plugin_have_update( $item['slug'] ) && $this->tgmpa->can_plugin_update( $item['slug'] ) ) {\n\t\t\t\t\t$actions['update'] = _x( 'Update %2$s', '%2$s = plugin name in screen reader markup', 'tgmpa' );\n\t\t\t\t}\n\n\t\t\t\t// Display the 'Activate' action link, but only if the plugin meets the minimum version.\n\t\t\t\tif ( $this->tgmpa->can_plugin_activate( $item['slug'] ) ) {\n\t\t\t\t\t$actions['activate'] = _x( 'Activate %2$s', '%2$s = plugin name in screen reader markup', 'tgmpa' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Create the actual links.\n\t\t\tforeach ( $actions as $action => $text ) {\n\t\t\t\t$nonce_url = wp_nonce_url(\n\t\t\t\t\tadd_query_arg(\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'plugin'           => urlencode( $item['slug'] ),\n\t\t\t\t\t\t\t'tgmpa-' . $action => $action . '-plugin',\n\t\t\t\t\t\t),\n\t\t\t\t\t\t$this->tgmpa->get_tgmpa_url()\n\t\t\t\t\t),\n\t\t\t\t\t'tgmpa-' . $action,\n\t\t\t\t\t'tgmpa-nonce'\n\t\t\t\t);\n\n\t\t\t\t$action_links[ $action ] = sprintf(\n\t\t\t\t\t'<a href=\"%1$s\">' . esc_html( $text ) . '</a>',\n\t\t\t\t\tesc_url( $nonce_url ),\n\t\t\t\t\t'<span class=\"screen-reader-text\">' . esc_html( $item['sanitized_plugin'] ) . '</span>'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t$prefix = ( defined( 'WP_NETWORK_ADMIN' ) && WP_NETWORK_ADMIN ) ? 'network_admin_' : '';\n\t\t\treturn apply_filters( \"tgmpa_{$prefix}plugin_action_links\", array_filter( $action_links ), $item['slug'], $item, $this->view_context );\n\t\t}\n\n\t\t/**\n\t\t * Generates content for a single row of the table.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param object $item The current item.\n\t\t */\n\t\tpublic function single_row( $item ) {\n\t\t\tparent::single_row( $item );\n\n\t\t\t/**\n\t\t\t * Fires after each specific row in the TGMPA Plugins list table.\n\t\t\t *\n\t\t\t * The dynamic portion of the hook name, `$item['slug']`, refers to the slug\n\t\t\t * for the plugin.\n\t\t\t *\n\t\t\t * @since 2.5.0\n\t\t\t */\n\t\t\tdo_action( \"tgmpa_after_plugin_row_{$item['slug']}\", $item['slug'], $item, $this->view_context );\n\t\t}\n\n\t\t/**\n\t\t * Show the upgrade notice below a plugin row if there is one.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @see /wp-admin/includes/update.php\n\t\t *\n\t\t * @param string $slug Plugin slug.\n\t\t * @param array  $item The information available in this table row.\n\t\t * @return null Return early if upgrade notice is empty.\n\t\t */\n\t\tpublic function wp_plugin_update_row( $slug, $item ) {\n\t\t\tif ( empty( $item['upgrade_notice'] ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\techo '\n\t\t\t\t<tr class=\"plugin-update-tr\">\n\t\t\t\t\t<td colspan=\"', absint( $this->get_column_count() ), '\" class=\"plugin-update colspanchange\">\n\t\t\t\t\t\t<div class=\"update-message\">',\n\t\t\t\t\t\t\tesc_html__( 'Upgrade message from the plugin author:', 'tgmpa' ),\n\t\t\t\t\t\t\t' <strong>', wp_kses_data( $item['upgrade_notice'] ), '</strong>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>';\n\t\t}\n\n\t\t/**\n\t\t * Extra controls to be displayed between bulk actions and pagination.\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @param string $which 'top' or 'bottom' table navigation.\n\t\t */\n\t\tpublic function extra_tablenav( $which ) {\n\t\t\tif ( 'bottom' === $which ) {\n\t\t\t\t$this->tgmpa->show_tgmpa_version();\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Defines the bulk actions for handling registered plugins.\n\t\t *\n\t\t * @since 2.2.0\n\t\t *\n\t\t * @return array $actions The bulk actions for the plugin install table.\n\t\t */\n\t\tpublic function get_bulk_actions() {\n\n\t\t\t$actions = array();\n\n\t\t\tif ( 'update' !== $this->view_context && 'activate' !== $this->view_context ) {\n\t\t\t\tif ( current_user_can( 'install_plugins' ) ) {\n\t\t\t\t\t$actions['tgmpa-bulk-install'] = __( 'Install', 'tgmpa' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( 'install' !== $this->view_context ) {\n\t\t\t\tif ( current_user_can( 'update_plugins' ) ) {\n\t\t\t\t\t$actions['tgmpa-bulk-update'] = __( 'Update', 'tgmpa' );\n\t\t\t\t}\n\t\t\t\tif ( current_user_can( 'activate_plugins' ) ) {\n\t\t\t\t\t$actions['tgmpa-bulk-activate'] = __( 'Activate', 'tgmpa' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $actions;\n\t\t}\n\n\t\t/**\n\t\t * Processes bulk installation and activation actions.\n\t\t *\n\t\t * The bulk installation process looks for the $_POST information and passes that\n\t\t * through if a user has to use WP_Filesystem to enter their credentials.\n\t\t *\n\t\t * @since 2.2.0\n\t\t */\n\t\tpublic function process_bulk_actions() {\n\t\t\t// Bulk installation process.\n\t\t\tif ( 'tgmpa-bulk-install' === $this->current_action() || 'tgmpa-bulk-update' === $this->current_action() ) {\n\n\t\t\t\tcheck_admin_referer( 'bulk-' . $this->_args['plural'] );\n\n\t\t\t\t$install_type = 'install';\n\t\t\t\tif ( 'tgmpa-bulk-update' === $this->current_action() ) {\n\t\t\t\t\t$install_type = 'update';\n\t\t\t\t}\n\n\t\t\t\t$plugins_to_install = array();\n\n\t\t\t\t// Did user actually select any plugins to install/update ?\n\t\t\t\tif ( empty( $_POST['plugin'] ) ) {\n\t\t\t\t\tif ( 'install' === $install_type ) {\n\t\t\t\t\t\t$message = __( 'No plugins were selected to be installed. No action taken.', 'tgmpa' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$message = __( 'No plugins were selected to be updated. No action taken.', 'tgmpa' );\n\t\t\t\t\t}\n\n\t\t\t\t\techo '<div id=\"message\" class=\"error\"><p>', esc_html( $message ), '</p></div>';\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif ( is_array( $_POST['plugin'] ) ) {\n\t\t\t\t\t$plugins_to_install = (array) $_POST['plugin'];\n\t\t\t\t} elseif ( is_string( $_POST['plugin'] ) ) {\n\t\t\t\t\t// Received via Filesystem page - un-flatten array (WP bug #19643).\n\t\t\t\t\t$plugins_to_install = explode( ',', $_POST['plugin'] );\n\t\t\t\t}\n\n\t\t\t\t// Sanitize the received input.\n\t\t\t\t$plugins_to_install = array_map( 'urldecode', $plugins_to_install );\n\t\t\t\t$plugins_to_install = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins_to_install );\n\n\t\t\t\t// Validate the received input.\n\t\t\t\tforeach ( $plugins_to_install as $key => $slug ) {\n\t\t\t\t\t// Check if the plugin was registered with TGMPA and remove if not.\n\t\t\t\t\tif ( ! isset( $this->tgmpa->plugins[ $slug ] ) ) {\n\t\t\t\t\t\tunset( $plugins_to_install[ $key ] );\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// For updates: make sure this is a plugin we *can* update (update available and WP version ok).\n\t\t\t\t\tif ( 'update' === $install_type && ( $this->tgmpa->is_plugin_installed( $slug ) && ( false === $this->tgmpa->does_plugin_have_update( $slug ) || ! $this->tgmpa->can_plugin_update( $slug ) ) ) ) {\n\t\t\t\t\t\tunset( $plugins_to_install[ $key ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// No need to proceed further if we have no plugins to handle.\n\t\t\t\tif ( empty( $plugins_to_install ) ) {\n\t\t\t\t\tif ( 'install' === $install_type ) {\n\t\t\t\t\t\t$message = __( 'No plugins are available to be installed at this time.', 'tgmpa' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$message = __( 'No plugins are available to be updated at this time.', 'tgmpa' );\n\t\t\t\t\t}\n\n\t\t\t\t\techo '<div id=\"message\" class=\"error\"><p>', esc_html( $message ), '</p></div>';\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Pass all necessary information if WP_Filesystem is needed.\n\t\t\t\t$url = wp_nonce_url(\n\t\t\t\t\t$this->tgmpa->get_tgmpa_url(),\n\t\t\t\t\t'bulk-' . $this->_args['plural']\n\t\t\t\t);\n\n\t\t\t\t// Give validated data back to $_POST which is the only place the filesystem looks for extra fields.\n\t\t\t\t$_POST['plugin'] = implode( ',', $plugins_to_install ); // Work around for WP bug #19643.\n\n\t\t\t\t$method = ''; // Leave blank so WP_Filesystem can populate it as necessary.\n\t\t\t\t$fields = array_keys( $_POST ); // Extra fields to pass to WP_Filesystem.\n\n\t\t\t\tif ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, $fields ) ) ) {\n\t\t\t\t\treturn true; // Stop the normal page form from displaying, credential request form will be shown.\n\t\t\t\t}\n\n\t\t\t\t// Now we have some credentials, setup WP_Filesystem.\n\t\t\t\tif ( ! WP_Filesystem( $creds ) ) {\n\t\t\t\t\t// Our credentials were no good, ask the user for them again.\n\t\t\t\t\trequest_filesystem_credentials( esc_url_raw( $url ), $method, true, false, $fields );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t/* If we arrive here, we have the filesystem */\n\n\t\t\t\t// Store all information in arrays since we are processing a bulk installation.\n\t\t\t\t$names      = array();\n\t\t\t\t$sources    = array(); // Needed for installs.\n\t\t\t\t$file_paths = array(); // Needed for upgrades.\n\t\t\t\t$to_inject  = array(); // Information to inject into the update_plugins transient.\n\n\t\t\t\t// Prepare the data for validated plugins for the install/upgrade.\n\t\t\t\tforeach ( $plugins_to_install as $slug ) {\n\t\t\t\t\t$name   = $this->tgmpa->plugins[ $slug ]['name'];\n\t\t\t\t\t$source = $this->tgmpa->get_download_url( $slug );\n\n\t\t\t\t\tif ( ! empty( $name ) && ! empty( $source ) ) {\n\t\t\t\t\t\t$names[] = $name;\n\n\t\t\t\t\t\tswitch ( $install_type ) {\n\n\t\t\t\t\t\t\tcase 'install':\n\t\t\t\t\t\t\t\t$sources[] = $source;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'update':\n\t\t\t\t\t\t\t\t$file_paths[]                 = $this->tgmpa->plugins[ $slug ]['file_path'];\n\t\t\t\t\t\t\t\t$to_inject[ $slug ]           = $this->tgmpa->plugins[ $slug ];\n\t\t\t\t\t\t\t\t$to_inject[ $slug ]['source'] = $source;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tunset( $slug, $name, $source );\n\n\t\t\t\t// Create a new instance of TGMPA_Bulk_Installer.\n\t\t\t\t$installer = new TGMPA_Bulk_Installer(\n\t\t\t\t\tnew TGMPA_Bulk_Installer_Skin(\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'url'          => esc_url_raw( $this->tgmpa->get_tgmpa_url() ),\n\t\t\t\t\t\t\t'nonce'        => 'bulk-' . $this->_args['plural'],\n\t\t\t\t\t\t\t'names'        => $names,\n\t\t\t\t\t\t\t'install_type' => $install_type,\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t\t// Wrap the install process with the appropriate HTML.\n\t\t\t\techo '<div class=\"tgmpa wrap\">',\n\t\t\t\t\t'<h2>', esc_html( get_admin_page_title() ), '</h2>';\n\n\t\t\t\t// Process the bulk installation submissions.\n\t\t\t\tadd_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1, 3 );\n\n\t\t\t\tif ( 'tgmpa-bulk-update' === $this->current_action() ) {\n\t\t\t\t\t// Inject our info into the update transient.\n\t\t\t\t\t$this->tgmpa->inject_update_info( $to_inject );\n\n\t\t\t\t\t$installer->bulk_upgrade( $file_paths );\n\t\t\t\t} else {\n\t\t\t\t\t$installer->bulk_install( $sources );\n\t\t\t\t}\n\n\t\t\t\tremove_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1, 3 );\n\n\t\t\t\techo '</div>';\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Bulk activation process.\n\t\t\tif ( 'tgmpa-bulk-activate' === $this->current_action() ) {\n\t\t\t\tcheck_admin_referer( 'bulk-' . $this->_args['plural'] );\n\n\t\t\t\t// Did user actually select any plugins to activate ?\n\t\t\t\tif ( empty( $_POST['plugin'] ) ) {\n\t\t\t\t\techo '<div id=\"message\" class=\"error\"><p>', esc_html__( 'No plugins were selected to be activated. No action taken.', 'tgmpa' ), '</p></div>';\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Grab plugin data from $_POST.\n\t\t\t\t$plugins = array();\n\t\t\t\tif ( isset( $_POST['plugin'] ) ) {\n\t\t\t\t\t$plugins = array_map( 'urldecode', (array) $_POST['plugin'] );\n\t\t\t\t\t$plugins = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins );\n\t\t\t\t}\n\n\t\t\t\t$plugins_to_activate = array();\n\t\t\t\t$plugin_names        = array();\n\n\t\t\t\t// Grab the file paths for the selected & inactive plugins from the registration array.\n\t\t\t\tforeach ( $plugins as $slug ) {\n\t\t\t\t\tif ( $this->tgmpa->can_plugin_activate( $slug ) ) {\n\t\t\t\t\t\t$plugins_to_activate[] = $this->tgmpa->plugins[ $slug ]['file_path'];\n\t\t\t\t\t\t$plugin_names[]        = $this->tgmpa->plugins[ $slug ]['name'];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tunset( $slug );\n\n\t\t\t\t// Return early if there are no plugins to activate.\n\t\t\t\tif ( empty( $plugins_to_activate ) ) {\n\t\t\t\t\techo '<div id=\"message\" class=\"error\"><p>', esc_html__( 'No plugins are available to be activated at this time.', 'tgmpa' ), '</p></div>';\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Now we are good to go - let's start activating plugins.\n\t\t\t\t$activate = activate_plugins( $plugins_to_activate );\n\n\t\t\t\tif ( is_wp_error( $activate ) ) {\n\t\t\t\t\techo '<div id=\"message\" class=\"error\"><p>', wp_kses_post( $activate->get_error_message() ), '</p></div>';\n\t\t\t\t} else {\n\t\t\t\t\t$count        = count( $plugin_names ); // Count so we can use _n function.\n\t\t\t\t\t$plugin_names = array_map( array( 'TGMPA_Utils', 'wrap_in_strong' ), $plugin_names );\n\t\t\t\t\t$last_plugin  = array_pop( $plugin_names ); // Pop off last name to prep for readability.\n\t\t\t\t\t$imploded     = empty( $plugin_names ) ? $last_plugin : ( implode( ', ', $plugin_names ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'tgmpa' ) . ' ' . $last_plugin );\n\n\t\t\t\t\tprintf( // WPCS: xss ok.\n\t\t\t\t\t\t'<div id=\"message\" class=\"updated\"><p>%1$s %2$s.</p></div>',\n\t\t\t\t\t\tesc_html( _n( 'The following plugin was activated successfully:', 'The following plugins were activated successfully:', $count, 'tgmpa' ) ),\n\t\t\t\t\t\t$imploded\n\t\t\t\t\t);\n\n\t\t\t\t\t// Update recently activated plugins option.\n\t\t\t\t\t$recent = (array) get_option( 'recently_activated' );\n\t\t\t\t\tforeach ( $plugins_to_activate as $plugin => $time ) {\n\t\t\t\t\t\tif ( isset( $recent[ $plugin ] ) ) {\n\t\t\t\t\t\t\tunset( $recent[ $plugin ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tupdate_option( 'recently_activated', $recent );\n\t\t\t\t}\n\n\t\t\t\tunset( $_POST ); // Reset the $_POST variable in case user wants to perform one action after another.\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t/**\n\t\t * Prepares all of our information to be outputted into a usable table.\n\t\t *\n\t\t * @since 2.2.0\n\t\t */\n\t\tpublic function prepare_items() {\n\t\t\t$columns               = $this->get_columns(); // Get all necessary column information.\n\t\t\t$hidden                = array(); // No columns to hide, but we must set as an array.\n\t\t\t$sortable              = array(); // No reason to make sortable columns.\n\t\t\t$primary               = $this->get_primary_column_name(); // Column which has the row actions.\n\t\t\t$this->_column_headers = array( $columns, $hidden, $sortable, $primary ); // Get all necessary column headers.\n\n\t\t\t// Process our bulk activations here.\n\t\t\tif ( 'tgmpa-bulk-activate' === $this->current_action() ) {\n\t\t\t\t$this->process_bulk_actions();\n\t\t\t}\n\n\t\t\t// Store all of our plugin data into $items array so WP_List_Table can use it.\n\t\t\t$this->items = apply_filters( 'tgmpa_table_data_items', $this->_gather_plugin_data() );\n\t\t}\n\n\t\t/* *********** DEPRECATED METHODS *********** */\n\n\t\t/**\n\t\t * Retrieve plugin data, given the plugin name.\n\t\t *\n\t\t * @since      2.2.0\n\t\t * @deprecated 2.5.0 use {@see TGM_Plugin_Activation::_get_plugin_data_from_name()} instead.\n\t\t * @see        TGM_Plugin_Activation::_get_plugin_data_from_name()\n\t\t *\n\t\t * @param string $name Name of the plugin, as it was registered.\n\t\t * @param string $data Optional. Array key of plugin data to return. Default is slug.\n\t\t * @return string|boolean Plugin slug if found, false otherwise.\n\t\t */\n\t\tprotected function _get_plugin_data_from_name( $name, $data = 'slug' ) {\n\t\t\t_deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'TGM_Plugin_Activation::_get_plugin_data_from_name()' );\n\n\t\t\treturn $this->tgmpa->_get_plugin_data_from_name( $name, $data );\n\t\t}\n\t}\n}\n\n\nif ( ! class_exists( 'TGM_Bulk_Installer' ) ) {\n\n\t/**\n\t * Hack: Prevent TGMPA v2.4.1- bulk installer class from being loaded if 2.4.1- is loaded after 2.5+.\n\t */\n\tclass TGM_Bulk_Installer {\n\t}\n}\nif ( ! class_exists( 'TGM_Bulk_Installer_Skin' ) ) {\n\n\t/**\n\t * Hack: Prevent TGMPA v2.4.1- bulk installer skin class from being loaded if 2.4.1- is loaded after 2.5+.\n\t */\n\tclass TGM_Bulk_Installer_Skin {\n\t}\n}\n\n/**\n * The WP_Upgrader file isn't always available. If it isn't available,\n * we load it here.\n *\n * We check to make sure no action or activation keys are set so that WordPress\n * does not try to re-include the class when processing upgrades or installs outside\n * of the class.\n *\n * @since 2.2.0\n */\nadd_action( 'admin_init', 'tgmpa_load_bulk_installer' );\nif ( ! function_exists( 'tgmpa_load_bulk_installer' ) ) {\n\t/**\n\t * Load bulk installer\n\t */\n\tfunction tgmpa_load_bulk_installer() {\n\t\t// Silently fail if 2.5+ is loaded *after* an older version.\n\t\tif ( ! isset( $GLOBALS['tgmpa'] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get TGMPA class instance.\n\t\t$tgmpa_instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) );\n\n\t\tif ( isset( $_GET['page'] ) && $tgmpa_instance->menu === $_GET['page'] ) {\n\t\t\tif ( ! class_exists( 'Plugin_Upgrader', false ) ) {\n\t\t\t\trequire_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';\n\t\t\t}\n\n\t\t\tif ( ! class_exists( 'TGMPA_Bulk_Installer' ) ) {\n\n\t\t\t\t/**\n\t\t\t\t * Installer class to handle bulk plugin installations.\n\t\t\t\t *\n\t\t\t\t * Extends WP_Upgrader and customizes to suit the installation of multiple\n\t\t\t\t * plugins.\n\t\t\t\t *\n\t\t\t\t * @since 2.2.0\n\t\t\t\t *\n\t\t\t\t * @internal Since 2.5.0 the class is an extension of Plugin_Upgrader rather than WP_Upgrader\n\t\t\t\t * @internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer to TGMPA_Bulk_Installer.\n\t\t\t\t *           This was done to prevent backward compatibility issues with v2.3.6.\n\t\t\t\t *\n\t\t\t\t * @package TGM-Plugin-Activation\n\t\t\t\t * @author  Thomas Griffin\n\t\t\t\t * @author  Gary Jones\n\t\t\t\t */\n\t\t\t\tclass TGMPA_Bulk_Installer extends Plugin_Upgrader {\n\t\t\t\t\t/**\n\t\t\t\t\t * Holds result of bulk plugin installation.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @var string\n\t\t\t\t\t */\n\t\t\t\t\tpublic $result;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Flag to check if bulk installation is occurring or not.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @var boolean\n\t\t\t\t\t */\n\t\t\t\t\tpublic $bulk = false;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * TGMPA instance\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.5.0\n\t\t\t\t\t *\n\t\t\t\t\t * @var object\n\t\t\t\t\t */\n\t\t\t\t\tprotected $tgmpa;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Whether or not the destination directory needs to be cleared ( = on update).\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.5.0\n\t\t\t\t\t *\n\t\t\t\t\t * @var bool\n\t\t\t\t\t */\n\t\t\t\t\tprotected $clear_destination = false;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * References parent constructor and sets defaults for class.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @param \\Bulk_Upgrader_Skin|null $skin Installer skin.\n\t\t\t\t\t */\n\t\t\t\t\tpublic function __construct( $skin = null ) {\n\t\t\t\t\t\t// Get TGMPA class instance.\n\t\t\t\t\t\t$this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) );\n\n\t\t\t\t\t\tparent::__construct( $skin );\n\n\t\t\t\t\t\tif ( isset( $this->skin->options['install_type'] ) && 'update' === $this->skin->options['install_type'] ) {\n\t\t\t\t\t\t\t$this->clear_destination = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( $this->tgmpa->is_automatic ) {\n\t\t\t\t\t\t\t$this->activate_strings();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tadd_action( 'upgrader_process_complete', array( $this->tgmpa, 'populate_file_path' ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Sets the correct activation strings for the installer skin to use.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t */\n\t\t\t\t\tpublic function activate_strings() {\n\t\t\t\t\t\t$this->strings['activation_failed']  = __( 'Plugin activation failed.', 'tgmpa' );\n\t\t\t\t\t\t$this->strings['activation_success'] = __( 'Plugin activated successfully.', 'tgmpa' );\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Performs the actual installation of each plugin.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @see WP_Upgrader::run()\n\t\t\t\t\t *\n\t\t\t\t\t * @param array $options The installation config options.\n\t\t\t\t\t * @return null|array Return early if error, array of installation data on success.\n\t\t\t\t\t */\n\t\t\t\t\tpublic function run( $options ) {\n\t\t\t\t\t\t$result = parent::run( $options );\n\n\t\t\t\t\t\t// Reset the strings in case we changed one during automatic activation.\n\t\t\t\t\t\tif ( $this->tgmpa->is_automatic ) {\n\t\t\t\t\t\t\tif ( 'update' === $this->skin->options['install_type'] ) {\n\t\t\t\t\t\t\t\t$this->upgrade_strings();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$this->install_strings();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn $result;\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Processes the bulk installation of plugins.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @internal This is basically a near identical copy of the WP Core Plugin_Upgrader::bulk_upgrade()\n\t\t\t\t\t * method, with minor adjustments to deal with new installs instead of upgrades.\n\t\t\t\t\t * For ease of future synchronizations, the adjustments are clearly commented, but no other\n\t\t\t\t\t * comments are added. Code style has been made to comply.\n\t\t\t\t\t *\n\t\t\t\t\t * @see Plugin_Upgrader::bulk_upgrade()\n\t\t\t\t\t * @see https://core.trac.wordpress.org/browser/tags/4.2.1/src/wp-admin/includes/class-wp-upgrader.php#L838\n\t\t\t\t\t *\n\t\t\t\t\t * @param array $plugins The plugin sources needed for installation.\n\t\t\t\t\t * @param array $args    Arbitrary passed extra arguments.\n\t\t\t\t\t * @return string|bool Install confirmation messages on success, false on failure.\n\t\t\t\t\t */\n\t\t\t\t\tpublic function bulk_install( $plugins, $args = array() ) {\n\t\t\t\t\t\t// [TGMPA + ] Hook auto-activation in.\n\t\t\t\t\t\tadd_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 );\n\n\t\t\t\t\t\t$defaults    = array(\n\t\t\t\t\t\t\t'clear_update_cache' => true,\n\t\t\t\t\t\t);\n\t\t\t\t\t\t$parsed_args = wp_parse_args( $args, $defaults );\n\n\t\t\t\t\t\t$this->init();\n\t\t\t\t\t\t$this->bulk = true;\n\n\t\t\t\t\t\t$this->install_strings(); // [TGMPA + ] adjusted.\n\n\t\t\t\t\t\t/* [TGMPA - ] $current = get_site_transient( 'update_plugins' ); */\n\n\t\t\t\t\t\t/* [TGMPA - ] add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4); */\n\n\t\t\t\t\t\t$this->skin->header();\n\n\t\t\t\t\t\t// Connect to the Filesystem first.\n\t\t\t\t\t\t$res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) );\n\t\t\t\t\t\tif ( ! $res ) {\n\t\t\t\t\t\t\t$this->skin->footer();\n\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t$this->skin->bulk_header();\n\n\t\t\t\t\t\t// Only start maintenance mode if:\n\t\t\t\t\t\t// - running Multisite and there are one or more plugins specified, OR\n\t\t\t\t\t\t// - a plugin with an update available is currently active.\n\t\t\t\t\t\t// @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible.\n\t\t\t\t\t\t$maintenance = ( is_multisite() && ! empty( $plugins ) );\n\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t[TGMPA - ]\n\t\t\t\t\t\tforeach ( $plugins as $plugin )\n\t\t\t\t\t\t\t$maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin] ) );\n\t\t\t\t\t\t*/\n\t\t\t\t\t\tif ( $maintenance ) {\n\t\t\t\t\t\t\t$this->maintenance_mode( true );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t$results = array();\n\n\t\t\t\t\t\t$this->update_count   = count( $plugins );\n\t\t\t\t\t\t$this->update_current = 0;\n\t\t\t\t\t\tforeach ( $plugins as $plugin ) {\n\t\t\t\t\t\t\t$this->update_current++;\n\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t[TGMPA - ]\n\t\t\t\t\t\t\t$this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true);\n\n\t\t\t\t\t\t\tif ( !isset( $current->response[ $plugin ] ) ) {\n\t\t\t\t\t\t\t\t$this->skin->set_result('up_to_date');\n\t\t\t\t\t\t\t\t$this->skin->before();\n\t\t\t\t\t\t\t\t$this->skin->feedback('up_to_date');\n\t\t\t\t\t\t\t\t$this->skin->after();\n\t\t\t\t\t\t\t\t$results[$plugin] = true;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Get the URL to the zip file\n\t\t\t\t\t\t\t$r = $current->response[ $plugin ];\n\n\t\t\t\t\t\t\t$this->skin->plugin_active = is_plugin_active($plugin);\n\t\t\t\t\t\t\t*/\n\n\t\t\t\t\t\t\t$result = $this->run( array(\n\t\t\t\t\t\t\t\t'package'           => $plugin, // [TGMPA + ] adjusted.\n\t\t\t\t\t\t\t\t'destination'       => WP_PLUGIN_DIR,\n\t\t\t\t\t\t\t\t'clear_destination' => false, // [TGMPA + ] adjusted.\n\t\t\t\t\t\t\t\t'clear_working'     => true,\n\t\t\t\t\t\t\t\t'is_multi'          => true,\n\t\t\t\t\t\t\t\t'hook_extra'        => array(\n\t\t\t\t\t\t\t\t\t'plugin' => $plugin,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t) );\n\n\t\t\t\t\t\t\t$results[ $plugin ] = $this->result;\n\n\t\t\t\t\t\t\t// Prevent credentials auth screen from displaying multiple times.\n\t\t\t\t\t\t\tif ( false === $result ) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} //end foreach $plugins\n\n\t\t\t\t\t\t$this->maintenance_mode( false );\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Fires when the bulk upgrader process is complete.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * @since WP 3.6.0 / TGMPA 2.5.0\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * @param Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might\n\t\t\t\t\t\t *                              be a Theme_Upgrader or Core_Upgrade instance.\n\t\t\t\t\t\t * @param array           $data {\n\t\t\t\t\t\t *     Array of bulk item update data.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t *     @type string $action   Type of action. Default 'update'.\n\t\t\t\t\t\t *     @type string $type     Type of update process. Accepts 'plugin', 'theme', or 'core'.\n\t\t\t\t\t\t *     @type bool   $bulk     Whether the update process is a bulk update. Default true.\n\t\t\t\t\t\t *     @type array  $packages Array of plugin, theme, or core packages to update.\n\t\t\t\t\t\t * }\n\t\t\t\t\t\t */\n\t\t\t\t\t\tdo_action( 'upgrader_process_complete', $this, array(\n\t\t\t\t\t\t\t'action'  => 'install', // [TGMPA + ] adjusted.\n\t\t\t\t\t\t\t'type'    => 'plugin',\n\t\t\t\t\t\t\t'bulk'    => true,\n\t\t\t\t\t\t\t'plugins' => $plugins,\n\t\t\t\t\t\t) );\n\n\t\t\t\t\t\t$this->skin->bulk_footer();\n\n\t\t\t\t\t\t$this->skin->footer();\n\n\t\t\t\t\t\t// Cleanup our hooks, in case something else does a upgrade on this connection.\n\t\t\t\t\t\t/* [TGMPA - ] remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin')); */\n\n\t\t\t\t\t\t// [TGMPA + ] Remove our auto-activation hook.\n\t\t\t\t\t\tremove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 );\n\n\t\t\t\t\t\t// Force refresh of plugin update information.\n\t\t\t\t\t\twp_clean_plugins_cache( $parsed_args['clear_update_cache'] );\n\n\t\t\t\t\t\treturn $results;\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Handle a bulk upgrade request.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.5.0\n\t\t\t\t\t *\n\t\t\t\t\t * @see Plugin_Upgrader::bulk_upgrade()\n\t\t\t\t\t *\n\t\t\t\t\t * @param array $plugins The local WP file_path's of the plugins which should be upgraded.\n\t\t\t\t\t * @param array $args    Arbitrary passed extra arguments.\n\t\t\t\t\t * @return string|bool Install confirmation messages on success, false on failure.\n\t\t\t\t\t */\n\t\t\t\t\tpublic function bulk_upgrade( $plugins, $args = array() ) {\n\n\t\t\t\t\t\tadd_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 );\n\n\t\t\t\t\t\t$result = parent::bulk_upgrade( $plugins, $args );\n\n\t\t\t\t\t\tremove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 );\n\n\t\t\t\t\t\treturn $result;\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Abuse a filter to auto-activate plugins after installation.\n\t\t\t\t\t *\n\t\t\t\t\t * Hooked into the 'upgrader_post_install' filter hook.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.5.0\n\t\t\t\t\t *\n\t\t\t\t\t * @param bool $bool The value we need to give back (true).\n\t\t\t\t\t * @return bool\n\t\t\t\t\t */\n\t\t\t\t\tpublic function auto_activate( $bool ) {\n\t\t\t\t\t\t// Only process the activation of installed plugins if the automatic flag is set to true.\n\t\t\t\t\t\tif ( $this->tgmpa->is_automatic ) {\n\t\t\t\t\t\t\t// Flush plugins cache so the headers of the newly installed plugins will be read correctly.\n\t\t\t\t\t\t\twp_clean_plugins_cache();\n\n\t\t\t\t\t\t\t// Get the installed plugin file.\n\t\t\t\t\t\t\t$plugin_info = $this->plugin_info();\n\n\t\t\t\t\t\t\t// Don't try to activate on upgrade of active plugin as WP will do this already.\n\t\t\t\t\t\t\tif ( ! is_plugin_active( $plugin_info ) ) {\n\t\t\t\t\t\t\t\t$activate = activate_plugin( $plugin_info );\n\n\t\t\t\t\t\t\t\t// Adjust the success string based on the activation result.\n\t\t\t\t\t\t\t\t$this->strings['process_success'] = $this->strings['process_success'] . \"<br />\\n\";\n\n\t\t\t\t\t\t\t\tif ( is_wp_error( $activate ) ) {\n\t\t\t\t\t\t\t\t\t$this->skin->error( $activate );\n\t\t\t\t\t\t\t\t\t$this->strings['process_success'] .= $this->strings['activation_failed'];\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$this->strings['process_success'] .= $this->strings['activation_success'];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn $bool;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( ! class_exists( 'TGMPA_Bulk_Installer_Skin' ) ) {\n\n\t\t\t\t/**\n\t\t\t\t * Installer skin to set strings for the bulk plugin installations..\n\t\t\t\t *\n\t\t\t\t * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple\n\t\t\t\t * plugins.\n\t\t\t\t *\n\t\t\t\t * @since 2.2.0\n\t\t\t\t *\n\t\t\t\t * @internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer_Skin to\n\t\t\t\t *           TGMPA_Bulk_Installer_Skin.\n\t\t\t\t *           This was done to prevent backward compatibility issues with v2.3.6.\n\t\t\t\t *\n\t\t\t\t * @see https://core.trac.wordpress.org/browser/trunk/src/wp-admin/includes/class-wp-upgrader-skins.php\n\t\t\t\t *\n\t\t\t\t * @package TGM-Plugin-Activation\n\t\t\t\t * @author  Thomas Griffin\n\t\t\t\t * @author  Gary Jones\n\t\t\t\t */\n\t\t\t\tclass TGMPA_Bulk_Installer_Skin extends Bulk_Upgrader_Skin {\n\t\t\t\t\t/**\n\t\t\t\t\t * Holds plugin info for each individual plugin installation.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @var array\n\t\t\t\t\t */\n\t\t\t\t\tpublic $plugin_info = array();\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Holds names of plugins that are undergoing bulk installations.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @var array\n\t\t\t\t\t */\n\t\t\t\t\tpublic $plugin_names = array();\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Integer to use for iteration through each plugin installation.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @var integer\n\t\t\t\t\t */\n\t\t\t\t\tpublic $i = 0;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * TGMPA instance\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.5.0\n\t\t\t\t\t *\n\t\t\t\t\t * @var object\n\t\t\t\t\t */\n\t\t\t\t\tprotected $tgmpa;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Constructor. Parses default args with new ones and extracts them for use.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @param array $args Arguments to pass for use within the class.\n\t\t\t\t\t */\n\t\t\t\t\tpublic function __construct( $args = array() ) {\n\t\t\t\t\t\t// Get TGMPA class instance.\n\t\t\t\t\t\t$this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) );\n\n\t\t\t\t\t\t// Parse default and new args.\n\t\t\t\t\t\t$defaults = array(\n\t\t\t\t\t\t\t'url'          => '',\n\t\t\t\t\t\t\t'nonce'        => '',\n\t\t\t\t\t\t\t'names'        => array(),\n\t\t\t\t\t\t\t'install_type' => 'install',\n\t\t\t\t\t\t);\n\t\t\t\t\t\t$args     = wp_parse_args( $args, $defaults );\n\n\t\t\t\t\t\t// Set plugin names to $this->plugin_names property.\n\t\t\t\t\t\t$this->plugin_names = $args['names'];\n\n\t\t\t\t\t\t// Extract the new args.\n\t\t\t\t\t\tparent::__construct( $args );\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Sets install skin strings for each individual plugin.\n\t\t\t\t\t *\n\t\t\t\t\t * Checks to see if the automatic activation flag is set and uses the\n\t\t\t\t\t * the proper strings accordingly.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t */\n\t\t\t\t\tpublic function add_strings() {\n\t\t\t\t\t\tif ( 'update' === $this->options['install_type'] ) {\n\t\t\t\t\t\t\tparent::add_strings();\n\t\t\t\t\t\t\t$this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)', 'tgmpa' );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: <strong>%2$s</strong>.', 'tgmpa' );\n\t\t\t\t\t\t\t$this->upgrader->strings['skin_update_failed']       = __( 'The installation of %1$s failed.', 'tgmpa' );\n\n\t\t\t\t\t\t\tif ( $this->tgmpa->is_automatic ) {\n\t\t\t\t\t\t\t\t// Automatic activation strings.\n\t\t\t\t\t\t\t\t$this->upgrader->strings['skin_upgrade_start']        = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' );\n\t\t\t\t\t\t\t\t$this->upgrader->strings['skin_update_successful']    = __( '%1$s installed and activated successfully.', 'tgmpa' ) . ' <a href=\"#\" class=\"hide-if-no-js\" onclick=\"%2$s\"><span>' . esc_html__( 'Show Details', 'tgmpa' ) . '</span><span class=\"hidden\">' . esc_html__( 'Hide Details', 'tgmpa' ) . '</span>.</a>';\n\t\t\t\t\t\t\t\t$this->upgrader->strings['skin_upgrade_end']          = __( 'All installations and activations have been completed.', 'tgmpa' );\n\t\t\t\t\t\t\t\t$this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', 'tgmpa' );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Default installation strings.\n\t\t\t\t\t\t\t\t$this->upgrader->strings['skin_upgrade_start']        = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' );\n\t\t\t\t\t\t\t\t$this->upgrader->strings['skin_update_successful']    = esc_html__( '%1$s installed successfully.', 'tgmpa' ) . ' <a href=\"#\" class=\"hide-if-no-js\" onclick=\"%2$s\"><span>' . esc_html__( 'Show Details', 'tgmpa' ) . '</span><span class=\"hidden\">' . esc_html__( 'Hide Details', 'tgmpa' ) . '</span>.</a>';\n\t\t\t\t\t\t\t\t$this->upgrader->strings['skin_upgrade_end']          = __( 'All installations have been completed.', 'tgmpa' );\n\t\t\t\t\t\t\t\t$this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', 'tgmpa' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Outputs the header strings and necessary JS before each plugin installation.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @param string $title Unused in this implementation.\n\t\t\t\t\t */\n\t\t\t\t\tpublic function before( $title = '' ) {\n\t\t\t\t\t\tif ( empty( $title ) ) {\n\t\t\t\t\t\t\t$title = esc_html( $this->plugin_names[ $this->i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparent::before( $title );\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Outputs the footer strings and necessary JS after each plugin installation.\n\t\t\t\t\t *\n\t\t\t\t\t * Checks for any errors and outputs them if they exist, else output\n\t\t\t\t\t * success strings.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t *\n\t\t\t\t\t * @param string $title Unused in this implementation.\n\t\t\t\t\t */\n\t\t\t\t\tpublic function after( $title = '' ) {\n\t\t\t\t\t\tif ( empty( $title ) ) {\n\t\t\t\t\t\t\t$title = esc_html( $this->plugin_names[ $this->i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparent::after( $title );\n\n\t\t\t\t\t\t$this->i++;\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Outputs links after bulk plugin installation is complete.\n\t\t\t\t\t *\n\t\t\t\t\t * @since 2.2.0\n\t\t\t\t\t */\n\t\t\t\t\tpublic function bulk_footer() {\n\t\t\t\t\t\t// Serve up the string to say installations (and possibly activations) are complete.\n\t\t\t\t\t\tparent::bulk_footer();\n\n\t\t\t\t\t\t// Flush plugins cache so we can make sure that the installed plugins list is always up to date.\n\t\t\t\t\t\twp_clean_plugins_cache();\n\n\t\t\t\t\t\t$this->tgmpa->show_tgmpa_version();\n\n\t\t\t\t\t\t// Display message based on if all plugins are now active or not.\n\t\t\t\t\t\t$update_actions = array();\n\n\t\t\t\t\t\tif ( $this->tgmpa->is_tgmpa_complete() ) {\n\t\t\t\t\t\t\t// All plugins are active, so we display the complete string and hide the menu to protect users.\n\t\t\t\t\t\t\techo '<style type=\"text/css\">#adminmenu .wp-submenu li.current { display: none !important; }</style>';\n\t\t\t\t\t\t\t$update_actions['dashboard'] = sprintf(\n\t\t\t\t\t\t\t\tesc_html( $this->tgmpa->strings['complete'] ),\n\t\t\t\t\t\t\t\t'<a href=\"' . esc_url( self_admin_url() ) . '\">' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '</a>'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$update_actions['tgmpa_page'] = '<a href=\"' . esc_url( $this->tgmpa->get_tgmpa_url() ) . '\" target=\"_parent\">' . esc_html( $this->tgmpa->strings['return'] ) . '</a>';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Filter the list of action links available following bulk plugin installs/updates.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * @since 2.5.0\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * @param array $update_actions Array of plugin action links.\n\t\t\t\t\t\t * @param array $plugin_info    Array of information for the last-handled plugin.\n\t\t\t\t\t\t */\n\t\t\t\t\t\t$update_actions = apply_filters( 'tgmpa_update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );\n\n\t\t\t\t\t\tif ( ! empty( $update_actions ) ) {\n\t\t\t\t\t\t\t$this->feedback( implode( ' | ', (array) $update_actions ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t/* *********** DEPRECATED METHODS *********** */\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Flush header output buffer.\n\t\t\t\t\t *\n\t\t\t\t\t * @since      2.2.0\n\t\t\t\t\t * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead\n\t\t\t\t\t * @see        Bulk_Upgrader_Skin::flush_output()\n\t\t\t\t\t */\n\t\t\t\t\tpublic function before_flush_output() {\n\t\t\t\t\t\t_deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' );\n\t\t\t\t\t\t$this->flush_output();\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Flush footer output buffer and iterate $this->i to make sure the\n\t\t\t\t\t * installation strings reference the correct plugin.\n\t\t\t\t\t *\n\t\t\t\t\t * @since      2.2.0\n\t\t\t\t\t * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead\n\t\t\t\t\t * @see        Bulk_Upgrader_Skin::flush_output()\n\t\t\t\t\t */\n\t\t\t\t\tpublic function after_flush_output() {\n\t\t\t\t\t\t_deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' );\n\t\t\t\t\t\t$this->flush_output();\n\t\t\t\t\t\t$this->i++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nif ( ! class_exists( 'TGMPA_Utils' ) ) {\n\n\t/**\n\t * Generic utilities for TGMPA.\n\t *\n\t * All methods are static, poor-dev name-spacing class wrapper.\n\t *\n\t * Class was called TGM_Utils in 2.5.0 but renamed TGMPA_Utils in 2.5.1 as this was conflicting with Soliloquy.\n\t *\n\t * @since 2.5.0\n\t *\n\t * @package TGM-Plugin-Activation\n\t * @author  Juliette Reinders Folmer\n\t */\n\tclass TGMPA_Utils {\n\t\t/**\n\t\t * Whether the PHP filter extension is enabled.\n\t\t *\n\t\t * @see http://php.net/book.filter\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @static\n\t\t *\n\t\t * @var bool $has_filters True is the extension is enabled.\n\t\t */\n\t\tpublic static $has_filters;\n\n\t\t/**\n\t\t * Wrap an arbitrary string in <em> tags. Meant to be used in combination with array_map().\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @static\n\t\t *\n\t\t * @param string $string Text to be wrapped.\n\t\t * @return string\n\t\t */\n\t\tpublic static function wrap_in_em( $string ) {\n\t\t\treturn '<em>' . wp_kses_post( $string ) . '</em>';\n\t\t}\n\n\t\t/**\n\t\t * Wrap an arbitrary string in <strong> tags. Meant to be used in combination with array_map().\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @static\n\t\t *\n\t\t * @param string $string Text to be wrapped.\n\t\t * @return string\n\t\t */\n\t\tpublic static function wrap_in_strong( $string ) {\n\t\t\treturn '<strong>' . wp_kses_post( $string ) . '</strong>';\n\t\t}\n\n\t\t/**\n\t\t * Helper function: Validate a value as boolean\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @static\n\t\t *\n\t\t * @param mixed $value Arbitrary value.\n\t\t * @return bool\n\t\t */\n\t\tpublic static function validate_bool( $value ) {\n\t\t\tif ( ! isset( self::$has_filters ) ) {\n\t\t\t\tself::$has_filters = extension_loaded( 'filter' );\n\t\t\t}\n\n\t\t\tif ( self::$has_filters ) {\n\t\t\t\treturn filter_var( $value, FILTER_VALIDATE_BOOLEAN );\n\t\t\t} else {\n\t\t\t\treturn self::emulate_filter_bool( $value );\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Helper function: Cast a value to bool\n\t\t *\n\t\t * @since 2.5.0\n\t\t *\n\t\t * @static\n\t\t *\n\t\t * @param mixed $value Value to cast.\n\t\t * @return bool\n\t\t */\n\t\tprotected static function emulate_filter_bool( $value ) {\n\t\t\t// @codingStandardsIgnoreStart\n\t\t\tstatic $true  = array(\n\t\t\t\t'1',\n\t\t\t\t'true', 'True', 'TRUE',\n\t\t\t\t'y', 'Y',\n\t\t\t\t'yes', 'Yes', 'YES',\n\t\t\t\t'on', 'On', 'ON',\n\t\t\t);\n\t\t\tstatic $false = array(\n\t\t\t\t'0',\n\t\t\t\t'false', 'False', 'FALSE',\n\t\t\t\t'n', 'N',\n\t\t\t\t'no', 'No', 'NO',\n\t\t\t\t'off', 'Off', 'OFF',\n\t\t\t);\n\t\t\t// @codingStandardsIgnoreEnd\n\n\t\t\tif ( is_bool( $value ) ) {\n\t\t\t\treturn $value;\n\t\t\t} else if ( is_int( $value ) && ( 0 === $value || 1 === $value ) ) {\n\t\t\t\treturn (bool) $value;\n\t\t\t} else if ( ( is_float( $value ) && ! is_nan( $value ) ) && ( (float) 0 === $value || (float) 1 === $value ) ) {\n\t\t\t\treturn (bool) $value;\n\t\t\t} else if ( is_string( $value ) ) {\n\t\t\t\t$value = trim( $value );\n\t\t\t\tif ( in_array( $value, $true, true ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else if ( in_array( $value, $false, true ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t} // End of class TGMPA_Utils\n} // End of class_exists wrapper\n"
  },
  {
    "path": "admin/includes/load_admin.php",
    "content": "<?php\n/**\n * AH Stripe\n *\n * @package   Editus_Admin\n * @author    Nick Haskins <nick@aesopinteractive.com>\n * @license   GPL-2.0+\n * @link      http://aesopinteractive.com\n * @copyright 2015 Aesopinteractive LLC\n */\nnamespace lasso_admin;\n\nuse lasso_public_facing\\lasso;\n\nclass load_admin {\n\n\t/**\n\t * Instance of this class.\n\t *\n\t * @since    0.0.1\n\t *\n\t * @var      object\n\t */\n\tprotected static $instance = null;\n\n\t/**\n\t * Slug of the plugin screen.\n\t *\n\t * @since    0.0.1\n\t *\n\t * @var      string\n\t */\n\tprotected $plugin_screen_hook_suffix = null;\n\n\t/**\n\t * Initialize the plugin by loading admin scripts & styles and adding a\n\t * settings page and menu.\n\t *\n\t * @since     0.0.1\n\t */\n\tprivate function __construct() {\n\n\t\t$plugin = lasso::get_instance();\n\t\t$this->plugin_slug = $plugin->get_plugin_slug();\n\n\t\tadd_action( 'admin_head',  \t\t\tarray( $this, 'admin_assets' ) );\n\t\tadd_action( 'admin_notices', \t\tarray( $this, 'license_nag' ) );\n\t\tadd_action( 'admin_head', \t\t\tarray( $this, 'dismiss_nag' ) );\n\t\tadd_filter( 'plugin_row_meta',    \tarray( $this, 'plugin_meta' ), 10, 2 );\n\n\t\tif ( !class_exists( 'EDD_SL_Plugin_Updater' ) ) {\n\t\t\tinclude LASSO_DIR.'admin/includes/EDD_SL_Plugin_Updater.php';\n\t\t}\n\n\t\tif ( !class_exists( 'TGM_Plugin_Activation' ) ) {\n\t\t\tinclude LASSO_DIR.'admin/includes/class-tgm-plugin-activation.php';\n\t\t}\n\n\t\tnew menus\\welcome();\n\t\tnew menus\\settings();\n\n\t\tif ( !defined( 'LASSO_AGENCY_MODE' ) ) {\n\t\t\tnew menus\\license();\n\t\t}\n\n\t}\n\n\t/**\n\t * Return an instance of this class.\n\t *\n\t * @since     0.0.1\n\t *\n\t * @return    object    A single instance of this class.\n\t */\n\tpublic static function get_instance() {\n\n\t\t// If the single instance hasn't been set, set it now.\n\t\tif ( null == self::$instance ) {\n\t\t\tself::$instance = new self;\n\t\t}\n\n\t\treturn self::$instance;\n\t}\n\n\t/**\n\t * Load some assets for the appropriate pages in admin\n\t *\n\t * @since 1.0\n\t */\n\tpublic function admin_assets() {\n\n\t\t$screen = get_current_screen();\n\n\t\t$pages = array(\n\t\t\t'settings_page_lasso-editor-settings',\n\t\t\t'settings_page_lasso-editor-settings-network',\n\t\t\t'dashboard_page_lasso-welcome-screen'\n\t\t);\n\n\t\tforeach ( $pages as $page ) {\n\t\t\twp_enqueue_media();\n            wp_enqueue_style( 'wp-color-picker');\n            wp_enqueue_script( 'wp-color-picker');\n\t\t\n\t\t\twp_enqueue_script( 'lasso-editor-settings-script', LASSO_URL.'/admin/assets/js/lasso-editor-settings.js', array( 'jquery','wp-color-picker' ), LASSO_VERSION, true );\n\t\t\twp_enqueue_style( 'lasso-editor-settings-style', LASSO_URL.'/admin/assets/css/lasso-editor-settings.css', LASSO_VERSION );\n\t\t}\n\t}\n\n\t/**\n\t * Add some custom links to the plugins.php page\n\t *\n\t * @since 0.8.8\n\t * @param unknown $links array array of new links\n\t * @param unknown $file\n\t *\n\t * @return array new array of links for our plugin listing on plugins.php\n\t */\n\tpublic function plugin_meta( $links, $file ) {\n\n\t\tif ( strpos( $file, 'lasso.php' ) !== false && !defined( 'LASSO_AGENCY_MODE' ) ) {\n\n\t\t\t$new_links = array(\n\t\t\t\t'<a href=\"http://edituswp.com/help\" target=\"_blank\">Help</a>'\n\t\t\t);\n\n\t\t\t$links = array_merge( $links, $new_links );\n\t\t}\n\n\t\treturn $links;\n\t}\n\n\t/**\n\t*\tAdds an admin notice reminding the user if their license key has not been saved\n\t*\n\t*\t@since 0.9.7\n\t*\t@todo make dismissible\n\t*/\n\tpublic function license_nag(){\n\n\t\t$screen \t= get_current_screen();\n\t\t$welcome    = 'toplevel_page_lasso-editor' == $screen->id;\n\t\t$license  \t= get_option( 'lasso_license_key' );\n\t\t$status   \t= get_option( 'lasso_license_status' );\n\n\t\t$message_empty    = apply_filters('lasso_empty_license_message','Your license key for support and automatic updates for Editus is missing!');\n\t\t$message_invalid  = apply_filters('lasso_invalid_license_message','Oh snap! It looks like your Editus license key is invalid. Might check here to see if its been added correctly.');\n\t\t$message_inactive  = apply_filters('lasso_inactive_license_message','It looks like your license key has not yet been activated.');\n\n\t\t$license_link \t  = sprintf('<a href=\"%s\">Update License</a>', esc_url( add_query_arg( array( 'page' => 'lasso-license' ), admin_url('admin.php') ) ) );\n\t\t$dismiss_link     = sprintf('<a style=\"text-decoration:none;\" href=\"%s\" id=\"lasso-dismiss-notice\" class=\"notice-dismiss\"><span class=\"screen-reader-text\">%s</span></a>', esc_url( add_query_arg( 'lasso-notice', 'dismiss' ) ), __('Dismiss this notice.','lasso') );\n\n\t\t$not_hidden       = get_user_meta( get_current_user_ID(), 'lasso_license_nag_dismissed', true );\n\n\t\tif ( current_user_can('manage_options') && !$welcome && !defined( 'LASSO_AGENCY_MODE') && !$not_hidden ) {\n\n\t\t\tif ( empty( $license ) ) {\n\n        \t\tprintf('<div class=\"lasso-notice error\" style=\"position:relative;\"><p>%s %s</p>%s</div>', $message_empty, $license_link, $dismiss_link );\n\n        \t} else if ( 'invalid' == $status ){ // license key entered wrong or something\n\n\t\t\t\tprintf('<div class=\"lasso-notice error\" style=\"position:relative;\"><p>%s %s</p>%s</div>', $message_invalid, $license_link , $dismiss_link );\n\n        \t} else if ( empty( $status ) ){ // license key saved but not activated\n\n\t\t\t\tprintf('<div class=\"lasso-notice error\" style=\"position:relative;\"><p>%s %s</p>%s</div>', $message_inactive, $license_link, $dismiss_link );\n\n        \t}\n\t\t}\n\n\t}\n\n\t/**\n\t*  Process hiding the dimiss\n\t*\n\t* @since 0.9.7\n\t*/\n\tpublic function dismiss_nag() {\n\n\t\tif ( isset( $_GET['lasso-notice'] ) && 'dismiss' == $_GET['lasso-notice'] && current_user_can('manage_options') ) {\n\t\t\tupdate_user_meta( get_current_user_id(), 'lasso_license_nag_dismissed', 1 );\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "admin/includes/menus/license.php",
    "content": "<?php\n\nnamespace lasso_admin\\menus;\n\nclass license {\n\n\tfunction __construct() {\n\n\t\tdefine( 'LASSO_STORE_ITEM_NAME', 'lasso' );\n\t\tdefine( 'LASSO_STORE_URL', 'https://edituswp.com' );\n\n\t\tadd_action( 'admin_init',  array( $this, 'plugin_updater' ), 0 );\n\t\tadd_action( 'admin_menu',  array( $this, 'license_menu' ) );\n\t\tadd_action( 'network_admin_menu',  array( $this, 'license_menu' ) ); // CHANGED Added hook.\n\t\tadd_action( 'admin_init',  array( $this, 'register_option' ) );\n\t\tadd_action( 'admin_init',  array( $this, 'activate_license' ) );\n\t\tadd_action( 'admin_init',  array( $this, 'deactivate_license' ) );\n\t}\n\n\tfunction plugin_updater() {\n\n\t\t// retrieve our license key from the DB\n\t\t$license_key = trim( get_option( 'lasso_license_key' ) );\n\n\t\t// setup the updater\n\t\t$edd_updater = new \\EDD_SL_Plugin_Updater( LASSO_STORE_URL , LASSO_FILE, array(\n\t\t\t\t'version'  => LASSO_VERSION,\n\t\t\t\t'license'  => $license_key,\n\t\t\t\t'item_name' => LASSO_STORE_ITEM_NAME,\n\t\t\t\t'author'  => __( 'Aesopinteractive LLC', 'lasso' )\n\t\t\t)\n\t\t);\n\n\t}\n\tfunction license_menu() {\n\n\t\t// CHANGED Removed condition.\n\t\tadd_submenu_page( 'lasso-editor', __( 'License Key', 'lasso' ), __( 'License', 'lasso' ), 'manage_options', 'lasso-license', array( $this, 'license_page' ) );\n\n\t}\n\tfunction license_page() {\n\t\t$license  = get_option( 'lasso_license_key' );\n\t\t$status  = get_option( 'lasso_license_status' );\n\n?>\n\t\t<div class=\"wrap\">\n\t\t\t<h2><?php _e( 'Editus License', 'lasso' ); ?></h2>\n\t\t\t<p><?php _e( 'Input the license key you recieved with your purchase to ensure your version of Editus stays updated.', 'lasso' );?></p>\n\t\t\t<form class=\"lasso--form-settings\" method=\"post\" action=\"options.php\">\n\n\t\t\t\t<?php settings_fields( 'lasso_license' ); ?>\n\n\t\t\t\t<table class=\"form-table\">\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<tr valign=\"top\">\n\t\t\t\t\t\t\t<th scope=\"row\" valign=\"top\">\n\t\t\t\t\t\t\t\t<?php _e( 'License Key', 'lasso' ); ?>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<input id=\"lasso_license_key\" name=\"lasso_license_key\" type=\"text\" class=\"regular-text\" value=\"<?php esc_attr_e( $license ); ?>\" />\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<?php if ( false !== $license ) { ?>\n\t\t\t\t\t\t\t<tr valign=\"top\">\n\t\t\t\t\t\t\t\t<th scope=\"row\" valign=\"top\">\n\t\t\t\t\t\t\t\t\t<?php _e( 'Activate License', 'lasso' ); ?>\n\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<?php if ( $status !== false && $status == 'valid' ) { ?>\n\t\t\t\t\t\t\t\t\t\t<span style=\"color:green;\"><?php _e( 'active' ); ?></span>\n\t\t\t\t\t\t\t\t\t\t<?php wp_nonce_field( 'lasso_license_nonce', 'lasso_license_nonce' ); ?>\n\t\t\t\t\t\t\t\t\t\t<input type=\"submit\" class=\"button-secondary\" name=\"edd_license_deactivate\" value=\"<?php esc_attr_e( 'Deactivate License', 'lasso' ); ?>\"/>\n\t\t\t\t\t\t\t\t\t<?php } else {\n\t\t\t\twp_nonce_field( 'lasso_license_nonce', 'lasso_license_nonce' ); ?>\n\t\t\t\t\t\t\t\t\t\t<input type=\"submit\" class=\"button-secondary\" name=\"edd_license_activate\" value=\"<?php esc_attr_e( 'Activate License', 'lasso' ); ?>\"/>\n\t\t\t\t\t\t\t\t\t<?php } ?>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<?php } ?>\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t\t<?php submit_button( 'Save License' ); ?>\n\n\t\t\t</form>\n\t\t<?php\n\t}\n\n\t// register option\n\tfunction register_option() {\n\n\t\tregister_setting( 'lasso_license', 'lasso_license_key', array( $this, 'sanitize_license' ) );\n\t}\n\n\t// santize\n\tfunction sanitize_license( $new ) {\n\t\t$old = get_option( 'lasso_license_key' );\n\t\tif ( $old && $old != $new ) {\n\t\t\tdelete_option( 'lasso_license_status' ); // new license has been entered, so must reactivate\n\t\t}\n\t\treturn $new;\n\t}\n\n\t// activate\n\tfunction activate_license() {\n\n\t\t// listen for our activate button to be clicked\n\t\tif ( isset( $_POST['edd_license_activate'] ) ) {\n\n\t\t\t// run a quick security check\n\t\t\tif ( ! check_admin_referer( 'lasso_license_nonce', 'lasso_license_nonce' ) )\n\t\t\t\treturn; // get out if we didn't click the Activate button\n\n\t\t\t// retrieve the license from the database\n\t\t\t$license = trim( get_option( 'lasso_license_key' ) );\n\n\t\t\t// data to send in our API request\n\t\t\t$api_params = array(\n\t\t\t\t'edd_action'=> 'activate_license',\n\t\t\t\t'license'  => $license,\n\t\t\t\t'item_name' => urlencode( LASSO_STORE_ITEM_NAME ), // the name of our product in EDD\n\t\t\t\t'url'       => home_url()\n\t\t\t);\n\n\t\t\t// Call the custom API.\n\t\t\t$response = wp_remote_post( LASSO_STORE_URL, array( 'body' => $api_params, 'timeout' => 15, 'sslverify' => false ) );\n\n\t\t\t// make sure the response came back okay\n\t\t\tif ( is_wp_error( $response ) )\n\t\t\t\treturn false;\n\n\t\t\t// decode the license data\n\t\t\t$license_data = json_decode( wp_remote_retrieve_body( $response ) );\n\n\t\t\t// $license_data->license will be either \"valid\" or \"invalid\"\n\n\t\t\tupdate_option( 'lasso_license_status', $license_data->license );\n\n\t\t}\n\t}\n\n\tfunction deactivate_license() {\n\n\t\t// listen for our activate button to be clicked\n\t\tif ( isset( $_POST['edd_license_deactivate'] ) ) {\n\n\t\t\t// run a quick security check\n\t\t\tif ( ! check_admin_referer( 'lasso_license_nonce', 'lasso_license_nonce' ) )\n\t\t\t\treturn; // get out if we didn't click the Activate button\n\n\t\t\t// retrieve the license from the database\n\t\t\t$license = trim( get_option( 'lasso_license_key' ) );\n\n\n\t\t\t// data to send in our API request\n\t\t\t$api_params = array(\n\t\t\t\t'edd_action'=> 'deactivate_license',\n\t\t\t\t'license'  => $license,\n\t\t\t\t'item_name' => urlencode( LASSO_STORE_ITEM_NAME ), // the name of our product in EDD\n\t\t\t\t'url'       => home_url()\n\t\t\t);\n\n\t\t\t// Call the custom API.\n\t\t\t$response = wp_remote_post( LASSO_STORE_URL, array( 'body' => $api_params, 'timeout' => 15, 'sslverify' => false ) );\n\n\t\t\t// make sure the response came back okay\n\t\t\tif ( is_wp_error( $response ) )\n\t\t\t\treturn false;\n\n\t\t\t// decode the license data\n\t\t\t$license_data = json_decode( wp_remote_retrieve_body( $response ) );\n\n\t\t\t// $license_data->license will be either \"deactivated\" or \"failed\"\n\t\t\tif ( $license_data->license == 'deactivated' )\n\t\t\t\tdelete_option( 'lasso_license_status' );\n\n\t\t}\n\t}\n\n\t// check status of license\n\tfunction check_license() {\n\n\t\tglobal $wp_version;\n\n\t\t$license = trim( get_option( 'lasso_license_key' ) );\n\n\t\t$api_params = array(\n\t\t\t'edd_action' => 'check_license',\n\t\t\t'license' => $license,\n\t\t\t'item_name' => urlencode( LASSO_STORE_ITEM_NAME ),\n\t\t\t'url'       => home_url()\n\t\t);\n\n\t\t// Call the custom API.\n\t\t$response = wp_remote_post( LASSO_STORE_URL, array( 'body' => $api_params, 'timeout' => 15, 'sslverify' => false ) );\n\n\t\tif ( is_wp_error( $response ) )\n\t\t\treturn false;\n\n\t\t$license_data = json_decode( wp_remote_retrieve_body( $response ) );\n\n\t\tif ( $license_data->license == 'valid' ) {\n\t\t\techo 'valid'; exit;\n\t\t\t// this license is still valid\n\t\t} else {\n\t\t\techo 'invalid'; exit;\n\t\t\t// this license is no longer valid\n\t\t}\n\t}\n}"
  },
  {
    "path": "admin/includes/menus/settings.php",
    "content": "<?php\n/**\n * Class responsible for adding a settings submenu\n *\n */\nnamespace lasso_admin\\menus;\n\nclass settings {\n\n\tfunction __construct() {\n\n\t\tadd_action( 'admin_menu',     array( $this, 'menu' ) );\n\t\tadd_action( 'network_admin_menu',   array( $this, 'menu' ) );\n\t\tadd_action( 'wp_ajax_lasso-editor-settings', array( $this, 'process_settings' ) );\n\n\t}\n\n\t/**\n\t * Add a submenu page to the \"Settings\" tab if network activated, otherwise add to our menu page\n\t *\n\t * @since 1.0\n\t */\n\tfunction menu() {\n\n\t\t// CHANGED Removed condition.\n\t\tadd_submenu_page( 'lasso-editor', __( 'Settings', 'lasso' ), __( 'Settings', 'lasso' ), 'manage_options', 'lasso-editor-settings', array( $this, 'settings' ) );\n\n\t}\n\n\t/**\n\t * Submenu page callback\n\t *\n\t * @since 1.0\n\t */\n\tfunction settings() {\n\n\t\techo self::lasso_editor_settings_form();\n\t}\n\n\t/**\n\t * Save settings via ajax\n\t *\n\t * @since 1.0\n\t */\n\tfunction process_settings() {\n\n\t\t// bail out if current user isn't and administrator and they are not logged in\n\t\tif ( !current_user_can( 'manage_options' ) || !is_user_logged_in() )\n\t\t\treturn;\n\n\t\tif ( isset( $_POST['action'] ) && 'lasso-editor-settings' == $_POST['action'] && check_admin_referer( 'nonce', 'lasso_editor_settings' ) ) {\n\n\t\t\t$options = isset( $_POST['lasso_editor'] ) ? $_POST['lasso_editor'] : false;\n\t\t\t\n\t\t\t$arr = $options['allowed_post_types'];\n\t\t\t$options = array_map( 'sanitize_text_field', $options );\n\t\t\t$options['allowed_post_types'] = array_keys( $arr);\n\n\t\t\t\n\n\t\t\tif ( function_exists( 'is_multisite' ) && is_multisite() ) {\n\n\t\t\t\tupdate_site_option( 'lasso_editor', $options );\n\n\t\t\t} else {\n\n\t\t\t\tupdate_option( 'lasso_editor', $options );\n\t\t\t}\n\n\t\t\twp_send_json_success();\n\n\t\t} else {\n\n\t\t\twp_send_json_error();\n\n\t\t}\n\n\t\tdie();\n\n\t}\n\t\n\tfunction create_section_for_color_picker($id, $title, $defvalue) { \n\t\t$color_value = lasso_editor_get_option( $id, 'lasso_editor',$defvalue );\n\t \n\t\techo '<div lass=\"lasso-editor-settings--option-inner\">'.\"\\n\";\n\t\techo '<label>'.$title.'</label>';\n\t\techo '<input type=\"text\" name=\"lasso_editor['.$id.']\" value=\"'.$color_value.'\" id=\"lasso-editor-'.$title.'\" class=\"color-picker\"/>';\n\t\techo \"</div>\\n\";\n\t }\n\n\t/**\n\t * Draw the settings form\n\t *\n\t * @since 1.0\n\t */\n\tfunction lasso_editor_settings_form() {\n\n\t\tif ( !is_user_logged_in() )\n\t\t\treturn;\n        \n        // check for lasso story engine and add a class doniting this\n        $ase_status = class_exists( 'Aesop_Core' ) || defined( 'LASSO_CUSTOM' ) ? 'ase-active' : 'ase-not-active';\n\n\t\t$article_object   = lasso_editor_get_option( 'article_class', 'lasso_editor' );\n\t\t$featImgClass    = lasso_editor_get_option( 'featimg_class', 'lasso_editor' );\n\t\t$titleClass    = lasso_editor_get_option( 'title_class', 'lasso_editor' );\n\n\t\t$post_new_disabled   = lasso_editor_get_option( 'post_adding_disabled', 'lasso_editor' );\n\t\t$save_to_post_disabled  = lasso_editor_get_option( 'post_save_disabled', 'lasso_editor' );\n\t\t$edit_post_disabled  = lasso_editor_get_option( 'post_edit_disabled', 'lasso_editor' );\n\t\t$post_settings_disabled = lasso_editor_get_option( 'post_settings_disabled', 'lasso_editor' );\n\t\t$allow_change_date = lasso_editor_get_option( 'allow_change_date', 'lasso_editor' );\n        $allow_edit_excerpt = lasso_editor_get_option( 'allow_edit_excerpt', 'lasso_editor' );\n\t\t$allow_new_category = lasso_editor_get_option( 'allow_new_category', 'lasso_editor' );\n\t\t$shortcodify_disabled  = lasso_editor_get_option( 'shortcodify_disabled', 'lasso_editor' );\n\t\t$enable_autosave  = lasso_editor_get_option( 'enable_autosave', 'lasso_editor' );\n\t\t\n\t\t$disable_shortcode_editing = lasso_editor_get_option('disable_shortcode_editing', 'lasso_editor');\n\n\t\t$use_old_ui      = lasso_editor_get_option( 'use_old_ui', 'lasso_editor' );\n\t\t$toolbar_headings      = lasso_editor_get_option( 'toolbar_headings', 'lasso_editor' );\n\t\t$toolbar_headings_h4      = lasso_editor_get_option( 'toolbar_headings_h4', 'lasso_editor' );\n\t\t$toolbar_list      = lasso_editor_get_option( 'toolbar_list', 'lasso_editor' );\n\t\t$toolbar_show_color      = lasso_editor_get_option( 'toolbar_show_color', 'lasso_editor' );\n\t\t$toolbar_show_alignment  = lasso_editor_get_option( 'toolbar_show_alignment', 'lasso_editor' );\n        \n        $text_select_popup = lasso_editor_get_option('text_select_popup', 'lasso_editor', false);\n\t\t\n\t\t$objectsNoSave  \t= lasso_editor_get_option('dont_save', 'lasso_editor');\n\t\t$objectsNonEditable  \t= lasso_editor_get_option('non_editable', 'lasso_editor');\n\t\t$disable_tour = lasso_editor_get_option('disable_tour', 'lasso_editor');\n\t\t$show_ignored_items = lasso_editor_get_option('show_ignored_items', 'lasso_editor');\n\t\t$save_using_rest_disabled = lasso_editor_get_option('save_using_rest_disabled', 'lasso_editor');\n\t\t\n\t\t$default_post_types = apply_filters( 'lasso_allowed_post_types', array( 'post', 'page'));\n\t\t$allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor',  $default_post_types);\n\t\t\n\t\t$links_editable = lasso_editor_get_option('links_editable', 'lasso_editor', false);\n\t\t$bold_tag = lasso_editor_get_option( 'bold_tag', 'lasso_editor',  \"b\");\n\t\t$i_tag = lasso_editor_get_option( 'i_tag', 'lasso_editor',  \"i\");\n        \n        $add_table = lasso_editor_get_option('add_table', 'lasso_editor', false);\n        $add_paragraph = lasso_editor_get_option('add_paragraph', 'lasso_editor', false);\n\t\t\n\t\t// do we support pending status\n\t\t$no_pending_status = lasso_editor_get_option('no_pending_status', 'lasso_editor');\n\t\t\n\t\t$no_url_setting = lasso_editor_get_option('no_url_setting', 'lasso_editor');\n\t\t\n\t\t$insert_comp_ui = lasso_editor_get_option('insert_comp_ui', 'lasso_editor');\n\t\tif (!$insert_comp_ui) {\n\t\t\t$insert_comp_ui = 'drag';\n\t\t}\n        \n        $link_prefix_http = lasso_editor_get_option('link_prefix_http', 'lasso_editor');\n\t\t$inherit_categories = lasso_editor_get_option('inherit_categories', 'lasso_editor');\n        \n        $use_old_wpimg = lasso_editor_get_option('use_old_wpimg', 'lasso_editor','off');\n        $use_wp_block_image = lasso_editor_get_option('use_wp_block_image', 'lasso_editor','off');\n\t\t\n\t\t$support_custom_taxonomy   = lasso_editor_get_option( 'support_custom_taxonomy', 'lasso_editor' );\n        \n        $new_post_text    = lasso_editor_get_option( 'new_post_text', 'lasso_editor' );\n        \n        $no_wrap_shortcode    = lasso_editor_get_option( 'no_wrap_shortcode', 'lasso_editor');\n\n?>\n\t\t<div class=\"wrap\">\n\t\t<style>\n\t\t.lasso-editor-settings--option-wrap {\n\t\t\tdisplay:none;\n\t\t}\n\t\t\n\t\t.accordion:before {\n\t\t\tfont-family: dashicons;\n\t\t\tcontent: \"\\f139\";\n\t\t}\n\t\t.accordion.show:before {\n\t\t\tfont-family: dashicons;\n\t\t\tcontent: \"\\f140\";\n\t\t}\n\t\t</style>\n\t\t<script>\n\t\t(function( $ ) {\n\t\t\tjQuery(document).ready(function(){\n\t\t\t\tjQuery('.accordion.show').next().addClass('show');\n\t\t\t\tjQuery('.accordion.show').next().slideDown(350);\n\t\t\t\tjQuery('.accordion').click(function(e) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t  \n\t\t\t\t\tvar $this = $(this);\n\t\t\t\t  \n\t\t\t\t\tif ($this.hasClass('show')) {\n\t\t\t\t\t\t$this.removeClass('show');\n\t\t\t\t\t\t$this.next().removeClass('show');\n\t\t\t\t\t\t$this.next().slideUp(350);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$this.toggleClass('show');\n\t\t\t\t\t\t$this.next().addClass('show');\n\t\t\t\t\t\t$this.next().slideDown(350);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t})( jQuery );\n\t\t\n\t\t\n\t\t</script>        \n\t    \t<h2><?php _e( 'Editus Settings', 'lasso' );?></h2>\n            \n\t\t\t<form id=\"lasso-editor-settings-form\" class=\"lasso--form-settings\" method=\"post\" enctype=\"multipart/form-data\">\n\n\t\t\t\t<?php do_action('lasso_settings_before');?>\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t<h3 class=\"accordion show\"><?php _e( 'Enable for:', 'lasso' );?></h3>\n\t\t\t\t<div class=\"lasso-editor-settings--option-wrap show\">\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\">\n\t\t\t\t\t\t\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Enable Editus for the following post types.', 'lasso' );?></span>\n\t\t\t\t\t\t<?php\n\t\t\t\t\t\t$args = array(\n\t\t\t\t\t\t\t'public'   => true\n\t\t\t\t\t\t);\n\t\t\t\t\t\t \n\t\t\t\t\t\t$allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types );\n\t\t\t\t\t\t$post_types = get_post_types( $args, 'objects' );\n\t\t\t\t\t\t \n\t\t\t\t\t\tforeach ( $post_types  as $post_type ) {\n\t\t\t\t\t\t   if ($post_type->name == 'attachment') continue;\n\t\t\t\t\t\t   $checked =\"\";\n\t\t\t\t\t\t   if (  in_array( $post_type->name, $allowed_post_types )  ) {\n\t\t\t\t\t\t\t\t$checked = 'checked=\"checked\"';\n\t\t\t\t\t\t   }\n\t\t\t\t\t\t   echo '<label><input type=\"checkbox\" '.$checked.' name=\"lasso_editor[allowed_post_types]['.$post_type->name.']\" id=\"lasso_editor[allowed_post_types]['.$post_type->name.']\" >'.$post_type->name.'</label>';\n\t\t\t\t\t\t}\n\t\t\t\t\t\t?>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t\n\n\t\t\t\t<h3 class=\"accordion show\"><?php _e( 'Internal Settings', 'lasso' );?></h3>\n\t\t\t\t<div class=\"lasso-editor-settings--option-wrap show\">\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<label><?php _e( 'Article Class', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Provide the CSS class (including the preceding dot) of container that holds the post. This should be the first parent container class that holds the_content.', 'lasso' );?></span>\n\t\t\t\t\t\t<input type=\"text\" name=\"lasso_editor[article_class]\" id=\"lasso_editor[article_class]\" value=\"<?php echo esc_attr( $article_object );?>\" placeholder=\".entry-content\">\n\t\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<label><?php _e( 'Featured Image Class', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Provide the CSS class that uses a featured image as a background image. This currently only supports themes that have the featured image set as background image.', 'lasso' );?></span>\n\t\t\t\t\t\t<input type=\"text\" name=\"lasso_editor[featimg_class]\" id=\"lasso_editor[featimg_class]\" value=\"<?php echo esc_attr( $featImgClass );?>\" placeholder=\".entry-content\">\n\t\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<label><?php _e( 'Article Title Class', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Provide the CSS class for the post title. This will enable you to update the title of the post by clicking and typing.', 'lasso' );?></span>\n\t\t\t\t\t\t<input type=\"text\" name=\"lasso_editor[title_class]\" id=\"lasso_editor[title_class]\" value=\"<?php echo esc_attr( $titleClass );?>\" placeholder=\".entry-content\">\n\t\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<label><?php _e( 'Ignored Items to Save', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'If your post container holds additional markup, list the css class names (comma separated, including the dot) of those items. When you enter the editor, Editus will remove (NOT delete) these items so that it does not save them as HTML.', 'lasso' );?></span>\n\t\t\t\t\t\t<textarea name=\"lasso_editor[dont_save]\" id=\"lasso_editor[dont_save]\" placeholder=\".classname, .another-class\"><?php echo esc_attr( $objectsNoSave );?></textarea>\n\t\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<label><?php _e( 'Read Only Items', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'If your post has items that should not be editable, list the css class names (comma separated, including the dot) of those items.', 'lasso' );?></span>\n\t\t\t\t\t\t<textarea name=\"lasso_editor[non_editable]\" id=\"lasso_editor[non_editable]\" placeholder=\".classname, .another-class\"><?php echo esc_attr( $objectsNonEditable );?></textarea>\n\t\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" >\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[show_ignored_items]\" id=\"lasso_editor[show_ignored_items]\" <?php echo checked( $show_ignored_items, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[show_ignored_items]\"> <?php _e( 'Show Ignored Items', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'By default the ignored items are hidden. Check this to show ignored items while keeping them uneditable.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<h3 class=\"accordion\"><?php _e( 'Editor UI', 'lasso' );?></h3>\n\t\t\t\t<div class=\"lasso-editor-settings--option-wrap\">\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[use_old_ui]\" id=\"lasso_editor_use_old_ui\" <?php echo checked( $use_old_ui, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[use_old_ui]\"><?php _e( 'Use the Old Toolbar', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Use this option to disable the new color options and use the pre-1.0 toolbar.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t    <div id=\"lasso-editor-settings--colors\">\n\t\t\t\t\t<?php\n\t\t\t\t\tself::create_section_for_color_picker('button-color1', _e( 'Editor Bar Color Top', 'lasso' ), '#0000ff');\n\t\t\t\t\tself::create_section_for_color_picker('button-color2', _e( 'Editor Bar Color Bottom', 'lasso' ), '#000030');\n\t\t\t\t\tself::create_section_for_color_picker('dialog-color', _e( 'Dialog Color', 'lasso' ), '#000055');\n\t\t\t\t\tself::create_section_for_color_picker('text-color', _e( 'Icon/Text Color', 'lasso' ), '#ffffff');\n\t\t\t\t\t?>\n\t\t\t\t\t<button type=\"button\" id=\"lasso-editor-settings--default-colors\" ><?php _e( 'Default Colors', 'lasso' );?></button>\n\t\t\t\t    <div style=\"height:50px;\"></div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[toolbar_headings]\" id=\"lasso_editor[toolbar_headings]\" <?php echo checked( $toolbar_headings, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[toolbar_headings]\"><?php _e( 'Enable H2 and H3 Buttons', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Show the buttons to set H2 and H3 settings.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[toolbar_headings_h4]\" id=\"lasso_editor[toolbar_headings_h4]\" <?php echo checked( $toolbar_headings_h4, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[toolbar_headings_h4]\"><?php _e( 'Enable H4/H5/H6 Buttons', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Show the buttons to set H4/H5/H6 settings.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[toolbar_list]\" id=\"lasso_editor[toolbar_list]\" <?php echo checked( $toolbar_list, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[toolbar_list]\"><?php _e( 'Enable OL/UL Buttons', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Show the buttons to create Ordered and Unordered Lists from text selection.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[toolbar_show_color]\" id=\"lasso_editor[toolbar_show_color]\" <?php echo checked( $toolbar_show_color, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[toolbar_show_color]\"><?php _e( 'Enable Text Color Buttons', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Show the buttons to set text colors.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[toolbar_show_alignment]\" id=\"lasso_editor[toolbar_show_alignment]\" <?php echo checked( $toolbar_show_alignment, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[toolbar_show_alignment]\"><?php _e( 'Enable Text Align Buttons', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Show the buttons to set text alignment.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[links_editable]\" id=\"lasso_editor[links_editable]\" <?php echo checked( $links_editable, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[links_editable]\"><?php _e( 'Make links editable under the Editing Mode', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Make links editable under the Editing Mode. Turning this on will make the links non-clickable while editing.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t    <label for=\"lasso_editor[insert_comp_ui]\"> <?php _e( 'Insert Component UI', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'UI mechanism to insert components', 'lasso' );?></span>\n\t\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t       <input type=\"radio\" name=\"lasso_editor[insert_comp_ui]\" value='drag' <?php echo checked( $insert_comp_ui, 'drag' );?>> <?php _e( 'Drag and Drop', 'lasso' );?>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<input type=\"radio\" name=\"lasso_editor[insert_comp_ui]\" value=\"click\" <?php echo checked( $insert_comp_ui, 'click' );?>> <?php _e( 'Click', 'lasso' );?>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<input type=\"radio\" name=\"lasso_editor[insert_comp_ui]\" value=\"mediumcom\" <?php echo checked( $insert_comp_ui, 'mediumcom' );?>> <?php _e( 'Auto Button on Empty Paragraph. medium.com-like UI.', 'lasso' );?>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n                    \n                    <div class=\"lasso-editor-settings--option-inner\" >\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[text_select_popup]\" id=\"lasso_editor[text_select_popup]\" <?php echo checked( $text_select_popup, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[text_select_popup]\"><?php _e( 'Popup When Text is Selected', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Instead of using the bottom toolbar to format texts, use a popup box to format texts.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n                    \n\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t<h3 class=\"accordion\"><?php _e( 'Component', 'lasso' );?></h3>\n                <div class=\"lasso-editor-settings--option-wrap\" style=\"border:none;\" >\n                    <div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[add_table]\" id=\"lasso_editor[add_table]\" <?php echo checked( $add_table, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[add_table]\"><span class=\"dashicons dashicons-grid-view\"> </span> <?php _e( 'Additional Component: Table', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Allow user to add and edit tables.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n                    \n                     <div class=\"lasso-editor-settings--option-inner\" >\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[add_paragraph]\" id=\"lasso_editor[add_paragraph]\" <?php echo checked( $add_paragraph, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[add_paragraph]\"><span class=\"dashicons dashicons-editor-paragraph\"></span><?php _e( 'Additional Component: Paragraph', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Plain HTML Paragraph.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n                \n                <?php if ( 'ase-active' != $ase_status ) { ?>\n                    <script>\n                    $(document).ready(function(){\n                        $(\"#lasso_editor\\\\[use_old_wpimg\\\\]\").on('change', function(){                        \n                            if($(\"#lasso_editor\\\\[use_old_wpimg\\\\]:checked\").length){\n                                $(\"#lasso_editor\\\\[use_wp_block_image\\\\]\").prop('disabled', true);\n                                $(\"#lasso_editor\\\\[use_wp_block_image\\\\]\").prop('checked', false);\n                                return;\n                            }\n\n                            $(\"#lasso_editor\\\\[use_wp_block_image\\\\]\").prop('disabled', false);\n                        });\n\n                        $(\"#lasso_editor\\\\[use_wp_block_image\\\\]\").on('change', function(){        \n                            if($(\"#lasso_editor\\\\[use_wp_block_image\\\\]:checked\").length){\n                                $(\"#lasso_editor\\\\[use_old_wpimg\\\\]\").prop('disabled', true);\n                                $(\"#lasso_editor\\\\[use_old_wpimg\\\\]\").prop('checked', false);\n                                return;\n                            }\n\n                            $(\"#lasso_editor\\\\[use_old_wpimg\\\\]\").prop('disabled', false);\n                        });\n                    })\n                    </script>\n                \n                    <div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[use_old_wpimg]\" id=\"lasso_editor[use_old_wpimg]\" <?php echo checked( $use_old_wpimg, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[use_old_wpimg]\"><?php _e( 'Use Simple Image', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Use Simple Image Component without Extra Options.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n                \n                \n                    <div class=\"lasso-editor-settings--option-inner\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[use_wp_block_image]\" id=\"lasso_editor[use_wp_block_image]\" <?php echo checked( $use_wp_block_image, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[use_wp_block_image]\"><?php _e( 'Use WP Image Block', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Use WP Image Block as the image component. Gutenberg Block Editor needs to be enabled.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n                <?php }?>\n                </div>\n\t\t\t\t\n\n\t\t\t\t<h3 class=\"accordion\"><?php _e( 'Post Settings UI', 'lasso' );?></h3>\n\t\t\t\t<div class=\"lasso-editor-settings--option-wrap\"  >\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[post_settings_disabled]\" id=\"lasso_editor[post_settings_disabled]\" <?php echo checked( $post_settings_disabled, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[post_settings_disabled]\"> <?php _e( 'Disable Post Settings', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Check this to disable users from being able to edit post settings from the front-end.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[allow_change_date]\" id=\"lasso_editor[allow_change_date]\" <?php echo checked( $allow_change_date, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[allow_change_date]\"> <?php _e( 'Allow Changing Post Date', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Add the date selector to change the post\\'s date to the Post Setting dialog', 'lasso' );?></span>\n\t\t\t\t\t</div>\n                    \n                    <div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[allow_edit_excerpt]\" id=\"lasso_editor[allow_edit_excerpt]\" <?php echo checked( $allow_edit_excerpt, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[allow_edit_excerpt]\"> <?php _e( 'Allow Editing Excerpt', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Allow the post\\'s excerpt to be edited in the Post Setting dialog', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[allow_new_category]\" id=\"lasso_editor[allow_new_category]\" <?php echo checked( $allow_new_category, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[allow_new_category]\"> <?php _e( 'Allow Adding New Category', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Add the user to create new, previously non-existing categories for posts.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[no_pending_status]\" id=\"lasso_editor[no_pending_status]\" <?php echo checked( $no_pending_status, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[no_pending_status]\"> <?php _e( 'Do Not Allow \"Pending\" Status', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Remove the Option to Set the Status to Pending.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[no_url_setting]\" id=\"lasso_editor[no_slug_setting]\" <?php echo checked( $no_url_setting, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[no_url_setting]\"> <?php _e( 'Remove POST URL Option', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Remove the Option to Set the URL for the Post.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[post_adding_disabled]\" id=\"lasso_editor[post_adding_disabled]\" <?php echo checked( $post_new_disabled, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[post_adding_disabled]\"><?php _e( 'Disable Post Adding', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Check this box to disable users from being able to add new posts from the front-end.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" >\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[support_custom_taxonomy]\" id=\"lasso_editor[support_custom_taxonomy]\" <?php echo checked( $support_custom_taxonomy, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[support_custom_taxonomy]\"><?php _e( 'Support Custom Taxonomy', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Allow editing custom taxonomies.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\n\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t<h3 class=\"accordion\"><?php _e( 'Misc', 'lasso' );?></h3>\n\t\t\t\t<div class=\"lasso-editor-settings--option-wrap\">\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[disable_tour]\" id=\"lasso_editor[disable_tour]\" <?php echo checked( $disable_tour, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[disable_tour]\"> <?php _e( 'Do Not Show Tour Dialog', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Check this box to disable the tour dialog box for all users.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n                    \n                    <div class=\"lasso-editor-settings--option-inner\" style=\"border:none;\">\n\t\t\t\t\t\t<label><?php _e( 'Placeholder Text for New Post', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Placeholder text to be displayed when a new post is created.', 'lasso' );?></span>\n\t\t\t\t\t\t<input type=\"text\" name=\"lasso_editor[new_post_text]\" id=\"lasso_editor[new_post_text]\" value=\"<?php echo esc_attr( $new_post_text );?>\" placeholder=\"<?php $def = wp_strip_all_tags(apply_filters( 'lasso_new_object_content', __( 'Once upon a time...','lasso')));echo $def;?>\", true)>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[disable_shortcode_editing]\" id=\"lasso_editor[disable_shortcode_editing]\" <?php echo checked( $disable_shortcode_editing, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[disable_shortcode_editing]\"> <?php _e( 'Do Not Allow Shortcode Editing', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Check this box to disable frontend editing of shortcodes.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t    <label for=\"lasso_editor[bold_tag]\"> <?php _e( '\"Bold\" Tag', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Choose the HTML tag used for the \"Bold\" style.', 'lasso' );?></span>\n\t\t\t\t\t    <input type=\"radio\" name=\"lasso_editor[bold_tag]\" value='b' <?php echo checked( $bold_tag, 'b' );?>> b\n\t\t\t\t\t\t<input type=\"radio\" name=\"lasso_editor[bold_tag]\" value=\"strong\" <?php echo checked( $bold_tag, 'strong' );?>> strong\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t    <label for=\"lasso_editor[i_tag]\"> <?php _e( '\"Italic\" Tag', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Choose the HTML tag used for the \"Italic\" style.', 'lasso' );?></span>\n\t\t\t\t\t    <input type=\"radio\" name=\"lasso_editor[i_tag]\" value='i' <?php echo checked( $i_tag, 'i' );?>> i\n\t\t\t\t\t\t<input type=\"radio\" name=\"lasso_editor[i_tag]\" value=\"em\" <?php echo checked( $i_tag, 'em' );?>> em\n\t\t\t\t\t</div>\n                    <div class=\"lasso-editor-settings--option-inner\" style=\"border:none\" >\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[link_prefix_http]\" id=\"lasso_editor[link_prefix_http]\" <?php echo checked( $link_prefix_http, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[link_prefix_http]\"><?php _e( 'Auto Prefix HTTP to links', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'When user adds a hyperlink, automatically add http:// if the user does not specify it explicitly.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" >\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[inherit_categories]\" id=\"lasso_editor[inherit_categories]\" <?php echo checked( $inherit_categories, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[inherit_categories]\"><?php _e( 'Inherit Post Categories When Creating a New Post', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'When creating a new post, take the categories of the current post and apply to the new post.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<h3 class=\"accordion\"><?php _e( 'Advanced Options', 'lasso' );?></h3>\n                \n\t\t\t\t<div class=\"lasso-editor-settings--option-wrap \">\n\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Suggested not to turn these options on without consulting the developer.', 'lasso' );?></span>\n\t\t\t\t\t<span class=\"lasso--setting-description\"> </span>\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[shortcodify_disabled]\" id=\"lasso_editor[shortcodify_disabled]\" <?php echo checked( $shortcodify_disabled, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[shortcodify_disabled]\"><?php _e( 'Disable Aesop Component Conversion', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Check this box to disable the conversion process used on Aesop Story Engine components.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[enable_autosave]\" id=\"lasso_editor[enable_autosave]\" <?php echo checked( $enable_autosave, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[enable_autosave]\"><?php _e( 'Enable Auto Save', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'Check this box to enable auto save.', 'lasso' );?></span>\n\t\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[post_save_disabled]\" id=\"lasso_editor[post_save_disabled]\" <?php echo checked( $save_to_post_disabled, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[post_save_disabled]\"><?php _e( 'Disable Post Saving', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'By default the editor will update the database with the post or page it is being used on. Check this box to disable this. If you check this box, it is assumed that you will be using the provided filters to save your own content.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n\t\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[post_edit_disabled]\" id=\"lasso_editor[post_edit_disabled]\" <?php echo checked( $edit_post_disabled, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[post_edit_disabled]\"><?php _e( 'Disable Post Editing', 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'You may use this option if you only want to edit custom fields. Refer <a href=\"https://edituswp.com/editing-and-updating-custom-fields-from-frontend/\">here</a> for more information. The custom fields you specify will be still editable under the editing mode.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\t<div class=\"lasso-editor-settings--option-inner\" style=\"border:none\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[save_using_rest_disabled]\" id=\"lasso_editor[save_using_rest_disabled]\" <?php echo checked( $save_using_rest_disabled, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[save_using_rest_disabled]\"><?php _e( \"Don't Use REST API to Save\", 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'By default the editor will use REST API to save posts. Check this box to use custom AJAX calls instead.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n                    \n                    <div class=\"lasso-editor-settings--option-inner\">\n\t\t\t\t\t\t<input type=\"checkbox\" class=\"checkbox\" name=\"lasso_editor[no_wrap_shortcode]\" id=\"lasso_editor[no_wrap_shortcode]\" <?php echo checked( $no_wrap_shortcode, 'on' );?> >\n\t\t\t\t\t\t<label for=\"lasso_editor[no_wrap_shortcode]\"><?php _e( \"Don't Wrap Shortcodes\", 'lasso' );?></label>\n\t\t\t\t\t\t<span class=\"lasso--setting-description\"><?php _e( 'By default Editus wraps shortcodes so they can be preserved. Disable this behavior.', 'lasso' );?></span>\n\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t\n\n\n\t\t\t\t<div class=\"lasso-editor-settings--submit\">\n\t\t\t\t    <input type=\"hidden\" name=\"action\" value=\"lasso-editor-settings\" />\n\t\t\t\t    <input type=\"submit\" class=\"button-primary\" value=\"<?php esc_attr_e( 'Save Settings', 'lasso' );?>\" />\n\t\t\t\t\t<?php wp_nonce_field( 'nonce', 'lasso_editor_settings' ); ?>\n\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t<?php do_action('lasso_settings_after');?>\n\t\t\t</form>\n\n\t\t</div><?php\n\n\t}\n}\n\n"
  },
  {
    "path": "admin/includes/menus/welcome.php",
    "content": "<?php\n/**\n * Creates a welcome screen with pre-flight check sequence\n *\n * @since 0.8.2\n */\nnamespace lasso_admin\\menus;\n\nclass welcome {\n\n\tfunction __construct() {\n\n\t\tadd_action( 'admin_init',   array( $this, 'redirect' ) );\n\t\tadd_action( 'admin_menu',   array( $this, 'lasso_welcome' ) );\n\t\tadd_action( 'network_admin_menu',   array( $this, 'lasso_welcome' ) );  // CHANGED Added hook.\n\n\t\tadd_action( 'tgmpa_register',  array( $this,'required_plugins' ));\n\n\t}\n\n\tfunction redirect() {\n\n\t\t// Bail if no activation redirect\n\t\tif ( !get_transient( '_lasso_welcome_redirect' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Delete the redirect transient\n\t\tdelete_transient( '_lasso_welcome_redirect' );\n\n\t\t// Bail if activating from network, or bulk\n\t\tif ( is_network_admin() || isset( $_GET['activate-multi'] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\twp_safe_redirect( esc_url_raw( add_query_arg( array( 'page' => 'lasso-editor' ), admin_url( 'admin.php' ) ) ) );\n\n\t}\n\n\t/**\n\t * Add dashboard pages for welcome and welcome back\n\t *\n\t * @since 0.8\n\t */\n\tfunction lasso_welcome() {\n\n\t\t// CHANGED Removed condition.\n\t\tadd_menu_page( __( 'Editus', 'lasso' ), __( 'Editus', 'lasso' ), 'manage_options', 'lasso-editor', '', LASSO_URL.'/admin/assets/img/menu-icon.png' );\n\t\tadd_submenu_page( 'lasso-editor', __( 'Welcome', 'lasso' ), __( 'Status', 'lasso' ), 'manage_options', 'lasso-editor', array( $this, 'welcome' ) );\n\n\t}\n\n\t/**\n\t * Callback for the intial welcome screen for new users\n\t *\n\t * @since 0.8.2\n\t */\n\tfunction welcome() {\n\n\t\t?>\n\t\t  <div class=\"wrap lasso--welcome\">\n\n\t\t  \t\t<?php self::header();?>\n\n\t\t  \t\t<ul class=\"lasso--welcome__steps\">\n\n\t\t  \t\t<?php // CHANGED Added the is_network_admin condition. ?>\n\t\t\t  \t\t<?php if ( is_network_admin() ) : ?>\n\n\t\t\t  \t\t\t<li>\n\t\t\t  \t\t\t\t<p><?php _e( 'We will check the current theme on every site in your network and give you a quick status feedback here. You can see the status by visiting the Editus menu on each site.', 'lasso' );?></p>\n\t\t\t  \t\t\t</li>\n\n\t\t\t  \t\t<?php else :\n\n\t\t\t\t\t$checks = self::lasso_preflight_check();\n\n\t\t\t\t\tif ( $checks && !defined( 'LASSO_AGENCY_MODE' ) ):\n\n\t\t\t\t\t\tforeach ( (array) $checks as $key => $check ) {\n\n\t\t\t\t\t\t\techo $check;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\telse:\n\n\t\t\t\t\t\t\t// pre-flight is go for flight\n\t\t\t\t\t\t?>\n\t\t\t\t\t\t<li class=\"success\">\n\t\t\t\t\t\t\t<h3><?php _e( 'You\\'re Ready to Rock!', 'lasso' );?></h3>\n\t\t\t\t\t\t\t<?php if ( lasso_get_supported_theme_class() ) { ?>\n\t\t\t\t\t\t\t<p><?php _e( 'Your theme is automatically supported. No additional setup is needed.', 'lasso' );?></p>\n\t\t\t\t\t\t\t<?php } ?>\n\t\t\t  \t\t\t\t<p><?php _e( 'Editus will place a small menu on the bottom of your site. While on a single post or page, click the \"pen\" icon to go into edit mode. Press escape to get out of edit mode.', 'lasso' );?></p>\n\t\t\t  \t\t\t</li>\n\t\t\t  \t\t\t<?php\n\t\t\t  \t\t\tendif;\n\t\t\t\t\tendif; ?>\n\n\t\t\t  \t</ul>\n\t\t  \t</div>\n\t \t<?php\n\t}\n\n\t/**\n\t * Universal header draw on both welcome and activation screens\n\t *\n\t * @since 0.8.2\n\t */\n\tfunction header() {\n\n?>\n\n\t  \t\t<div class=\"lasso--welcome__top\">\n\n\t  \t\t\t<img style=\"width:125px;\" src=\"<?php echo LASSO_URL.'/admin/assets/img/logo.png';?>\">\n\t    \t\t<h1><?php _e( 'Welcome to Editus', 'lasso' );?></h1>\n\t    \t\t<p><?php _e( 'Version', 'lasso' );echo '<span> '.LASSO_VERSION.'</span>';?></p>\n\n\t    \t\t<?php if ( !defined( 'LASSO_AGENCY_MODE' ) ): ?>\n\n\t\t\t    \t<ul class=\"lasso--welcome__social\">\n\t\t\t    \t\t<li><a href=\"https://edituswp.com/help\" target=\"_blank\"><i class=\"dashicons dashicons-sos\"></i> <?php _e( 'Help', 'lasso' );?></a></li>\n\t\t\t    \t\t<li><a href=\"http://twitter.com/aesopinteractiv\" target=\"_blank\"><i class=\"dashicons dashicons-twitter\"></i> <?php _e( 'Twitter', 'lasso' );?></a></li>\n\t\t\t    \t\t<li><a href=\"http://facebook.com/aesopinteractive\" target=\"_blank\"><i class=\"dashicons dashicons-facebook\"></i> <?php _e( 'Facebook', 'lasso' );?></a></li>\n\t\t\t    \t</ul>\n\n\t\t\t    <?php endif; ?>\n\n\t\t    </div>\n\n\t \t<?php\n\t}\n\n\t/**\n\t * Run a series of checks to inform the user about incompatibilities, missing option fields, missing license keys for updates and suggested addons\n\t *\n\t * @since 0.8.6\n\t */\n\tfunction lasso_preflight_check() {\n\n\t\t$notices \t\t= array();\n\n\t\t$article_object = lasso_editor_get_option( 'article_class', 'lasso_editor' );\n\n\t\t$theme_name  \t= wp_get_theme()->get('Name');\n\t\t$theme_class  \t= lasso_get_supported_theme_class();\n\n\t\t$license   \t\t= get_option( 'lasso_license_key' );\n\t\t$status   \t\t= get_option( 'lasso_license_status' );\n\t\t\n\n\t\t// if the required CSS class has not been saved\n\t\tif ( empty( $article_object ) && false == $theme_class ) {\n\n\t\t\t// we dont automatically support this theme so show them otherwise\n\t\t\t$notices[] = sprintf('<li class=\"error\">\n\t\t\t\t\t\t\t<h3>'.__( 'Article CSS Class Needed!', 'lasso' ).'</h3>\n\t\t\t\t\t\t\t<p>'.__( 'Before using Editus,', 'lasso' ).' <a href=\"%s\">'.__( 'enter and save', 'lasso' ).'</a> '.__( 'the CSS class of the container that holds your post and page content. You can <a href=\"https://dl.dropboxusercontent.com/u/5594632/lasso-media/doc-movies/using-inspector-lasso.gif\" target=\"_blank\">use a tool like inspector</a> in Chrome or Firefox to find this CSS class, or ', 'lasso' ).' <a href=\"mailto:editus@aesopinteractive.com\">'.__( 'email us.', 'lasso' ).'</a> '.__( 'with a link to a public URL with the theme and we\\'ll find it for you.', 'lasso' ).'</p>\n\t\t\t\t\t\t\t</li>', admin_url( 'admin.php?page=lasso-editor-settings' ) );\n\t\t}\n\n\t\t// WP REST API not active\n\t\tif ( !function_exists( 'json_get_url_prefix' ) &&  !function_exists( 'rest_url' )) {\n\t\t\t$notices[] = '<li class=\"info\"><h3>WP REST API not Activated!</h3>\n\t\t\t\t\t\t\t<p>'.__( 'Just a heads up that the WP REST API isn\\'t activated. This is required to list the posts and pages on the front-end.', 'lasso' ).'</p>\n\t\t\t\t\t\t\t</li>';\n\t\t}\n\n\t\t// aesop story engine isnt active\n\t\tif ( !class_exists( 'Aesop_Core' ) ) {\n\t\t\t$notices[] = sprintf( '<li class=\"info\"><h3>Aesop Story Engine not Activated!</h3>\n\t\t\t\t\t\t\t<p>'.__( 'Just a heads up that ', 'lasso' ).'<a href=\"%s\" target=\"_blank\n\t\t\t\t\t\t\t\">'.__( 'Aesop Story Engine', 'lasso' ).'</a> '.__( 'isn\\'t activated. It\\'s not required to use Editus, but you won\\'t get the cool drag and drop components without it activated. It\\'s free!', 'lasso' ).'</p>\n\t\t\t\t\t\t\t</li>', admin_url('plugin-install.php?tab=search&s=aesop+story+engine') );\n\t\t}\n\n\t\t// we dont really get along with wp side comments because of the section ids that get applied dynamically. since we save our html, it'll get saved along with the post as HTML\n\t\tif ( class_exists( 'WP_Side_Comments' ) ) {\n\t\t\t$notices[] = '<li class=\"error\"><h3>'.__( 'WP Side Comments Compatibility Warning!', 'lasso' ).'</h3>\n\t\t\t\t\t\t\t<p>'.__( 'Since Editus saves the HTML of a post, this may cause undesired issues. We\\'re working to resolve incompatibilities faster than a jack rabbit in a hot greasy griddle in the middle of August.', 'lasso' ).'</p>\n\t\t\t\t\t\t\t</li>';\n\t\t}\n\n\t\t// if the license key isnt activated\n\t\tif ( empty( $license ) ) {\n\t\t\t$notices[] = '<li class=\"info\"><h3>'.__( 'License Key Not Activated', 'lasso' ).'</h3>\n\t\t\t\t\t\t\t<p>'.__( 'Just a heads up, your license key isn\\'t activated. Enter your license key into the License tab on the left in order to receive plugin update notifications.', 'lasso' ).'</p>\n\t\t\t\t\t\t\t</li>';\n\t\t}\n\t\tif ( !empty( $license ) && 'invalid' == $status ) {\n\t\t\t$notices[] = '<li class=\"error\"><h3>'.__( 'License Key Invalid', 'lasso' ).'</h3>\n\t\t\t\t\t\t\t<p>'.__( 'The license key that you entered is ', 'lasso' ).'<strong>'.__( 'invalid', 'lasso' ).'</strong>'.__( '. It may have been entered incorreclty, or may have expired.', 'lasso' ).'</p>\n\t\t\t\t\t\t\t</li>';\n\t\t}\n\n\t\treturn apply_filters( 'lasso_preflight_notices', $notices );\n\n\t}\n\n\t/**\n\t * Register the required plugins for this theme.\n\t *\n\t *\t@since 0.9.3\n\t */\n\tfunction required_plugins() {\n\n\t    $plugins = array(\n\n\t        array(\n\t            'name'      => __('Aesop Story Engine','lasso'),\n\t            'slug'      => 'aesop-story-engine',\n\t            'required'  => false,\n\t        ),\n\n\t    );\n\n\t    $config = array(\n\t        'default_path' => '',                      // Default absolute path to pre-packaged plugins.\n\t        'menu'         => 'lasso-install-plugins', // Menu slug.\n\t        'has_notices'  => true,                    // Show admin notices or not.\n\t        'dismissable'  => true,                    // If false, a user cannot dismiss the nag message.\n\t        'dismiss_msg'  => '',                      // If 'dismissable' is false, this message will be output at top of nag.\n\t        'is_automatic' => false,                   // Automatically activate plugins after installation or not.\n\t        'message'      => '',                      // Message to output right before the plugins table.\n\t        'strings'      => array(\n\t            'page_title'                      => __( 'Install Required Plugins', 'lasso' ),\n\t            'menu_title'                      => __( 'Install Plugins', 'lasso' ),\n\t            'installing'                      => __( 'Installing Plugin: %s', 'lasso' ), // %s = plugin name.\n\t            'oops'                            => __( 'Something went wrong with the plugin API.', 'lasso' ),\n\t            'notice_can_install_required'     => _n_noop( 'This plugin requires the following plugin: %1$s.', 'This plugin requires the following plugins: %1$s.' ), // %1$s = plugin name(s).\n\t            'notice_can_install_recommended'  => _n_noop( 'This plugin recommends the following plugin: %1$s.', 'This plugin recommends the following plugins: %1$s.' ), // %1$s = plugin name(s).\n\t            'notice_cannot_install'           => _n_noop( 'Sorry, but you do not have the correct permissions to install the %s plugin. Contact the administrator of this site for help on getting the plugin installed.', 'Sorry, but you do not have the correct permissions to install the %s plugins. Contact the administrator of this site for help on getting the plugins installed.' ), // %1$s = plugin name(s).\n\t            'notice_can_activate_required'    => _n_noop( 'The following required plugin is currently inactive: %1$s.', 'The following required plugins are currently inactive: %1$s.' ), // %1$s = plugin name(s).\n\t            'notice_can_activate_recommended' => _n_noop( 'The following recommended plugin is currently inactive: %1$s.', 'The following recommended plugins are currently inactive: %1$s.' ), // %1$s = plugin name(s).\n\t            'notice_cannot_activate'          => _n_noop( 'Sorry, but you do not have the correct permissions to activate the %s plugin. Contact the administrator of this site for help on getting the plugin activated.', 'Sorry, but you do not have the correct permissions to activate the %s plugins. Contact the administrator of this site for help on getting the plugins activated.' ), // %1$s = plugin name(s).\n\t            'notice_ask_to_update'            => _n_noop( 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this plugin: %1$s.', 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this plugin: %1$s.' ), // %1$s = plugin name(s).\n\t            'notice_cannot_update'            => _n_noop( 'Sorry, but you do not have the correct permissions to update the %s plugin. Contact the administrator of this site for help on getting the plugin updated.', 'Sorry, but you do not have the correct permissions to update the %s plugins. Contact the administrator of this site for help on getting the plugins updated.' ), // %1$s = plugin name(s).\n\t            'install_link'                    => _n_noop( 'Begin installing plugin', 'Begin installing plugins' ),\n\t            'activate_link'                   => _n_noop( 'Begin activating plugin', 'Begin activating plugins' ),\n\t            'return'                          => __( 'Return to Required Plugins Installer', 'lasso' ),\n\t            'plugin_activated'                => __( 'Plugin activated successfully.', 'lasso' ),\n\t            'complete'                        => __( 'All plugins installed and activated successfully. %s', 'lasso' ), // %s = dashboard link.\n\t            'nag_type'                        => 'updated' // Determines admin notice type - can only be 'updated', 'update-nag' or 'error'.\n\t        )\n\t    );\n\t\t\n\t\t$plugins = apply_filters( 'lasso_required_plugins', $plugins );\n\n\t    tgmpa( $plugins, $config );\n\n\t}\n}\n\n"
  },
  {
    "path": "bootstrap.php",
    "content": "<?php\n/**\n * Bootstrap the plugin if version check passed.\n *\n * @package   @lasso\n * @author    Josh Pollock <Josh@JoshPress.net>\n * @license   GPL-2.0+\n */\n/*----------------------------------------------------------------------------*\n * Register Autoloader\n *----------------------------------------------------------------------------*/\ninclude_once( LASSO_DIR . '/includes/lasso_autoloader.php' );\n$loader = new lasso_autoloader();\n\n$loader->register();\n\n/*----------------------------------------------------------------------------*\n * Public-Facing Functionality\n *----------------------------------------------------------------------------*/\n//require_once plugin_dir_path( __FILE__ ) . 'public/class-lasso.php';\n\n$loader->addNamespace('lasso', LASSO_DIR . 'includes' );\n$loader->addNamespace('lasso_public_facing', LASSO_DIR . 'public/includes' );\n$loader->addNamespace('lasso\\internal_api', LASSO_DIR . 'internal-api' );\nnew lasso\\internal_api\\end_points();\n\nregister_activation_hook( __FILE__, array( 'lasso_public_facing\\lasso', 'activate' ) );\nregister_deactivation_hook( __FILE__, array( 'lasso_public_facing\\lasso', 'deactivate' ) );\n\nadd_action( 'plugins_loaded', array( 'lasso_public_facing\\lasso', 'get_instance' ) );\n\n//load tour\nadd_action(  'init', function() {\n\tif (! is_admin() && is_user_logged_in() ) {\n\t\tnew \\lasso_public_facing\\tour();\n\t}\n});\n\n\n/*----------------------------------------------------------------------------*\n * Dashboard and Administrative Functionality\n *----------------------------------------------------------------------------*/\n\nif ( is_admin() ) {\n\t$loader->addNamespace('lasso_admin', LASSO_DIR . 'admin/includes' );\n\tadd_action( 'plugins_loaded', array( 'lasso_admin\\load_admin', 'get_instance' ) );\n\n}\n"
  },
  {
    "path": "composer.json",
    "content": "{\n   \"name\": \"aesop/lasso\",\n   \"type\": \"wordpress-plugin\",\n   \"description\": \"Lasso Front-end Creator\",\n   \"homepage\": \"http://edituswp.com\",\n   \"license\": \"GPL-2.0+\",\n   \"keywords\": [\"plugin\",\"wordpress\",\"lasso\",\"editor\",\"hosted\"],\n   \"support\": {\n   \t\"issues\": \"https://github.com/AesopInteractive/lasso/issues\"\n   },\n   \"require\": {\n     \"composer/installers\": \"~1.0.6\"\n   }\n}"
  },
  {
    "path": "includes/lasso_autoloader.php",
    "content": "<?php\n/**\n * PSR-4 Autoloader\n *\n * Copied from http://www.php-fig.org/psr/psr-4/examples/\n *\n * @package   Lasso\n * @author    Josh Pollock <Josh@JoshPress.net>\n * @license   GPL-2.0+\n */\n\nclass lasso_autoloader {\n\t/**\n\t * An associative array where the key is a namespace prefix and the value\n\t * is an array of base directories for classes in that namespace.\n\t *\n\t * @var array\n\t */\n\tprotected $prefixes = array();\n\n\t/**\n\t * Register loader with SPL autoloader stack.\n\t *\n\t * @return void\n\t */\n\tpublic function register() {\n\t\tspl_autoload_register(array($this, 'loadClass'));\n\t}\n\n\t/**\n\t * Adds a base directory for a namespace prefix.\n\t *\n\t * @param string $prefix The namespace prefix.\n\t * @param string $base_dir A base directory for class files in the\n\t * namespace.\n\t * @param bool $prepend If true, prepend the base directory to the stack\n\t * instead of appending it; this causes it to be searched first rather\n\t * than last.\n\t * @return void\n\t */\n\tpublic function addNamespace($prefix, $base_dir, $prepend = false) {\n\t\t// normalize namespace prefix\n\t\t$prefix = trim($prefix, '\\\\') . '\\\\';\n\n\t\t// normalize the base directory with a trailing separator\n\t\t$base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/';\n\n\t\t// initialize the namespace prefix array\n\t\tif (isset($this->prefixes[$prefix]) === false) {\n\t\t\t$this->prefixes[$prefix] = array();\n\t\t}\n\n\t\t// retain the base directory for the namespace prefix\n\t\tif ($prepend) {\n\t\t\tarray_unshift($this->prefixes[$prefix], $base_dir);\n\t\t} else {\n\t\t\tarray_push($this->prefixes[$prefix], $base_dir);\n\t\t}\n\t}\n\n\t/**\n\t * Loads the class file for a given class name.\n\t *\n\t * @param string $class The fully-qualified class name.\n\t * @return mixed The mapped file name on success, or boolean false on\n\t * failure.\n\t */\n\tpublic function loadClass($class) {\n\t\t// the current namespace prefix\n\t\t$prefix = $class;\n\n\t\t// work backwards through the namespace names of the fully-qualified\n\t\t// class name to find a mapped file name\n\t\twhile (false !== $pos = strrpos($prefix, '\\\\')) {\n\n\t\t\t// retain the trailing namespace separator in the prefix\n\t\t\t$prefix = substr($class, 0, $pos + 1);\n\n\t\t\t// the rest is the relative class name\n\t\t\t$relative_class = substr($class, $pos + 1);\n\n\t\t\t// try to load a mapped file for the prefix and relative class\n\t\t\t$mapped_file = $this->loadMappedFile($prefix, $relative_class);\n\t\t\tif ($mapped_file) {\n\t\t\t\treturn $mapped_file;\n\t\t\t}\n\n\t\t\t// remove the trailing namespace separator for the next iteration\n\t\t\t// of strrpos()\n\t\t\t$prefix = rtrim($prefix, '\\\\');\n\t\t}\n\n\t\t// never found a mapped file\n\t\treturn false;\n\t}\n\n\t/**\n\t * Load the mapped file for a namespace prefix and relative class.\n\t *\n\t * @param string $prefix The namespace prefix.\n\t * @param string $relative_class The relative class name.\n\t * @return mixed Boolean false if no mapped file can be loaded, or the\n\t * name of the mapped file that was loaded.\n\t */\n\tprotected function loadMappedFile($prefix, $relative_class) {\n\t\t// are there any base directories for this namespace prefix?\n\t\tif (isset($this->prefixes[$prefix]) === false) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// look through base directories for this namespace prefix\n\t\tforeach ($this->prefixes[$prefix] as $base_dir) {\n\n\t\t\t// replace the namespace prefix with the base directory,\n\t\t\t// replace namespace separators with directory separators\n\t\t\t// in the relative class name, append with .php\n\t\t\t$file = $base_dir\n\t\t\t        . str_replace('\\\\', '/', $relative_class)\n\t\t\t        . '.php';\n\n\t\t\t// if the mapped file exists, require it\n\t\t\tif ($this->requireFile($file)) {\n\t\t\t\t// yes, we're done\n\t\t\t\treturn $file;\n\t\t\t}\n\t\t}\n\n\t\t// never found it\n\t\treturn false;\n\t}\n\n\t/**\n\t * If a file exists, require it from the file system.\n\t *\n\t * @param string $file The file to require.\n\t * @return bool True if the file exists, false if not.\n\t */\n\tprotected function requireFile($file) {\n\t\tif (file_exists($file)) {\n\t\t\trequire $file;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n}\n"
  },
  {
    "path": "includes/process/delete.php",
    "content": "<?php\n\n/**\n * This class is responsible for deleting apost through all-posts menu\n *\n * @since 0.9.3\n */\nnamespace lasso\\process;\nuse lasso\\internal_api\\api_action;\n\nclass delete implements api_action {\n\n\t/**\n\t * The nonce action for this request.\n\t *\n\t * @since 0.9.3\n\t *\n\t * @var string\n\t */\n\tpublic $nonce_action = 'lasso_delete_post';\n\n\n\t/**\n\t * Process the post delete\n\t *\n\t * @since 1.0\n\t */\n\tpublic function post( $data ) {\n\n\t\t$postid = isset( $data['postid'] ) ? $data['postid'] : false;\n\n\t\t// bail out if teh current user can't publish posts\n\t\tif ( !lasso_user_can( 'delete_post', $postid ) )\n\t\t\treturn;\n\n\t\t$args = array(\n\t\t\t'ID'   \t\t\t=> (int) $postid,\n\t\t\t'post_status' \t=> 'trash'\n\t\t);\n\n\t\twp_update_post( apply_filters( 'lasso_object_deleted_args', $args ) );\n\n\t\tdo_action( 'lasso_object_deleted', $postid, get_current_user_ID() );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $_POST per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_delete_post' ] = array(\n\t\t\t'postid' => 'absint',\n\t\t);\n\n\t\treturn $params;\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_delete_post' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n}"
  },
  {
    "path": "includes/process/gallery.php",
    "content": "<?php\n/**\n * Process various gallery fucntions like fetching and saving images\n *\n * @since 1.0\n */\nnamespace lasso\\process;\n\nuse lasso\\internal_api\\api_action;\nuse lasso\\save_gallery;\n\nclass gallery implements api_action {\n\n\t/**\n\t * The nonce action for this request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var string\n\t */\n\tpublic $nonce_action = 'lasso_gallery';\n\n\t/**\n\t * Swaps a gallery during live editing\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return array Key \"markup\" has the HTML.\n\t */\n\tpublic function swap( $data ) {\n\n\n\t\t$id = $data[ 'gallery_id' ];\n\t\tif ( is_null( $id ) ) {\n\t\t\t$id = false;\n\t\t}\n\n\t\t$markup = sprintf( '<div contenteditable=\"false\" class=\"lasso--empty-component aesop-component aesop-gallery-component\" data-component-type=\"gallery\" data-id=\"%s\">%s</div>', $id, __( 'Save and refresh to view gallery.','lasso' ) );\n\n\t\treturn array(\n\t\t\t'gallery' => $markup\n\t\t);\n\n\t}\n\n\t/**\n\t * Creates a gallery\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return array|bool On success an array containing \"message\" or on failure false.\n\t */\n\tpublic function create( $data ) {\n\n\t\t//@todo adapt auth callbacks to work with args.\n\t\tif (  ! lasso_user_can( 'publish_posts' ) ) {\n\t\t\treturn false;\n\n\t\t}\n\n\t\t$gallery_ids = isset( $data['gallery_ids'] ) ? $data['gallery_ids'] : false;\n\n\t\t// bail if no gallery ids\n\t\tif ( empty( $gallery_ids ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t$postid   \t\t = isset( $data['postid'] ) ? (int) $data['postid'] : false;\n\t\t$type   \t\t = isset( $data['gallery_type'] ) ? $data['gallery_type'] : false;\n\t\t$edgallerytitle\t = isset( $data['edgallerytitle'] ) ? $data['edgallerytitle'] : $postid.'-'.rand();\n\n\t\t// insert a new gallery\n\t\t$args = array(\n\t\t\t'post_title'    => $edgallerytitle ,\n\t\t\t'post_status'   => 'publish',\n\t\t\t'post_type'     => 'ai_galleries'\n\t\t);\n\n\t\t$postid = wp_insert_post( apply_filters( 'lasso_insert_gallery_args', $args ) );\n\n\t\t// update gallery ids\n\t\tif ( $gallery_ids ) {\n\n\t\t\tupdate_post_meta( $postid, '_ase_gallery_images', $gallery_ids );\n\n\t\t}\n\n\t\t// update the gallery type\n\t\tif ( !empty( $type ) ) {\n\n\t\t\tupdate_post_meta( $postid, 'aesop_gallery_type', $type );\n\n\t\t}\n\n\t\tdo_action( 'lasso_gallery_published', $postid, $gallery_ids, get_current_user_ID() );\n\n\t\treturn array(\n\t\t\t'message' => 'gallery-created',\n\t\t\t'id' => $postid\n\t\t);\n\n\t}\n\n\t/**\n\t * Update an existing gallery\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return array \"message\" key has the message.\n\t */\n\tpublic function update( $data ) {\n\n\t\t$options      = isset( $data['fields'] ) ? $data['fields'] : false;\n\t\t$postid   \t  = !empty( $options ) ? (int) $options['id'] : false;\n\t\t$gallery_ids  = isset( $data['gallery_ids'] ) ? $data['gallery_ids'] : false;\n\t\tif ( ! empty( $data ) && $data[ 'gallery_type' ] ) {\n\t\t\t$type = $data[ 'gallery_type' ];\n\t\t}elseif ( ! empty( $options ) && $options[ 'galleryType' ] ) {\n\t\t\t$type = $options[ 'galleryType' ];\n\t\t}else{\n\t\t\t$type = false;\n\t\t}\n\n\t\tsave_gallery::save_gallery_options( $postid, $gallery_ids, $options, $type );\n\n\t\treturn array(\n\t\t\t'message' => 'gallery-updated'\n\t\t);\n\n\t}\n\n\t/**\n\t * When the user clicks the settings icon in the gallery component it\n\t * opens the panel, gets the gallery unique, then makes a call to get the gallery images\n\t *\n\t * @since 0.12\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return bool\n\t */\n\tpublic function get_images( $data ) {\n\n\t\t//check caps\n\t\tif ( !current_user_can( 'edit_posts' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// bail if no id specified like on new galleries\n\t\tif ( is_null( $data['post_id'] ) || empty( $data['post_id'] ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t$postid  = isset( $data['post_id'] ) ? $data['post_id'] : false;\n\n\t\t// fetch image ids from cache\n\t\t$image_ids  = get_post_meta( $postid, '_ase_gallery_images', true );\n\n\t\t// send ids to return images\n\t\treturn self::get_the_images( $image_ids );\n\n\t}\n\n\t/**\n\t *  Return images for a specific gallery when the user goes to edit a gallery\n\t *\n\t * @param $image_ids array array of image ids\n\t * @since 0.1\n\t */\n\tprivate function get_the_images( $image_ids = '' ) {\n\n\t\tif ( empty( $image_ids ) )\n\t\t\treturn;\n\n\t\t$image_ids  = array_map( 'intval', explode( ',', $image_ids ) );\n\n\t\t$out[] = '<ul id=\"ase-gallery-images\">';\n\n\t\tif ( !empty( $image_ids ) ):\n\n\t\t\tforeach ( $image_ids as $image_id ) {\n\n\t\t\t\t$image    =  wp_get_attachment_image_src( $image_id, 'thumbnail', false );\n\n\t\t\t\t$out[] = sprintf( '\n\t\t        <li id=\"%1s\" class=\"ase-gallery-image\">\n\t\t        \t<i class=\"dashicons dashicons-no-alt\" title=\"%2s\"></i>\n\t\t        \t<i class=\"dashicons dashicons-edit\" title=\"%3s\"></i>\n\t\t           \t<img src=\"%4s\">\n\t\t        </li>\n\t\t       ',\n\t\t\t\t\tabsint( $image_id ),\n\t\t\t\t\t__( 'Delete From Gallery', 'lasso' ),\n\t\t\t\t\t__( 'Edit Image Caption', 'lasso' ),\n\t\t\t\t\tesc_url( $image[0] )\n\t\t\t\t);\n\n\t\t\t}\n\n\t\tendif;\n\n\t\t$out[] = '</ul>';\n\n\t\treturn array( 'html' => implode( '', $out ) );\n\n\t}\n\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $data per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_gallery_swap' ] = array(\n\t\t\t'gallery_id' => 'absint',\n\n\t\t);\n\n\t\t$params[ 'process_gallery_create' ] = array(\n\t\t\t'postid'   => 'absint',\n\t\t\t'content'   => 'wp_kses_post',\n\t\t\t'edgallerytitle' =>'sanitize_text_field',\n\t\t\t'gallery_type'      => array(\n\t\t\t\t'sanitize_text_field',\n\t\t\t\t'trim'\n\t\t\t),\n\t\t\t'gallery_ids'   => 'lasso_sanitize_data',\n\n\t\t);\n\n\t\t$params[ 'process_gallery_update' ] = array(\n\t\t\t'postid'        => 'absint',\n\t\t\t'gallery_ids'   => 'lasso_sanitize_data',\n\t\t\t'fields'        => 'lasso_sanitize_data',\n\t\t\t'gallery_type'      => array(\n\t\t\t\t'sanitize_text_field',\n\t\t\t\t'trim'\n\t\t\t)\n\t\t);\n\n\t\t$params[ 'process_gallery_get_images' ] = array(\n\t\t\t'post_id'       => 'absint'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_gallery_swap' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\t$params[ 'process_gallery_create' ] = array(\n\t\t\t'is_user_logged_in'\n\t\t);\n\n\t\t$params[ 'process_gallery_update' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\t$params[ 'process_gallery_get_images' ] = array();\n\n\t\treturn $params;\n\n\t}\n\n\n}\n\n"
  },
  {
    "path": "includes/process/map.php",
    "content": "<?php\n/**\n * Process saving a maps locations\n *\n * @since 1.0\n */\nnamespace lasso\\process;\n\nuse lasso\\internal_api\\api_action;\n\nclass map implements api_action {\n\n\t/**\n\t * The nonce action for this request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var string\n\t */\n\tpublic $nonce_action = 'lasso-process-map';\n\n\t/**\n\t *  Save the map locations and data\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return bool Always returns true.\n\t */\n\tpublic function save( $data ) {\n\n\t\t$postid     \t= isset( $data['postid'] ) ? $data['postid'] : false;\n\t\t$locations    \t= isset( $data['ase-map-component-locations'] ) ? $data['ase-map-component-locations'] : false;\n\t\t$start_point    = isset( $data['ase-map-component-start-point'] ) ? $data['ase-map-component-start-point']: false;\n\t\t$zoom       \t= isset( $data['ase-map-component-zoom'] ) ? $data['ase-map-component-zoom' ] : false;\n        \n\t\tif ( is_array( $locations ) ) {\n\t\t\tdelete_post_meta( $postid, 'ase_map_component_locations' );\n\n\t\t\t// update locations if set\n\t\t\tforeach ( $locations as $location ) {\n\t\t\t\t$point = json_decode( urldecode( $location ), true );\n\t\t\t\tadd_post_meta( $postid, 'ase_map_component_locations', $point );\n\t\t\t}\n\n\t\t\t// udpate start point\n            $point = json_decode( $start_point, true );\n\t\t\tupdate_post_meta( $postid, 'ase_map_component_start_point', $point );\n\n\t\t\t// update zoom\n\t\t\tupdate_post_meta( $postid, 'ase_map_component_zoom', $zoom );\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $_POST per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_map_save' ] = array(\n\t\t\t'postid' => 'absint',\n\t\t\t'ase-map-component-locations' => 'lasso_sanitize_data',\n\t\t\t'ase-map-component-start-point' => array(\n\t\t\t\t'json_decode',\n\t\t\t\t'urldecode'\n\t\t\t),\n\t\t\t'ase-map-component-zoom' => array(\n\t\t\t\t'json_decode',\n\t\t\t\t'urldecode'\n\t\t\t)\n\t\t);\n\n\t\treturn $params;\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_map_save' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\n}\n\n"
  },
  {
    "path": "includes/process/meta.php",
    "content": "<?php\n/**\n * Class responsible for processing optoins from lasso post meta api\n *\n * @since 1.0\n */\nnamespace lasso\\process;\n\nuse lasso\\internal_api\\api_action;\n\nclass meta implements api_action {\n\n\t/**\n\t * The nonce action for this request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var string\n\t */\n\tpublic $nonce_action = 'lasso-process-post-meta';\n\n\t/**\n\t * Process storing meta\n\t *\n\t * @since 0.9.5\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return bool Always returns true.\n\t */\n\tpublic function update( $data ) {\n\n\t\t$post_id = isset( $data['post_id'] ) ? $data['post_id'] : false;\n\n\t\t\t\n\t\t/**\n\t\t * Fields to allow for saving meta from.\n\t\t *\n\t\t * @since 0.9.5\n\t\t *\n\t\t * @param array $allowed_fields The fields\n\t\t */\n\t\t$allowed_fields = apply_filters( 'lasso_meta_fields', array() );\n        \n\t\tif ( ! empty( $allowed_fields ) ) {\n\t\t\tforeach( $allowed_fields as $field ) {\n\t\t\t\tif ( isset( $data[ $field ] ) ) {\n\t\t\t\t\t//this original line changed dash to underscore\n\t\t\t\t\t//update_post_meta( $post_id, lasso_unclean_string( $field ), $data[ $field ]  );\n\t\t\t\t\tupdate_post_meta( $post_id,  $field, $data[ $field ]  );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n        do_action( 'editus_after_meta_update', $post_id, $data );\n\n\n\t\treturn true;\n\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.5\n\t *\n\t * @return array Array of keys to pull from $data per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_meta_update' ] = array(\n\t\t\t'post_id' \t=> 'absint',\n\t\t\t'tab_name'\t=> 'trim'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.5\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_meta_update' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\n}\n\n"
  },
  {
    "path": "includes/process/new_object.php",
    "content": "<?php\n/**\n * Adds a new post object\n *\n * @since 1.0\n */\n\nnamespace lasso\\process;\n\nuse lasso\\internal_api\\api_action;\n\nclass new_object implements api_action {\n\n\t/**\n\t * The nonce action for this request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var string\n\t */\n\tpublic $nonce_action = 'lasso-editor-new-post';\n\n\n\t/**\n\t * Process the post object\n\t *\n\t * @params array $data Sanitized data to use for saving.\n\t *\n\t * @since 1.0\n\t */\n\tpublic function post( $data ) {\n\n\t\t$title  = $data[ 'story_title' ];\n\n\t\t$object = is_null( $data[ 'object'] ) ? false : $data[ 'object' ];\n        \n        $new_post_text    = lasso_editor_get_option( 'new_post_text', 'lasso_editor' );        \n        $new_post_text  = !empty($new_post_text) ? $new_post_text : wp_strip_all_tags(apply_filters( 'lasso_new_object_content', __( 'Once upon a time...','lasso')));\n\n\t\t// insert a new post\n\t\t$args = array(\n\t\t\t'post_title'    => $title,\n\t\t\t'post_status'   => 'draft',\n\t\t\t'post_type'    \t=> $object,\n\t\t\t'post_content'  =>'<p class=\"editus-firstp\" placeholder=\"'. $new_post_text. '\"></p>' \n\t\t);\n\n\t\t$postid = wp_insert_post( apply_filters( 'lasso_insert_object_args', $args ) );\n\n\t\tdo_action( 'lasso_new_object', $postid, $object, $title, get_current_user_ID() );\n\n\t\treturn array(\n\t\t\t'postlink' => get_permalink( $postid )\n\t\t);\n\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $_POST per action and their sanitization callback\n\t */\n\tpublic static function params() {\n\t\t$params[ 'process_new_object_post' ] = array(\n\t\t\t'story_title' => array( 'wp_strip_all_tags', 'trim' ),\n\t\t\t'object' => 'trim'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_new_object_post' ] = array();\n\n\t\treturn $params;\n\n\t}\n}\n\n"
  },
  {
    "path": "includes/process/revision.php",
    "content": "<?php\n\nnamespace lasso\\process;\n\n\nuse lasso\\internal_api\\api_action;\n\nclass revision implements api_action {\n\n\t/**\n\t * Array of revisions for a post\n\t *\n\t * @access protected\n\t *\n\t * @since 0.9.5\n\t *\n\t * @var array\n\t */\n\tprotected static $revisions = array();\n\n\t/**\n\t * Get revisions for a post\n\t *\n\t * @since 0.9.5\n\t *\n\t * @param array $data\n\t *\n\t * @return array\n\t */\n\tpublic static function get( $data ) {\n\t\t$args = array();\n\t\tif ( isset( $data[ 'limit' ] ) ) {\n\t\t\t$args[ 'posts_per_page' ] = $data[ 'limit' ];\n\t\t}else{\n\t\t\t$args[ 'posts_per_page' ] = 6; // we start at revision 0\n\t\t}\n\n\t\t$revisions = wp_get_post_revisions( $data[ 'postid' ], $args  );\n\t\tif ( is_array( $revisions )  && ! empty( $revisions )  ) {\n\t\t\tself::set_revisions( $data[ 'postid' ], $revisions );\n\t\t}\n\n\t\treturn self::$revisions;\n\t}\n\n\t/**\n\t * Set the revisions property\n\t *\n\t * @access protected\n\t *\n\t * @since 0.9.5\n\t *\n\t * @param int $id The post ID to get the revisions for\n\t * @param obj $revisions The revisions for this post\n\t */\n\tprotected static function set_revisions( $id, $revisions ) {\n\n\t\tarray_walk( $revisions, function ( $post, $i ) {\n\t\t\tself::$revisions[] = array(\n\t\t\t\t'post_content' => $post->post_content,\n\t\t\t\t'post_title' => $post->post_title,\n\t\t\t\t'modified_time' => mysql2date('g:i a', $post->post_modified),\n\t\t\t\t'modified_date' => mysql2date('F j, Y', $post->post_modified)\n\t\t\t);\n\t\t} );\n\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.5\n\t *\n\t * @return array Array of keys to pull from $_POST per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_revision_get' ] = array(\n\t\t\t'postid'    => 'absint',\n\t\t\t'limit'     => 'absint'\n\t\t);\n\n\t\treturn $params;\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.5\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_revision_get' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\n}\n"
  },
  {
    "path": "includes/process/save.php",
    "content": "<?php\n/**\n * Main class responsible for saving the post object\n *\n * @since 1.0\n */\nnamespace lasso\\process;\n\nuse lasso\\internal_api\\api_action;\n\nclass save implements api_action {\n\t\n\t/**\n\t * Process the post save\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return bool Always returns true.\n\t */\n\tpublic function content( $data ) {\n\n\t\t$save_to_post_disabled = $this->save_to_post_disables();\n\n\t\t$postid = (int) $data[ 'post_id' ];\n\t\t$content = $this->replace_rendered_shortcodes( $data[ 'content' ] );\n\t\t$content = $this->remove_comments( $content );\n\n\t\tif ( 'off' == $save_to_post_disabled || empty( $save_to_post_disabled ) ) {\n\n\t\t\t$args = array(\n\t\t\t\t'ID'           => (int) $postid,\n\t\t\t\t'post_content' => $content\n\t\t\t);\n\n\t\t\twp_update_post( apply_filters( 'lasso_object_save_args', $args ) );\n\n\t\t}\n\n\t\t// run save action\n\t\tdo_action( 'lasso_post_saved', $postid, $content, get_current_user_ID() );\n\n\t\treturn true;\n\n\t}\n\n\t/**\n\t * Process the post save\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return bool Always returns true.\n\t */\n\tpublic function publish_content( $data ) {\n\t\t$save_to_post_disabled = $this->save_to_post_disables();\n\n\t\t$postid = (int) $data[ 'post_id' ];\n\t\t$content = $this->replace_rendered_shortcodes( $data[ 'content' ] );\n\t\t$content = $this->remove_comments( $content );\n\n\t\tif ( 'off' == $save_to_post_disabled || empty( $save_to_post_disabled ) ) {\n\n\t\t\t$args = array (\n\t\t\t\t'ID'           \t=> $postid,\n\t\t\t\t'post_content' \t=> $content,\n\t\t\t\t'post_status' \t=> 'publish'\n\t\t\t);\n\t\t\twp_update_post( apply_filters( 'lasso_object_publish_args', $args ) );\n\n\t\t}\n\n\t\tdo_action( 'lasso_post_published', $postid, $content, get_current_user_ID() );\n\n\t\treturn true;\n\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $_POST per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_save_content' ] = array(\n\t\t\t'post_id' => 'absint',\n\t\t\t'content' => 'wp_kses_post'\n\t\t);\n\n\t\t$params[ 'process_save_publish_content' ] = array(\n\t\t\t'post_id' => 'absint',\n\t\t\t'content' => 'wp_kses_post'\n\t\t);\n\n\t\treturn $params;\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_save_content' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\t$params[ 'process_save_publish_content' ] = array();\n\n\t\treturn $params;\n\n\t}\n\n\t/**\n\t * Check if saving post is disabled.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @return bool\n\t */\n\tprotected function save_to_post_disables() {\n\t\t$save_to_post_disabled = lasso_editor_get_option( 'post_save_disabled', 'lasso_editor' );\n\n\t\treturn $save_to_post_disabled;\n\n\t}\n\n\t/**\n\t * Replace shortcodes from other plugins with shortcode tags.\n\t *\n\t * @since 0.9.9\n\t *\n\t * @access protected\n\t *\n\t * @param string $content\n\t *\n\t * @return string\n\t */\n\tprotected function replace_rendered_shortcodes( $content ) {\n\t\t//debug line\n        //file_put_contents(WP_PLUGIN_DIR.\"/file1.txt\", $content);\n\t\t\n\n\t\tif ( false === strpos( $content, '--EDITUS_OTHER_SHORTCODE_START|' ) ) {\n\t\t\treturn $content;\n\t\t}\n\t\t$content = htmlspecialchars_decode ($content);\n\n\t\t$content = preg_replace(\n\t\t\t'/<!--EDITUS_OTHER_SHORTCODE_START\\|\\[(.*?)\\]-->(.*?)<!--EDITUS_OTHER_SHORTCODE_END-->/s',\n\t\t\t'$1',\n\t\t\t$content\n\t\t);\n\n\t\treturn $content;\n\t}\n\t\n\tprotected function remove_comments($content) {\n\t\treturn preg_replace('/<!--(.*)-->/Uis', '', $content);\n\t}\n\n}\n"
  },
  {
    "path": "includes/process/title_update.php",
    "content": "<?php\n/**\n * Class responsible for processing the post title change\n *\n * @since 1.0\n */\nnamespace lasso\\process;\n\nuse lasso\\internal_api\\api_action;\n\nclass title_update implements api_action {\n\n\t/**\n\t * The nonce action for this request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var string\n\t */\n\tpublic $nonce_action = 'lasso_update_title';\n\n\t/**\n\t * Process title update\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return bool Always returns true.\n\t */\n\tpublic function post( $data ) {\n\n\t\t$postid = isset( $data['postid'] ) ? $data['postid'] : false;\n\t\t$title  = isset( $data['title'] ) ? $data['title'] : false;\n\n\t\t$args = array(\n\t\t\t'ID'   => (int) $postid,\n\t\t\t'post_title'    => wp_strip_all_tags( $title )\n\t\t);\n\n\t\twp_update_post( apply_filters( 'lasso_title_updated_args', $args ) );\n\n\t\tdo_action( 'lasso_title_updated', $postid, $title, get_current_user_ID() );\n\n\t\treturn true;\n\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $data per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_title_update_post' ] = array(\n\t\t\t'postid' => 'absint',\n\t\t\t'title' => 'strip_tags'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_title_update_post' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\n}\n\n"
  },
  {
    "path": "includes/process/tour.php",
    "content": "<?php\n/**\n * Class responsible for creating the welcome walkthrough on the editor\n *\n * @since 0.6\n */\n\nnamespace lasso\\process;\nuse lasso\\internal_api\\api_action;\n\nclass tour implements api_action {\n\n\t/**\n\t * The nonce action for this request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var string\n\t */\n\tpublic $nonce_action = 'lasso-editor-tour';\n\n\t/**\n\t * When the user decides to not have this show again save user meta to make it so.\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @returns bool Always returns true\n\t */\n\tpublic function hide( $data ) {\n\n\t\t$user_id = get_current_user_ID();\n\n\t\tupdate_user_meta( $user_id, 'lasso_hide_tour', true );\n\n\t\tdo_action( 'lasso_tour_hidden', $user_id );\n\n\t\treturn true;\n\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $_POST per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_tour_hide' ] = array(\n\t\t\t'action'\n\t\t);\n\n\t\treturn $params;\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_tour_hide' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n}\n\n"
  },
  {
    "path": "includes/process/update_object.php",
    "content": "<?php\n/**\n * This class is responsible for updating the post settings such as the post slug or post status\n * and is toggle from the post settings modal\n *\n * @since 1.0\n */\nnamespace lasso\\process;\n\nuse lasso\\internal_api\\api_action;\n\nclass update_object implements api_action{\n\n\t/**\n\t * The nonce action for this request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var string\n\t */\n\tpublic $nonce_action = 'lasso-update-post-settings';\n\n\t/**\n\t * Process the post update\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return bool Always returns true.\n\t */\n\tpublic function post( $data ) {\n\n\t\t$status = isset( $data['status'] ) ? $data['status'] : false;\n\t\t$postid = isset( $data['postid'] ) ? $data['postid'] : false;\n\t\t$slug   = isset( $data['story_slug'] ) ? $data['story_slug'] : false;\n\n\n\n\t\t$args = array(\n\t\t\t'ID'   \t\t\t=> (int) $postid,\n\t\t\t'post_name'  \t=> $slug,\n\t\t\t'post_status' \t=> $status\n\t\t);\n\n\t\twp_update_post( apply_filters( 'lasso_object_status_update_args', $args ) );\n\n\n\t\t// update categories\n\t\t$cats  = isset( $data['story_cats'] ) ? $data['story_cats'] : false;\n\t\tself::set_post_terms( $postid, $cats, 'category' );\n\n\n\t\t// update tags\n\t\t$tags = isset( $data['story_tags'] ) ? $data['story_tags'] : false;\n\t\tself::set_post_terms( $postid, $tags, 'post_tag' );\n\t\t\n\t\t// update custom taxonomy\n\t\t$taxs  = isset( $data['story_custom_taxonomy'] ) ? $data['story_custom_taxonomy'] : false;\n\t\tself::set_custom_taxonomy( $postid, $taxs );\n\t\t\n\t\t//update date\n\t\t$date  = isset( $data['post_date'] ) ? $data['post_date'] : false;\n\t\tself::set_date( $postid, $date );\n\n\n\t\tdo_action( 'lasso_post_updated', $postid, $slug, $status, get_current_user_ID() );\n\n\t\treturn true;\n\n\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $_POST per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_update_object_post' ] = array(\n\t\t\t'postid' => 'absint',\n\t\t\t'status' => 'strip_tags',\n\t\t\t'story_slug' => array(\n\t\t\t\t'trim',\n\t\t\t\t'sanitize_title'\n\t\t\t),\n\t\t\t'story_cats' => array(\n\t\t\t\t'trim',\n\t\t\t\t'strip_tags',\n\t\t\t),\n\t\t\t'story_tags' => array(\n\t\t\t\t'trim',\n\t\t\t\t'strip_tags',\n\t\t\t),\n\t\t\t'story_custom_taxonomy' => array(\n\t\t\t\t'trim',\n\t\t\t\t'strip_tags',\n\t\t\t),\n\t\t\t'post_date' => array(\n\t\t\t\t'trim',\n\t\t\t\t'strip_tags',\n\t\t\t),\n\n\t\t);\n\n\n\t\treturn $params;\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params[ 'process_update_object_post' ] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\n\n\t\treturn $params;\n\n\t}\n\n\n\t/**\n\t *  Update terms for post.\n\t *\n\t *  @since    0.9.3\n\t *\n\t *  @param    int    \t$postid       \tThe current postid\n     *  @param    string|bool     $value    The term slug, or a comma separated list of slugs. Or false to remove all terms set for post.\n\t *  @param    string     $taxonomy    \tThe name of the taxonomy to which the term belongs.\n\t *\n\t *  @return bool True if update was successful, false if not.\n\t */\n\tpublic function set_post_terms( $postid, $value, $taxonomy ) {\n\t\tif( $value ) {\n\t\t\t// first check if multiple, make array if so.\n\t\t\tif ( self::has_multiple_objects( $value ) ) {\t\n\t\t\t\t$value = explode( ',', $value );\n\t\t\t}\n\t\t\t\n\t\t\tif ($taxonomy =='category') {\n                // convert from names to category ids\n\t\t\t\t$cats = array();\n\t\t\t\tif (is_array($value)) {\n\t\t\t\t\tforeach ($value as $cat) {\n\t\t\t\t\t\t$cats [] = get_cat_ID($cat);\n\t\t\t\t\t}\n\t\t\t\t\t$value = $cats;\n\t\t\t\t} else {\n\t\t\t\t\t$value = get_cat_ID($value);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t$result = wp_set_object_terms( $postid, $value, $taxonomy );\n\t\t}\n\t\telse  {\n\t\t\t//remove all terms from post\n\t\t\t$result = wp_set_object_terms( $postid, null, $taxonomy );\n\n\t\t}\n\n\t\tif ( ! is_wp_error( $result ) ) {\n\t\t\treturn true;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\t\n\t/**\n\t *  Update terms for post.\n\t *\n\t *\n\t *  @param    int    \t$postid       \tThe current postid\n     *  @param    string|bool     $value    The term slug, or a comma separated list of slugs. Or false to remove all terms set for post.\n\t *                                      The first item is the name of taxonomy\n\t *\n\t *  @return bool True if update was successful, false if not.\n\t */\n\tpublic function set_custom_taxonomy( $postid, $value) {\n\t\t\n\t\tif( $value ) {\n\t\t\t// first check if multiple, make array if so.\n\t\t\tif ( self::has_multiple_objects( $value ) ) {\t\n\t\t\t\t$value = explode( ',', $value );\n\t\t\t}\n\t\t\t\t\t\t\n            // Deleting first array item\n\t\t\t$taxonomy = array_shift($value);\n\t\t\t$cats = array();\n\t\t\tforeach ($value as $cat) {\n\t\t\t\t$cats [] = get_cat_ID($cat);\n\t\t\t}\n\t\t\t$value = $cats;\n\t\t\t\n\t\n\t\t\t$result = wp_set_object_terms( $postid, $cats, $taxonomy );\n\t\t\tif ( ! is_wp_error( $result ) ) {\n\t\t\t\treturn true;\n\t\t\t}else{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic function set_date( $postid, $value) {\n\t\t\n\t\tif( $value ) {\n\t\t\t$time = current_time('mysql');\n            wp_update_post(\n\t\t\t\tarray (\n\t\t\t\t\t'ID'            => $postid, // ID of the post to update\n\t\t\t\t\t'post_date'     => date( 'Y-m-d H:i:s',  strtotime($value) ),\n\t\t\t\t\t'post_date_gmt'     => gmdate( 'Y-m-d H:i:s',  strtotime($value) ),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t *  Determines if the given value has multiple terms by checking to see\n\t *  if a comma exists in the value.\n\t *\n\t *  @param    string   $value    The value to evaluate for multiple terms.\n\t *  @return   bool               True if there are multiple terms; otherwise, false.\n\t *\t@since   0.9.3\n\t */\n\tpublic function has_multiple_objects( $value ) {\n\n\t\treturn 0 < strpos( $value, ',' );\n\n\t}\n\n\n}\n\n"
  },
  {
    "path": "includes/process/upload_image.php",
    "content": "<?php\n/**\n * Process a user uploading an image for the featured image in a post\n *\n * @since 1.0\n */\nnamespace lasso\\process;\n\nuse lasso\\internal_api\\api_action;\n\nclass upload_image implements api_action {\n\n\t/**\n\t * The nonce action for this request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var string\n\t */\n\tpublic $nonce_action = 'lasso_gallery';\n\n\t/**\n\t *  Set the post thumbnail when the user sets it on the front end\n\t *\n\t * @since 0.1\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return bool Always returns true.\n\t */\n\tpublic function upload( $data ) {\n\n\t\t$postid  \t= isset( $data['postid'] ) ? $data['postid'] : false;\n\t\t$image_id  \t= isset( $data['image_id'] ) ? absint( $data['image_id'] ) : false;\n\n\t\tset_post_thumbnail( $postid, $image_id );\n\n\t\tdo_action( 'lasso_featured_image_set', $postid, $image_id, get_current_user_ID() );\n\n\t\treturn true;\n\n\t}\n\n\t/**\n\t *  Delete the post thumbnail when deleted from front end\n\t *\n\t * @since 0.1\n\t *\n\t * @param array $data Sanitized data to use for saving.\n\t *\n\t * @return bool Always returns true.\n\t */\n\tpublic function delete( $data ) {\n\n\t\t$postid  = isset( $data['postid'] ) ? $data['postid'] : false;\n\n\t\tdelete_post_thumbnail( $postid );\n\n\t\tdo_action( 'lasso_featured_image_deleted', $postid, get_current_user_ID() );\n\n\t\treturn true;\n\n\t}\n\n\t/**\n\t * The keys required for the actions of this class.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $data per action and their sanitization callback\n\t */\n\tpublic static function params(){\n\t\t$params[ 'process_upload_image_upload' ] = array(\n\t\t\t'postid' => 'absint',\n\t\t\t'image_id' => 'absint'\n\t\t);\n\n\t\t$params[ 'process_upload_image_delete' ] = array(\n\t\t\t'postid' => 'absint',\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\n\t/**\n\t * Additional auth callbacks to check.\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action.\n\t */\n\tpublic static function auth_callbacks() {\n\t\t$params['process_image_upload']['process_image_delete'] = array(\n\t\t\t'lasso_user_can'\n\t\t);\n\n\t\treturn $params;\n\n\t}\n\t\n}\n"
  },
  {
    "path": "includes/sanatize.php",
    "content": "<?php\n/**\n * Generic sanitization, useful for sanitization of arrays.\n *\n * The code in this class is largely lifted from Pods (http://Pods.io), which is copyrighted by The Pods Foundation and licensed under the GPL. Muchas Gracias.\n *\n * @package   lasso\n * @author    Josh Pollock <Josh@JoshPress.net>\n * @license   GPL-2.0+\n * @link\n * @copyright 2014 Josh Pollock\n */\n\nnamespace lasso;\n\n\nclass sanatize {\n\n\n\t/**\n\t * Filter input and return sanitized output\n\t *\n\t * @param mixed $input The string, array, or object to sanitize\n\t * @param array $params Additional options\n\t *\n\t * @return array|mixed|object|string|void\n\t *\n\t * @since 1.1.10\n\t *\n\t */\n\tpublic static function do_sanitize( $input, $params = array() ) {\n\n\t\t$input = stripslashes_deep( $input );\n\n\t\tif ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) {\n\t\t\treturn $input;\n\t\t}\n\n\t\t$output = array();\n\n\t\t$defaults = array(\n\t\t\t'nested' => false,\n\t\t\t'type' => null // %s %d %f etc\n\t\t);\n\n\t\tif ( !is_array( $params ) ) {\n\t\t\t$defaults[ 'type' ] = $params;\n\n\t\t\t$params = $defaults;\n\t\t}\n\t\telse {\n\t\t\t$params = array_merge( $defaults, (array) $params );\n\t\t}\n\n\t\tif ( is_object( $input ) ) {\n\t\t\t$input = get_object_vars( $input );\n\n\t\t\t$n_params = $params;\n\t\t\t$n_params[ 'nested' ] = true;\n\n\t\t\tforeach ( $input as $key => $val ) {\n\t\t\t\t$output[ self::do_sanitize( $key ) ] = self::do_sanitize( $val, $n_params );\n\t\t\t}\n\n\t\t\t$output = (object) $output;\n\t\t}\n\t\telseif ( is_array( $input ) ) {\n\t\t\t$n_params = $params;\n\t\t\t$n_params[ 'nested' ] = true;\n\n\t\t\tforeach ( $input as $key => $val ) {\n\t\t\t\t$output[ self::do_sanitize( $key ) ] = self::do_sanitize( $val, $n_params );\n\t\t\t}\n\t\t}\n\t\telseif ( !empty( $params[ 'type' ] ) && false !== strpos( $params[ 'type' ], '%' ) ) {\n\t\t\t/**\n\t\t\t * @var $wpdb wpdb\n\t\t\t */\n\t\t\tglobal $wpdb;\n\n\t\t\t$output = $wpdb->prepare( $params[ 'type' ], $output );\n\t\t}\n\t\telse {\n\t\t\t$output = wp_slash( $input );\n\t\t}\n\n\t\treturn $output;\n\n\t}\n\n\t/**\n\t * Filter input and return sanitized SQL LIKE output\n\t *\n\t * @param mixed $input The string, array, or object to sanitize\n\t *\n\t * @return array|mixed|object|string|void\n\t *\n\t * @since 1.1.10\n\t *\n\t * @see like_escape\n\t */\n\tpublic static function sanitize_like( $input ) {\n\n\t\tif ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) {\n\t\t\treturn $input;\n\t\t}\n\n\t\t$output = array();\n\n\t\tif ( is_object( $input ) ) {\n\t\t\t$input = get_object_vars( $input );\n\n\t\t\tforeach ( $input as $key => $val ) {\n\t\t\t\t$output[ $key ] = self::sanitize_like( $val );\n\t\t\t}\n\n\t\t\t$output = (object) $output;\n\t\t}\n\t\telseif ( is_array( $input ) ) {\n\t\t\tforeach ( $input as $key => $val ) {\n\t\t\t\t$output[ $key ] = self::sanitize_like( $val );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tglobal $wpdb;\n\n\t\t\t//backwords-compat check for pre WP4.0\n\t\t\tif ( method_exists( 'wpdb', 'esc_like' ) ) {\n\t\t\t\t$output = $wpdb->esc_like( self::do_sanitize( $input ) );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// like_escape is deprecated in WordPress 4.0\n\t\t\t\t$output = like_escape( self::do_sanitize( $input ) );\n\t\t\t}\n\t\t}\n\n\t\treturn $output;\n\n\t}\n\n\n\t/**\n\t * Filter input and return unslashed output\n\t *\n\t * @param mixed $input The string, array, or object to unsanitize\n\t *\n\t * @return array|mixed|object|string|void\n\t *\n\t * @since 1.1.10\n\t *\n\t * @see wp_unslash\n\t */\n\tpublic static function unslash( $input ) {\n\n\t\tif ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) {\n\t\t\treturn $input;\n\t\t}\n\n\t\t$output = array();\n\n\t\tif ( empty( $input ) ) {\n\t\t\t$output = $input;\n\t\t}\n\t\telseif ( is_object( $input ) ) {\n\t\t\t$input = get_object_vars( $input );\n\n\t\t\tforeach ( $input as $key => $val ) {\n\t\t\t\t$output[ $key ] = self::unslash( $val );\n\t\t\t}\n\n\t\t\t$output = (object) $output;\n\t\t}\n\t\telseif ( is_array( $input ) ) {\n\t\t\tforeach ( $input as $key => $val ) {\n\t\t\t\t$output[ $key ] = self::unslash( $val );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t$output = wp_unslash( $input );\n\n\t\t}\n\n\t\treturn $output;\n\n\t}\n\n\n}\n"
  },
  {
    "path": "includes/save_gallery.php",
    "content": "<?php\n/**\n * Process various gallery fucntions like fetching and saving images\n *\n * @since 1.0\n */\nnamespace lasso;\n\nclass save_gallery {\n\n\n\t/**\n\t * Update an existing galleries options\n\t */\n\tpublic static function save_gallery_options( $postid, $gallery_ids, $options, $type = false ) {\n\n\t\t// gallery width\n\t\t$gallery_width = isset( $options['width'] ) ? $options['width'] : false;\n\n\t\t// gallery grid item width\n\t\t$item_width = isset( $options['itemwidth'] ) ? $options['itemwidth'] : false;\n\n\t\t// caption\n\t\t$caption = isset( $options['caption'] ) ? $options['caption'] : false;\n\n\t\t// gallery transition\n\t\t$transition = isset( $options['transition'] ) ? $options['transition'] : false;\n\n\t\t// gallery transition speed\n\t\t$transitionSpeed = isset( $options['speed'] ) ? $options['speed'] : false;\n\n\t\t// gallery hide thumbs\n\t\t$hideThumbs = isset( $options['hideThumbs'] ) ? $options['hideThumbs'] : false;\n\n\t\t// photoset layout hardwired to on for now\n\t\t$psLayout = isset( $options['pslayout'] ) ? $options['pslayout'] : false;\n\n\t\t// photoset layout\n\t\t$psLightbox = 'on';//isset( $options['pslightbox'] ) ? $options['pslightbox'] : false;\n\t\t\n\t\t// hero gallery height\n\t\t$gallery_height = isset( $options['height'] ) ? $options['height'] : false;\n\n\t\t// update gallery ids\n\t\tif ( !empty( $gallery_ids ) ) {\n\n\t\t\tupdate_post_meta( $postid, '_ase_gallery_images', $gallery_ids );\n\n\t\t}\n\n\t\tupdate_post_meta( $postid, 'aesop_gallery_type', sanitize_text_field( trim( $type ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_gallery_width', sanitize_text_field( trim( $gallery_width ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_grid_gallery_width', sanitize_text_field( trim( $item_width ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_gallery_caption', sanitize_text_field( trim( $caption ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_thumb_gallery_transition', sanitize_text_field( trim( $transition ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_thumb_gallery_transition_speed', absint( trim( $transitionSpeed ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_thumb_gallery_hide_thumbs', sanitize_text_field( trim( $hideThumbs ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_photoset_gallery_layout', sanitize_text_field( trim( $psLayout ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_photoset_gallery_lightbox', sanitize_text_field( trim( $psLightbox ) ) );\n\t\t\n\t\tupdate_post_meta( $postid, 'aesop_hero_gallery_height', sanitize_text_field( trim( $gallery_height ) ) );\n\t\t\n\t\t//hardwired for now\n\t\t\n\t\tupdate_post_meta( $postid, 'aesop_hero_gallery_transition_speed', 300 );\n\n\t}\n\n}\n\n"
  },
  {
    "path": "internal-api/api_action.php",
    "content": "<?php\n/**\n * Interface that all classes used as callbacks for internal API must implement.\n *\n * @since     0.9.2\n * @package   lasso\n * @author    Josh Pollock <Josh@JoshPress.net>\n * @license   GPL-2.0+\n */\n\nnamespace lasso\\internal_api;\n\n\ninterface api_action {\n\n\t/**\n\t * An array, keyed by action name, of params (IE keys of $_POST) and their sanitization callback to pass back to callback.\n\t *\n\t * Function should return an array fo arrays in the form of 'POST_var' => 'sanitization_callback'. For example <code>$params[ 'process_save_post' ] = array( 'post_id' => 'absint', 'content' => 'wp_kses_post' );\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of keys to pull from $_POST per action\n\t */\n\tpublic static function params();\n\n\t/**\n\t * An array, keyed by action name, of callback functions, in addition to the nonce check, to run.\n\t *\n\t * Function should return an array of additional callback functions. For example, '<code>$cb[ 'process_save_post' ] = array( 'lasso_user_can' );</code>\n\t *\n\t * @since     0.9.2\n\t *\n\t * @return array Array of additional functions to use to authorize action. Or an empty array.\n\t */\n\tpublic static function auth_callbacks();\n\n\n}\n"
  },
  {
    "path": "internal-api/auth.php",
    "content": "<?php\n/**\n * Check if a request is authorized.\n *\n * @package   lasso\n * @author    Josh Pollock <Josh@JoshPress.net>\n * @license   GPL-2.0+\n */\n\nnamespace lasso\\internal_api;\n\n\nclass auth {\n\n\t/**\n\t * Instance of callback class\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @var object|string\n\t */\n\tprotected $callback_instance;\n\n\t/**\n\t * Status code set based on auth checks.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var int\n\t */\n\tpublic $status_code;\n\n\n\t/**\n\t * An error message.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var string\n\t */\n\tpublic $error_message;\n\n\t/**\n\t * Constructor for this class\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param string $action The AJAX action we are processing.\n\t * @param string|object $callback_class The class to use for the callback. Either the name of the class or an instance of that class.\n\t * @param string $method The name of the callback method.\n\n\t */\n\tpublic function __construct( $action, $callback_class) {\n\t\tif ( ! is_object( $callback_class ) ) {\n\t\t\t$this->callback_instance = new $callback_class;\n\t\t}else{\n\t\t\t$this->callback_instance = $callback_class;\n\t\t}\n\n\t\tif ( $this->check_nonce() ) {\n\t\t\tif ( is_object( $this->callback_instance ) && $this->if_implements() ) {\n\t\t\t\tif ( $this->other_auth_checks( $action ) ) {\n\t\t\t\t\t$this->status_code = 200;\n\t\t\t\t} else {\n\t\t\t\t\t$this->error_message = __( 'Unauthorized action', 'lasso' );\n\t\t\t\t\t$this->status_code   = 401;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$this->error_message = __( 'All callback classes used for processing the Editus Internal API must implement the lasso\\internal_api\\api_action interface.', 'lasso' );\n\t\t\t\t$this->status_code   = 401;\n\t\t\t}\n\t\t} else {\n\t\t\t$this->status_code   = 401;\n\t\t\t$this->error_message = __( 'Nonce invalid', 'lasso' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Run other auth checks, besides nonce check as defined by the auth_callbacks() method of callback class\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @param string $action The AJAX action we are processing.\n\t *\n\t * @return bool True if auth checks were all postive.\n\t */\n\tprotected function other_auth_checks( $action ) {\n\t\t$auth_callbacks = $this->callback_instance->auth_callbacks();\n\n\t\tif ( is_array( $auth_callbacks ) && isset( $auth_callbacks[ $action ] ) && is_array( $auth_callbacks[ $action ] ) ) {\n\t\t\t$checks = $auth_callbacks[ $action ];\n\t\t\tif ( is_array( $checks ) ) {\n\t\t\t\tforeach ( $checks as $check ) {\n\t\t\t\t\tif ( is_array( $check ) ) {\n\t\t\t\t\t\t$check = call_user_func( array( $check[0], $check[1] ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$check = call_user_func( $check );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( false === $check ) {\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\t/**\n\t * Check if callback class implements the lasso\\internal_api\\api_action interface\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @return bool\n\t */\n\tprotected function if_implements() {\n\n\t\t$implements = class_implements( $this->callback_instance );\n\t\tif ( is_array( $implements ) && in_array( 'lasso\\internal_api\\api_action', $implements ) ) {\n\t\t\treturn true;\n\n\t\t}\n\n\n\n\t}\n\n\t/**\n\t * Verify that the nonce is valid\n\t *\n\t * @since 0.0.1\n\t *\n\t * @access protected\n\t *\n\t * @return bool\n\t */\n\tprotected function check_nonce() {\n\t\tif ( isset( $this->callback_instance->nonce_action ) ) {\n\t\t\t$nonce = $this->callback_instance->nonce_action;\n\t\t}else{\n\t\t\t$nonce = 'lasso_editor';\n\t\t}\n\n\t\treturn wp_verify_nonce( $_POST[ 'nonce' ], $nonce );\n\n\t}\n\n}\n"
  },
  {
    "path": "internal-api/docs.md",
    "content": "# How Internal API Works\n\n* All requests must be sent to the URL `home_url( 'internal-api' );`.\n* All requests must use the POST transport method.\n* Callback class and method is determined by the action (e.g. `_$POST[ 'action' ]` ).\n* The action must be in the form of `'namespace_class_method'`:\n    * namespace is a subnamespace of the lasso namespace. For example, if the action is `'foo_bar_hats'`, then the class used will be `\\lasso\\foo\\bar`,\n    * class refers to the class used to process request,\n    * method refers to the method in that class used to process request, or\n    * if the class or method names have underscores (_) in them, then a single dash (-) should be used instead.\n        * For example, if the class is `lasso\\hats\\foo_bar`, and the callback method is `bar_foo` then the action would be `hats_foo-bar_bar-foo`.\n* The class used to process the request must implement the `lasso\\internal_api\\api_action` interface. The inline docs of that interface make the requirements clear.\n* The class used to process may optionally specify a nonce action to be used as the second param of `wp_verify_nonce()`, by declaring a public property called `nonce_action`. If this property is not set then the nonce action will be assumed to \"lasso_editor\".\n* All nonces must be transmitted in $_POST[ 'nonce' ]\n* The method used to process the request must return an array or true on success.\n* The method used to process the request must return false or null on failure.\n"
  },
  {
    "path": "internal-api/end_points.php",
    "content": "<?php\n/**\n * Add hooks for internal API.\n *\n * @package   lasso\n * @author    Josh Pollock <Josh@JoshPress.net>\n * @license   GPL-2.0+\n */\n\nnamespace lasso\\internal_api;\n\n\nclass end_points {\n\n\t/**\n\t * Constructor for this class.\n\t *\n\t * Adds our API endpoint and hooks it in at template_redirect\n\t */\n\tpublic function __construct() {\n\t\tadd_action( 'init', array( $this, 'add_endpoints' ) );\n\t\tadd_action( 'template_redirect', array( route::init(), 'do_api' ) );\n\t}\n\n\t/**\n\t * Add endpoints for the API\n\t *\n\t * @uses \"init\" action\n\t */\n\tpublic function add_endpoints() {\n\t\t//add \"action\" as a rewrite tag\n\t\tadd_rewrite_tag( '%action%', '^[a-z0-9_\\-]+$' );\n\n\t\t//add the endpoint\n\t\tadd_rewrite_rule( 'lasso-internal-api/^[a-z0-9_\\-]+$/?', 'index.php?action=$matches[1]', 'top' );\n\n\t}\n}\n"
  },
  {
    "path": "internal-api/find_data.php",
    "content": "<?php\n/**\n * Find data & sanatize data for this request.\n *\n * @package   lasso\n * @author    Josh Pollock <Josh@JoshPress.net>\n * @license   GPL-2.0+\n */\n\nnamespace lasso\\internal_api;\n\n\nclass find_data {\n\n\n\t/**\n\t * Sanatized data for this request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @var array\n\t */\n\tpublic $data;\n\n\t/**\n\t *\n\t * @since 0.9.2\n\t *\n\t * @param object $callback_instance Callback class.\n\t * @param string $action The name of the action we are processing for.\n\t */\n\tpublic function __construct( $callback_instance, $action ) {\n\t\tif ( is_object( $callback_instance ) ) {\n\t\t\t$this->get_data( $callback_instance, $action );\n\t\t}\n\n\t}\n\n\n\t/**\n\t * Get necessary data from $_POST and sanatizes it.\n\t *\n\t * Sets $this->data;\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @param object $callback_instance Callback class.\n\t * @param string $action The name of the action we are processing for.\n\t */\n\tprotected function get_data( $callback_instance, $action ) {\n\t\t$data = array();\n\t\tif ( is_array( $_POST ) ) {\n\t\t\t$params = $callback_instance::params();\n\n\t\t\t/**\n\t\t\t * Add fields that can be saved.\n\t\t\t *\n\t\t\t * @since 0.9.5\n\t\t\t *\n\t\t\t * @param array $params Array of params in form of $params[ 'action_name' ][ 'POST_field' ] = 'callback_function_for_sanatizing' ]\n\t\t\t */\n\t\t\t$params = apply_filters( 'lasso_api_params', $params );\n\t\t\tif ( is_array( $params ) && isset( $params[ $action ] ) && is_array( $params[ $action ] ) ) {\n\t\t\t\t$params = $params[ $action ];\n\t\t\t\tforeach( $params as $key => $callback ) {\n\t\t\t\t\t$_data = null;\n\t\t\t\t\tif ( is_array( $callback ) ) {\n\t\t\t\t\t\tforeach( $callback as $cb ) {\n\t\t\t\t\t\t\t$_data = $this->sanitize( $key, $cb );\n\t\t\t\t\t\t}\n\t\t\t\t\t}else{\n\t\t\t\t\t\t$_data = $this->sanitize( $key, $callback );\n\t\t\t\t\t}\n\n\t\t\t\t\t$data[ $key ] = $_data;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t$this->data = $data;\n\n\t}\n\n\t/**\n\t * Sanitize a $_POST key\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @param string $key The key of _$POST to sanitize.\n\t * @param string|array $cb The name of callback functions, or an array fo callback functions to do Sanitization.\n\t *\n\t * @return string|null Sanitized data or null.\n\t */\n\tprotected function sanitize( $key, $cb ) {\n\t\t$_data = null;\n\t\tif ( isset( $_POST[ $key ] ) ) {\n\t\t\tif ( function_exists( $cb ) ) {\n\t\t\t\t$_data = call_user_func( $cb, $_POST[ $key ] );\n\n\t\t\t\treturn $_data;\n\n\t\t\t}\n\n\t\t\treturn $_data;\n\n\t\t}\n\n\t\treturn $_data;\n\t}\n\n}\n"
  },
  {
    "path": "internal-api/route.php",
    "content": "<?php\n/**\n * Route the requests\n *\n * @package   lasso\n * @author    Josh Pollock <Josh@JoshPress.net>\n * @license   GPL-2.0+\n */\n\nnamespace lasso\\internal_api;\n\n\nclass route {\n\n\t/**\n\t * Run API if possible\n\t *\n\t * @since 0.9.2\n\t *\n\t * @uses \"template_redirect\" action\n\t */\n\tpublic static function do_api() {\n\n\t\tglobal $wp_query;\n\n\t\t//get action, and if set, possibly act\n\t\t$action = $wp_query->get( 'action' );\n\t\tif ( $action && strpos( $_SERVER['REQUEST_URI'], 'lasso-internal-api' ) ) {\n\n\t\t\t$response = __( 'Editus API Error.', 'lasso' );\n\t\t\t$code = 400;\n\n\t\t\t//see if have a nonce. Will verify it in auth class.\n\t\t\tif ( isset( $_POST[ 'nonce' ] ) ) {\n\n\t\t\t\t$callback = self::find_callback( strip_tags( $action ) );\n\t\t\t\tif ( is_int( $callback )  ) {\n\t\t\t\t\t$code = $callback;\n\t\t\t\t}elseif( ! class_exists( $callback['class'] ) ) {\n\t\t\t\t\t$code = 415;\n\t\t\t\t}else {\n\t\t\t\t\t$action = str_replace( '-', '_', $action );\n\t\t\t\t\t$callback_instance = new $callback['class'];\n\t\t\t\t\t$auth              = self::auth( $action, $callback_instance, $callback['method'] );\n\t\t\t\t\tif ( 200 == $auth->status_code && is_array( $callback ) ) {\n\t\t\t\t\t\t$code = 200;\n\t\t\t\t\t\t$data = new find_data( $callback_instance, $action );\n\t\t\t\t\t\tif ( is_array( $data->data ) && ! empty( $data->data ) ) {\n\t\t\t\t\t\t\t$response = self::route( $action, $callback_instance, $callback['method'], $data->data );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$code = 500;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( isset( $auth->error_message ) && is_string( $auth->error_message ) ) {\n\t\t\t\t\t\t\t$response = $auth->error_message;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t$code = $auth->status_code;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}else{\n\t\t\t\t$code = 401;\n\t\t\t\t$response = __( 'Nonce not set.', 'lasso' );\n\t\t\t}\n\n\t\t\tself::respond( $response, $code );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Run the auth checks besides nonce\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @param string $action The AJAX action we are processing.\n\t * @param string|object $callback The class to use for the callback. Either the name of the class or an instance of that class.\n\n\t *\n\t * @return \\lasso\\internal_api\\auth\n\t */\n\tprotected static function auth( $action, $callback ) {\n\t\treturn new auth( $action, $callback );\n\n\t}\n\n\t/**\n\t * Find callback class and method\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @return array\n\t */\n\tprotected static function find_callback( $action ) {\n\t\tif ( $action ) {\n\t\t\t$parts = explode( '_', $action );\n\n\t\t\tif ( isset( $parts[0] ) && isset( $parts[1] ) && isset( $parts[2] ) ) {\n\t\t\t\t$class     = str_replace( '-', '_', $parts[1] );\n\n\t\t\t\t$class = \"\\\\lasso\\\\{$parts[0]}\\\\{$class}\";\n\t\t\t\t$callback  = str_replace( '-', '_', $parts[2] );\n\n\t\t\t\treturn array(\n\t\t\t\t\t'class'  => $class,\n\t\t\t\t\t'method' => $callback,\n\t\t\t\t);\n\t\t\t}\n\n\n\t\t}\n\n\t\treturn 405;\n\n\t}\n\n\t/**\n\t * Route the data to the right callback.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @param string $action The AJAX action we are processing.\n\t * @param string|object $callback The class to use for the callback. Either the name of the class or an instance of that class.\n\t * @param string $method The name of the callback method.\n\t * @param array $data The sanatized data for processing the request.\n\t *\n\t * @return mixed\n\t */\n\tprotected static function route( $action, $callback, $method, $data ) {\n\t\tif (  method_exists( $callback, $method ) ) {\n\t\t\t$response = call_user_func( array( $callback, $method ), $data  );\n\n\t\t\treturn $response;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Respond to request.\n\t *\n\t * @since 0.9.2\n\t *\n\t * @access protected\n\t *\n\t * @param array|string $response The response message to send.\n\t * @param bool|int $code Response code or bool. If is bool, response code will be 200 or 401\n\t */\n\tprotected static function respond( $response, $code ) {\n\t\tif ( true === $code ) {\n\t\t\t$code = 200;\n\t\t}\n\n\t\tif ( false == $code ) {\n\t\t\t$code = 401;\n\t\t}\n\n\t\tif ( is_string( $response ) ) {\n\t\t\t$data[] = $response;\n\t\t}elseif( is_array( $response ) ) {\n\t\t\t$data = $response;\n\t\t}else{\n\t\t\t$data[] = $code;\n\t\t}\n\n\t\tstatus_header( $code );\n\t\tnocache_headers();\n\t\tif ( 200 == $code ) {\n\t\t\twp_send_json_success( $data );\n\t\t}else{\n\t\t\twp_send_json_error( $data );\n\t\t}\n\n\t}\n\n\t/**\n\t * Holds the instance of this class.\n\t *\n\t * @access private\n\t * @var    object\n\t */\n\tprivate static $instance;\n\n\t/**\n\t * Returns an instance of this class.\n\t *\n\t * @access public\n\t *\n\t * @return route|object\n\t */\n\tpublic static function init() {\n\n\t\tif ( ! self::$instance ) {\n\t\t\tself::$instance = new self;\n\t\t}\n\n\t\treturn self::$instance;\n\n\t}\n\n}\n"
  },
  {
    "path": "languages/lasso-de_DE.po",
    "content": "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Editus\\n\"\n\"POT-Creation-Date: 2022-08-02 15:40-0400\\n\"\n\"PO-Revision-Date: 2022-08-02 15:50-0400\\n\"\n\"Last-Translator: \\n\"\n\"Language-Team: \\n\"\n\"Language: de_DE\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1);\\n\"\n\"X-Generator: Poedit 3.1.1\\n\"\n\"X-Poedit-Basepath: ..\\n\"\n\"X-Poedit-KeywordsList: __;_e;esc_attr_e\\n\"\n\"X-Poedit-SourceCharset: UTF-8\\n\"\n\"X-Poedit-SearchPath-0: .\\n\"\n\"X-Poedit-SearchPathExcluded-0: node_modules\\n\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:177\n#, php-format\nmsgid \"\"\n\"There is a new version of %1$s available. <a target=\\\"_blank\\\" class=\"\n\"\\\"thickbox\\\" href=\\\"%2$s\\\">View version %3$s details</a>.\"\nmsgstr \"\"\n\"Eine neue Version von %1$s ist verfügbar. <a target=\\\"_blank\\\" class=\"\n\"\\\"thickbox\\\" href=\\\"%2$s\\\">Details zu Version %3$s ansehen</a>.\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:184\n#, php-format\nmsgid \"\"\n\"There is a new version of %1$s available. <a target=\\\"_blank\\\" class=\"\n\"\\\"thickbox\\\" href=\\\"%2$s\\\">View version %3$s details</a> or <a href=\\\"%4$s\"\n\"\\\">update now</a>.\"\nmsgstr \"\"\n\"Es ist eine neue Version von %1$s verfügbar. <a target=\\\"_blank\\\" class=\"\n\"\\\"thickbox\\\" href=\\\"%2$s\\\">Zeige Details zur Version %3$s</a> oder <a href=\"\n\"\\\"%4$s\\\">aktualisiere jetzt.</a>.\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:324\nmsgid \"You do not have permission to install plugin updates\"\nmsgstr \"Du hast nicht die Rechte um Plugin-Updates zu installieren\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:324\nmsgid \"Error\"\nmsgstr \"Fehler\"\n\n#: admin/includes/class-tgm-plugin-activation.php:333\n#: admin/includes/menus/welcome.php:227\nmsgid \"Install Required Plugins\"\nmsgstr \"Erforderliche Plugins installieren\"\n\n#: admin/includes/class-tgm-plugin-activation.php:334\n#: admin/includes/menus/welcome.php:228\nmsgid \"Install Plugins\"\nmsgstr \"Plugins installieren\"\n\n#: admin/includes/class-tgm-plugin-activation.php:335\n#: admin/includes/menus/welcome.php:229\n#, php-format\nmsgid \"Installing Plugin: %s\"\nmsgstr \"Installieren von Plugin: %s\"\n\n#: admin/includes/class-tgm-plugin-activation.php:336\n#: admin/includes/menus/welcome.php:230\nmsgid \"Something went wrong with the plugin API.\"\nmsgstr \"Irgendetwas ging schief mit der Plugin API.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:397\n#: admin/includes/menus/welcome.php:241\nmsgid \"Return to Required Plugins Installer\"\nmsgstr \"Zurück zur Installation der benötigten Plugins\"\n\n#: admin/includes/class-tgm-plugin-activation.php:398\nmsgid \"Return to the dashboard\"\nmsgstr \"Zurück zum Dashboard\"\n\n#: admin/includes/class-tgm-plugin-activation.php:399\n#: admin/includes/class-tgm-plugin-activation.php:3029\n#: admin/includes/menus/welcome.php:242\nmsgid \"Plugin activated successfully.\"\nmsgstr \"Plugin erfolgreich aktiviert.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:400\n#, fuzzy\n#| msgid \"The following plugin was activated successfully:\"\n#| msgid_plural \"The following plugins were activated successfully:\"\nmsgid \"The following plugin was activated successfully:\"\nmsgstr \"Das folgende Plugin wurde erfolgreich aktiviert:\"\n\n#: admin/includes/class-tgm-plugin-activation.php:401\n#, php-format\nmsgid \"No action taken. Plugin %1$s was already active.\"\nmsgstr \"Keine Aktion durchgeführt. Das Plugin %1$s war bereits aktiviert.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:402\n#, php-format\nmsgid \"\"\n\"Plugin not activated. A higher version of %s is needed for this theme. \"\n\"Please update the plugin.\"\nmsgstr \"\"\n\"Das Plugin wurde nicht aktiviert. Eine neuere Version von %s ist für dieses \"\n\"Theme erforderlich. Bitte aktualisiere das Plugin.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:403\n#, php-format\nmsgid \"All plugins installed and activated successfully. %1$s\"\nmsgstr \"Alle Plugins wurden erfolgreich installiert und aktiviert. %1$s\"\n\n#: admin/includes/class-tgm-plugin-activation.php:404\nmsgid \"Dismiss this notice\"\nmsgstr \"Nachricht verwerfen\"\n\n#: admin/includes/class-tgm-plugin-activation.php:405\nmsgid \"Please contact the administrator of this site for help.\"\nmsgstr \"Bitte wende dich an den Seitenadministrator für Hilfe.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2167\nmsgid \"Required\"\nmsgstr \"Erforderlich\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2170\nmsgid \"Recommended\"\nmsgstr \"Empfohlen\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2186\nmsgid \"WordPress Repository\"\nmsgstr \"WordPress Repository\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2189\nmsgid \"External Source\"\nmsgstr \"Externe Quelle\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2192\nmsgid \"Pre-Packaged\"\nmsgstr \"Vorgepackt\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2209\nmsgid \"Not Installed\"\nmsgstr \"Nicht installiert\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2213\nmsgid \"Installed But Not Activated\"\nmsgstr \"Installiert aber nicht aktiviert\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2215\nmsgid \"Active\"\nmsgstr \"Aktiv\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2221\nmsgid \"Required Update not Available\"\nmsgstr \"Erforderliche Aktualisierung nicht verfügbar\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2224\nmsgid \"Requires Update\"\nmsgstr \"Benötigt Update\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2227\nmsgid \"Update recommended\"\nmsgstr \"Update empfohlen\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2379\nmsgid \"Installed version:\"\nmsgstr \"Installierte Version:\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2387\nmsgid \"Minimum required version:\"\nmsgstr \"Minimal erforderliche Version:\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2399\nmsgid \"Available version:\"\nmsgstr \"Verfügbare Version:\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2422\n#, php-format\nmsgid \"\"\n\"No plugins to install, update or activate. <a href=\\\"%1$s\\\">Return to the \"\n\"Dashboard</a>\"\nmsgstr \"\"\n\"Keine Plugins zu installieren, aktualisieren oder aktivieren. <a href=\\\"%1$s\"\n\"\\\">Zurück zum Dashboard</a>\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2436\nmsgid \"Plugin\"\nmsgstr \"Plugin\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2437\nmsgid \"Source\"\nmsgstr \"Quelle\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2438\nmsgid \"Type\"\nmsgstr \"Typ\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2442\n#: admin/includes/menus/welcome.php:118\nmsgid \"Version\"\nmsgstr \"Version\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2443\n#: admin/includes/menus/welcome.php:49 public/includes/editor-modules.php:614\nmsgid \"Status\"\nmsgstr \"Status\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2603\nmsgid \"Install\"\nmsgstr \"Installieren\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2609\nmsgid \"Update\"\nmsgstr \"Aktualisieren\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2612\nmsgid \"Activate\"\nmsgstr \"Aktivieren\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2643\nmsgid \"No plugins were selected to be installed. No action taken.\"\nmsgstr \"\"\n\"Es wurden keine Plugins zur Installation ausgewählt. Es wurde nichts \"\n\"unternommen.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2645\nmsgid \"No plugins were selected to be updated. No action taken.\"\nmsgstr \"\"\n\"Es wurden keine Plugins zur Aktualisierung ausgewählt. Es wurde nichts \"\n\"unternommen.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2681\nmsgid \"No plugins are available to be installed at this time.\"\nmsgstr \"Derzeit stehen keine Plugins zur Installation zur Verfügung.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2683\nmsgid \"No plugins are available to be updated at this time.\"\nmsgstr \"Derzeit stehen keine Plugins zur Aktualisierung zur Verfügung.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3028\nmsgid \"Plugin activation failed.\"\nmsgstr \"Plugin-Aktivierung fehlgeschlagen.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3362\n#, php-format\nmsgid \"Updating Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"Aktualisiere Plugin %1$s (%2$d/%3$d)\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3364\n#, php-format\nmsgid \"An error occurred while installing %1$s: <strong>%2$s</strong>.\"\nmsgstr \"\"\n\"Während der Installation von %1$s: <strong>%2$s</strong> ist ein Fehler \"\n\"aufgetreten.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3365\n#, php-format\nmsgid \"The installation of %1$s failed.\"\nmsgstr \"Die Installation von %1$s ist fehlgeschlagen.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3369\nmsgid \"\"\n\"The installation and activation process is starting. This process may take a \"\n\"while on some hosts, so please be patient.\"\nmsgstr \"\"\n\"Der Installations- und Aktivierungsprozess wird gestartet. Dieser Prozess \"\n\"kann auf manchen Servern etwas Zeit in Anspruch nehmen. Bitte habe etwas \"\n\"Geduld.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3370\n#, php-format\nmsgid \"%1$s installed and activated successfully.\"\nmsgstr \"%1$s erfolgreich installiert und aktiviert.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3371\nmsgid \"All installations and activations have been completed.\"\nmsgstr \"Alle Installationen und Aktivierungen wurden abgeschlossen.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3372\n#, php-format\nmsgid \"Installing and Activating Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"Plugin installieren und aktivieren %1$s (%2$d/%3$d)\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3375\nmsgid \"\"\n\"The installation process is starting. This process may take a while on some \"\n\"hosts, so please be patient.\"\nmsgstr \"\"\n\"Der Installationsprozess wird gestartet. Dieser Prozess kann auf manchen \"\n\"Servern etwas Zeit in Anspruch nehmen. Bitte habe etwas Geduld.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3377\nmsgid \"All installations have been completed.\"\nmsgstr \"Alle Installationen wurden abgeschlossen.\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3378\n#, php-format\nmsgid \"Installing Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"Installiere Plugin %1$s (%2$d/%3$d)\"\n\n#: admin/includes/load_admin.php:151\nmsgid \"Dismiss this notice.\"\nmsgstr \"Diesen Hinweis ausblenden.\"\n\n#: admin/includes/menus/license.php:30\nmsgid \"Aesopinteractive LLC\"\nmsgstr \"Aesopinteractive LLC\"\n\n#: admin/includes/menus/license.php:38 admin/includes/menus/license.php:57\nmsgid \"License Key\"\nmsgstr \"Lizenzschlüssel\"\n\n#: admin/includes/menus/license.php:38\nmsgid \"License\"\nmsgstr \"Lizenz\"\n\n#: admin/includes/menus/license.php:47\nmsgid \"Editus License\"\nmsgstr \"Editus-Lizenz\"\n\n#: admin/includes/menus/license.php:48\nmsgid \"\"\n\"Input the license key you recieved with your purchase to ensure your version \"\n\"of Editus stays updated.\"\nmsgstr \"\"\n\"Gib den Lizenzschlüssel ein, den du beim Kauf erhalten hast, um \"\n\"sicherzugehen dass Editus aktuell bleibt.\"\n\n#: admin/includes/menus/license.php:66 admin/includes/menus/license.php:75\nmsgid \"Activate License\"\nmsgstr \"Lizenz aktivieren\"\n\n#: admin/includes/menus/license.php:70\nmsgid \"active\"\nmsgstr \"aktiviert\"\n\n#: admin/includes/menus/license.php:72\nmsgid \"Deactivate License\"\nmsgstr \"Lizenz deaktivieren\"\n\n#: admin/includes/menus/settings.php:26 public/includes/editor-modules.php:493\n#: public/includes/editor-modules.php:892\n#: public/includes/editor-modules.php:894\n#: public/includes/editor-modules.php:909\n#: public/includes/editor-modules.php:928\nmsgid \"Settings\"\nmsgstr \"Einstellungen\"\n\n#: admin/includes/menus/settings.php:169\nmsgid \"Editus Settings\"\nmsgstr \"Editus-Einstellungen\"\n\n#: admin/includes/menus/settings.php:177\nmsgid \"Enable for:\"\nmsgstr \"Aktivieren für:\"\n\n#: admin/includes/menus/settings.php:181\nmsgid \"Enable Editus for the following post types.\"\nmsgstr \"Editus für die folgende Post-Typen aktivieren.\"\n\n#: admin/includes/menus/settings.php:203\nmsgid \"Internal Settings\"\nmsgstr \"Interne Einstellungen\"\n\n#: admin/includes/menus/settings.php:206\nmsgid \"Article Class\"\nmsgstr \"Artikel Klasse\"\n\n#: admin/includes/menus/settings.php:207\nmsgid \"\"\n\"Provide the CSS class (including the preceding dot) of container that holds \"\n\"the post. This should be the first parent container class that holds \"\n\"the_content.\"\nmsgstr \"\"\n\"Gib die CSS-Klasse (einschließlich des vorangehenden Punkts) des Containers \"\n\"an, der den Beitrag enthält. Dies sollte die erste übergeordnete \"\n\"Containerklasse sein, die the_content enthält.\"\n\n#: admin/includes/menus/settings.php:212\nmsgid \"Featured Image Class\"\nmsgstr \"Beitragsbild Klasse\"\n\n#: admin/includes/menus/settings.php:213\nmsgid \"\"\n\"Provide the CSS class that uses a featured image as a background image. This \"\n\"currently only supports themes that have the featured image set as \"\n\"background image.\"\nmsgstr \"\"\n\"Stelle die CSS-Klasse bereit, die ein Beitragsbild als Hintergrundbild \"\n\"verwendet. Derzeit werden nur Designs unterstützt, bei denen das \"\n\"Beitragsbild als Hintergrundbild festgelegt ist.\"\n\n#: admin/includes/menus/settings.php:218\nmsgid \"Article Title Class\"\nmsgstr \"Artikel Titel Klasse\"\n\n#: admin/includes/menus/settings.php:219\nmsgid \"\"\n\"Provide the CSS class for the post title. This will enable you to update the \"\n\"title of the post by clicking and typing.\"\nmsgstr \"\"\n\"Geib die CSS-Klasse für den Beitragstitel an. Auf diese Weise kannst du den \"\n\"Titel des Beitrags durch Klicken und Eingeben aktualisieren.\"\n\n#: admin/includes/menus/settings.php:224\nmsgid \"Ignored Items to Save\"\nmsgstr \"Ignorierte Elemente zum Speichern\"\n\n#: admin/includes/menus/settings.php:225\nmsgid \"\"\n\"If your post container holds additional markup, list the css class names \"\n\"(comma separated, including the dot) of those items. When you enter the \"\n\"editor, Editus will remove (NOT delete) these items so that it does not save \"\n\"them as HTML.\"\nmsgstr \"\"\n\"Wenn der Beitrags-Container zusätzliche Markierungen enthält, liste die CSS-\"\n\"Klassennamen (durch Kommas getrennt, einschließlich des Punktes) dieser \"\n\"Elemente auf. Wenn du den Editor startest, werden diese Elemente von Editus \"\n\"entfernt (NICHT gelöscht), sodass diese nicht als HTML gespeichert werden.\"\n\n#: admin/includes/menus/settings.php:230\nmsgid \"Read Only Items\"\nmsgstr \"Nur lesen\"\n\n#: admin/includes/menus/settings.php:231\nmsgid \"\"\n\"If your post has items that should not be editable, list the css class names \"\n\"(comma separated, including the dot) of those items.\"\nmsgstr \"\"\n\"Wenn dein Beitrag Elemente enthält, die nicht bearbeitet werden können, \"\n\"führe die CSS-Klassennamen (durch Kommas getrennt, einschließlich des \"\n\"Punktes) dieser Elemente an.\"\n\n#: admin/includes/menus/settings.php:237\nmsgid \"Show Ignored Items\"\nmsgstr \"Ignorierte Objekte anzeigen\"\n\n#: admin/includes/menus/settings.php:238\nmsgid \"\"\n\"By default the ignored items are hidden. Check this to show ignored items \"\n\"while keeping them uneditable.\"\nmsgstr \"\"\n\"Standardmäßig sind die ignorierten Elemente ausgeblendet. Aktiviere dieses \"\n\"Kontrollkästchen, um ignorierte Elemente anzuzeigen, die jedoch nicht \"\n\"bearbeitet werden können.\"\n\n#: admin/includes/menus/settings.php:242\nmsgid \"Editor UI\"\nmsgstr \"Editor UI\"\n\n#: admin/includes/menus/settings.php:246\nmsgid \"Use the Old Toolbar\"\nmsgstr \"Verwende die alte Symbolleiste\"\n\n#: admin/includes/menus/settings.php:247\nmsgid \"\"\n\"Use this option to disable the new color options and use the pre-1.0 toolbar.\"\nmsgstr \"\"\n\"Verwende diese Option, um die neuen Farboptionen zu deaktivieren und die \"\n\"Symbolleiste vor 1.0 zu verwenden.\"\n\n#: admin/includes/menus/settings.php:251\nmsgid \"Editor Bar Color Top\"\nmsgstr \"Bearbeitungsleiste Farbe oben\"\n\n#: admin/includes/menus/settings.php:252\nmsgid \"Editor Bar Color Bottom\"\nmsgstr \"Bearbeitungsleiste Farbe unten\"\n\n#: admin/includes/menus/settings.php:253\nmsgid \"Dialog Color\"\nmsgstr \"Dialogfeld Farbe\"\n\n#: admin/includes/menus/settings.php:254\nmsgid \"Icon/Text Color\"\nmsgstr \"Symbol und Textfarbe\"\n\n#: admin/includes/menus/settings.php:256\nmsgid \"Default Colors\"\nmsgstr \"Standardfarben\"\n\n#: admin/includes/menus/settings.php:261\nmsgid \"Enable H2 and H3 Buttons\"\nmsgstr \"Aktiviere H2/H3 Button\"\n\n#: admin/includes/menus/settings.php:262\nmsgid \"Show the buttons to set H2 and H3 settings.\"\nmsgstr \"Zeige Button für  H2/H3-Einstellungen.\"\n\n#: admin/includes/menus/settings.php:267\nmsgid \"Enable H4/H5/H6 Buttons\"\nmsgstr \"Aktiviere H4/H5/H6 Button\"\n\n#: admin/includes/menus/settings.php:268\nmsgid \"Show the buttons to set H4/H5/H6 settings.\"\nmsgstr \"Zeige Button für H4/H5/H6-Einstellungen.\"\n\n#: admin/includes/menus/settings.php:274\nmsgid \"Enable OL/UL Buttons\"\nmsgstr \"Aktiviere Buttons für Nummerierte Liste und Aufzählung\"\n\n#: admin/includes/menus/settings.php:275\nmsgid \"\"\n\"Show the buttons to create Ordered and Unordered Lists from text selection.\"\nmsgstr \"\"\n\"Zeige die Buttons um Nummerierte Listen und Aufzählungen aus markiertem Text \"\n\"zu erstellen.\"\n\n#: admin/includes/menus/settings.php:280\nmsgid \"Enable Text Color Buttons\"\nmsgstr \"Aktiviere Button für Textfarben\"\n\n#: admin/includes/menus/settings.php:281\nmsgid \"Show the buttons to set text colors.\"\nmsgstr \"Zeige Buttons, um Textfarben anzupassen.\"\n\n#: admin/includes/menus/settings.php:286\nmsgid \"Enable Text Align Buttons\"\nmsgstr \"Textausrichtungs-Buttons aktivieren\"\n\n#: admin/includes/menus/settings.php:287\nmsgid \"Show the buttons to set text alignment.\"\nmsgstr \"Zeige Textausrichtungs-Schaltflächen an.\"\n\n#: admin/includes/menus/settings.php:293\nmsgid \"Make links editable under the Editing Mode\"\nmsgstr \"Mache Links im Bearbeitungsmodus bearbeitbar\"\n\n#: admin/includes/menus/settings.php:294\nmsgid \"\"\n\"Make links editable under the Editing Mode. Turning this on will make the \"\n\"links non-clickable while editing.\"\nmsgstr \"\"\n\"Mache Links im Bearbeitungsmodus bearbeitbar. Wenn diese Option aktiviert \"\n\"ist, können Links während der Bearbeitung nicht angeklickt werden.\"\n\n#: admin/includes/menus/settings.php:298\nmsgid \"Insert Component UI\"\nmsgstr \"Komponente einfügen\"\n\n#: admin/includes/menus/settings.php:299\nmsgid \"UI mechanism to insert components\"\nmsgstr \"UI-Mechanismus zum Einfügen von Komponenten\"\n\n#: admin/includes/menus/settings.php:301\nmsgid \"Drag and Drop\"\nmsgstr \"Drag & Drop\"\n\n#: admin/includes/menus/settings.php:304\nmsgid \"Click\"\nmsgstr \"Klick\"\n\n#: admin/includes/menus/settings.php:307\nmsgid \"Auto Button on Empty Paragraph. medium.com-like UI.\"\nmsgstr \"Auto-Button bei leerem Absatz. medium.com-ähnliche Benutzeroberfläche.\"\n\n#: admin/includes/menus/settings.php:313\nmsgid \"Popup When Text is Selected\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:314\nmsgid \"\"\n\"Instead of using the bottom toolbar to format texts, use a popup box to \"\n\"format texts.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:320\n#, fuzzy\n#| msgid \"Insert Component\"\nmsgid \"Component\"\nmsgstr \"Komponente einfügen\"\n\n#: admin/includes/menus/settings.php:324\nmsgid \"Additional Component: Table\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:325\nmsgid \"Allow user to add and edit tables.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:331\nmsgid \"Additional Component: Paragraph\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:332\nmsgid \"Plain HTML Paragraph.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:363\n#, fuzzy\n#| msgid \"Use Selected Images\"\nmsgid \"Use Simple Image\"\nmsgstr \"Ausgewählte Bilder verwenden\"\n\n#: admin/includes/menus/settings.php:364\nmsgid \"Use Simple Image Component without Extra Options.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:371\nmsgid \"Use WP Image Block\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:372\nmsgid \"\"\n\"Use WP Image Block as the image component. Gutenberg Block Editor needs to \"\n\"be enabled.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:379\nmsgid \"Post Settings UI\"\nmsgstr \"Benutzeroberfläche für Beitragseinstellungen\"\n\n#: admin/includes/menus/settings.php:383\nmsgid \"Disable Post Settings\"\nmsgstr \"Beitragseinstellungen deaktivieren\"\n\n#: admin/includes/menus/settings.php:384\nmsgid \"\"\n\"Check this to disable users from being able to edit post settings from the \"\n\"front-end.\"\nmsgstr \"\"\n\"Aktiviere dieses Kontrollkästchen, um zu verhindern dass Benutzer \"\n\"Beitragseinstellungen im Frontend bearbeiten können.\"\n\n#: admin/includes/menus/settings.php:389\nmsgid \"Allow Changing Post Date\"\nmsgstr \"Ändern des Beitragsdatums zulassen\"\n\n#: admin/includes/menus/settings.php:390\nmsgid \"\"\n\"Add the date selector to change the post's date to the Post Setting dialog\"\nmsgstr \"\"\n\"Füge Datumsauswahl hinzu, um das Beitragsdatum im Dialogfeld \\\"Einstellungen\"\n\"\\\" zu ändern\"\n\n#: admin/includes/menus/settings.php:395\nmsgid \"Allow Editing Excerpt\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:396\n#, fuzzy\n#| msgid \"\"\n#| \"Add the date selector to change the post's date to the Post Setting dialog\"\nmsgid \"Allow the post's excerpt to be edited in the Post Setting dialog\"\nmsgstr \"\"\n\"Füge Datumsauswahl hinzu, um das Beitragsdatum im Dialogfeld \\\"Einstellungen\"\n\"\\\" zu ändern\"\n\n#: admin/includes/menus/settings.php:401\nmsgid \"Allow Adding New Category\"\nmsgstr \"Hinzufügen neuer Kategorien zulassen\"\n\n#: admin/includes/menus/settings.php:402\nmsgid \"\"\n\"Add the user to create new, previously non-existing categories for posts.\"\nmsgstr \"\"\n\"Erlaube Benutzern, neue (noch nicht existierende) Kategorien für Beiträge zu \"\n\"erstellen.\"\n\n#: admin/includes/menus/settings.php:407\nmsgid \"Do Not Allow \\\"Pending\\\" Status\"\nmsgstr \"Status \\\"Ausstehend\\\" verbieten\"\n\n#: admin/includes/menus/settings.php:408\nmsgid \"Remove the Option to Set the Status to Pending.\"\nmsgstr \"Entferne die Option, den Status auf Ausstehend zu setzen.\"\n\n#: admin/includes/menus/settings.php:413\nmsgid \"Remove POST URL Option\"\nmsgstr \"Entferne Beitrags-URL-Option\"\n\n#: admin/includes/menus/settings.php:414\nmsgid \"Remove the Option to Set the URL for the Post.\"\nmsgstr \"\"\n\"Entferne die Option, die URL-Titelform (slug) des Beitrags zu bearbeiten.\"\n\n#: admin/includes/menus/settings.php:419\nmsgid \"Disable Post Adding\"\nmsgstr \"Beitragserstellung deaktivieren\"\n\n#: admin/includes/menus/settings.php:420\nmsgid \"\"\n\"Check this box to disable users from being able to add new posts from the \"\n\"front-end.\"\nmsgstr \"\"\n\"Aktiviere dieses Kontrollkästchen, um zu verhindern dass Benutzer neue \"\n\"Beiträge aus dem Frontend hinzufügen können.\"\n\n#: admin/includes/menus/settings.php:425\nmsgid \"Support Custom Taxonomy\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:426\nmsgid \"Allow editing custom taxonomies.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:432\nmsgid \"Misc\"\nmsgstr \"Diverses\"\n\n#: admin/includes/menus/settings.php:436\nmsgid \"Do Not Show Tour Dialog\"\nmsgstr \"Tour-Dialog nicht mehr anzeigen\"\n\n#: admin/includes/menus/settings.php:437\nmsgid \"Check this box to disable the tour dialog box for all users.\"\nmsgstr \"\"\n\"Aktiviere dieses Kontrollkästchen, um den Tour-Dialog für alle Benutzer zu \"\n\"deaktivieren.\"\n\n#: admin/includes/menus/settings.php:441\nmsgid \"Placeholder Text for New Post\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:442\nmsgid \"Placeholder text to be displayed when a new post is created.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:443 includes/process/new_object.php:38\n#: public/includes/assets.php:248\nmsgid \"Once upon a time...\"\nmsgstr \"Schreib etwas...\"\n\n#: admin/includes/menus/settings.php:448\n#, fuzzy\n#| msgid \"Do Not Allow \\\"Pending\\\" Status\"\nmsgid \"Do Not Allow Shortcode Editing\"\nmsgstr \"Status \\\"Ausstehend\\\" verbieten\"\n\n#: admin/includes/menus/settings.php:449\n#, fuzzy\n#| msgid \"Check this box to disable the tour dialog box for all users.\"\nmsgid \"Check this box to disable frontend editing of shortcodes.\"\nmsgstr \"\"\n\"Aktiviere dieses Kontrollkästchen, um den Tour-Dialog für alle Benutzer zu \"\n\"deaktivieren.\"\n\n#: admin/includes/menus/settings.php:453\nmsgid \"\\\"Bold\\\" Tag\"\nmsgstr \"\\\"Fett\\\" Tag\"\n\n#: admin/includes/menus/settings.php:454\nmsgid \"Choose the HTML tag used for the \\\"Bold\\\" style.\"\nmsgstr \"Wähle das HTML-Tag für \\\"Fett\\\".\"\n\n#: admin/includes/menus/settings.php:459\nmsgid \"\\\"Italic\\\" Tag\"\nmsgstr \"\\\"Kursiv\\\" Tag\"\n\n#: admin/includes/menus/settings.php:460\nmsgid \"Choose the HTML tag used for the \\\"Italic\\\" style.\"\nmsgstr \"Wähle das HTML-Tag für \\\"Kursiv\\\".\"\n\n#: admin/includes/menus/settings.php:466\nmsgid \"Auto Prefix HTTP to links\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:467\nmsgid \"\"\n\"When user adds a hyperlink, automatically add http:// if the user does not \"\n\"specify it explicitly.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:471\n#, fuzzy\n#| msgid \"Advanced\"\nmsgid \"Advanced Options\"\nmsgstr \"Fortgeschritten\"\n\n#: admin/includes/menus/settings.php:472\nmsgid \"\"\n\"Suggested not to turn these options on without consulting the developer.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:477\nmsgid \"Disable Aesop Component Conversion\"\nmsgstr \"Aesop Komponente Konvertierung deaktivieren\"\n\n#: admin/includes/menus/settings.php:478\nmsgid \"\"\n\"Check this box to disable the conversion process used on Aesop Story Engine \"\n\"components.\"\nmsgstr \"\"\n\"Aktiviere dieses Kontrollkästchen, um den für die Aesop Story Engine-\"\n\"Komponenten verwendeten Konvertierungsprozess zu deaktivieren.\"\n\n#: admin/includes/menus/settings.php:483\nmsgid \"Enable Auto Save\"\nmsgstr \"Automatisches Speichern aktivieren\"\n\n#: admin/includes/menus/settings.php:484\nmsgid \"Check this box to enable auto save.\"\nmsgstr \"\"\n\"Aktiviere dieses Kontrollkästchen, um das automatische Speichern zu \"\n\"aktivieren.\"\n\n#: admin/includes/menus/settings.php:489\nmsgid \"Disable Post Saving\"\nmsgstr \"Speichern von Beiträgen deaktivieren\"\n\n#: admin/includes/menus/settings.php:490\nmsgid \"\"\n\"By default the editor will update the database with the post or page it is \"\n\"being used on. Check this box to disable this. If you check this box, it is \"\n\"assumed that you will be using the provided filters to save your own content.\"\nmsgstr \"\"\n\"Standardmäßig aktualisiert der Editor die Datenbank mit dem Beitrag oder der \"\n\"Seite, auf der er verwendet wird. Aktiviere dieses Kontrollkästchen, um dies \"\n\"zu deaktivieren. Wenn dieses Kontrollkästchen aktiviert ist, wird davon \"\n\"ausgegangen, dass die bereitgestellten Filter zum Speichern des eigenen \"\n\"Inhalts verwenden werden.\"\n\n#: admin/includes/menus/settings.php:496\nmsgid \"Disable Post Editing\"\nmsgstr \"Deaktiviere die Bearbeitung von Beiträgen\"\n\n#: admin/includes/menus/settings.php:497\nmsgid \"\"\n\"You may use this option if you only want to edit custom fields. Refer <a \"\n\"href=\\\"https://edituswp.com/editing-and-updating-custom-fields-from-frontend/\"\n\"\\\">here</a> for more information. The custom fields you specify will be \"\n\"still editable under the editing mode.\"\nmsgstr \"\"\n\"Du kannst diese Option verwenden, wenn du nur benutzerdefinierte Felder \"\n\"bearbeiten möchten. Weitere Informationen <a href=\\\"https://edituswp.com/\"\n\"editing-and-updating-custom-fields-from-frontend/\\\">hier</a>. Die \"\n\"ausgewählten benutzerdefinierten Felder können im Bearbeitungsmodus \"\n\"weiterhin bearbeitet werden.\"\n\n#: admin/includes/menus/settings.php:503\nmsgid \"Don't Use REST API to Save\"\nmsgstr \"REST-API zum Speichern nicht verwenden\"\n\n#: admin/includes/menus/settings.php:504\nmsgid \"\"\n\"By default the editor will use REST API to save posts. Check this box to use \"\n\"custom AJAX calls instead.\"\nmsgstr \"\"\n\"Standardmäßig verwendet der Editor die REST-API um Beiträge zu speichern. \"\n\"Aktiviere das Kontrollkästchen, um stattdessen benutzerdefinierte AJAX-Calls \"\n\"zu verwenden.\"\n\n#: admin/includes/menus/settings.php:510\n#, fuzzy\n#| msgid \"You can also use Shortcodes\"\nmsgid \"Don't Wrap Shortcodes\"\nmsgstr \"Du kannst auch Shortcodes verwenden\"\n\n#: admin/includes/menus/settings.php:511\nmsgid \"\"\n\"By default Editus wraps shortcodes so they can be preserved. Disable this \"\n\"behavior.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:521\nmsgid \"Save Settings\"\nmsgstr \"Einstellungen speichern\"\n\n#: admin/includes/menus/welcome.php:48\nmsgid \"Editus\"\nmsgstr \"Editus\"\n\n#: admin/includes/menus/welcome.php:49\nmsgid \"Welcome\"\nmsgstr \"Willkommen\"\n\n#: admin/includes/menus/welcome.php:71\nmsgid \"\"\n\"We will check the current theme on every site in your network and give you a \"\n\"quick status feedback here. You can see the status by visiting the Editus \"\n\"menu on each site.\"\nmsgstr \"\"\n\"Wir werden das aktuelle Theme auf jeder Seite in deinem Netzwerk überprüfen \"\n\"und dir hier ein rasches Feedback geben. Du kannst den Status abrufen, indem \"\n\"du das Editus-Menü auf jeder Seite besuchst.\"\n\n#: admin/includes/menus/welcome.php:90\nmsgid \"You're Ready to Rock!\"\nmsgstr \"Du bist bereit loszulegen!\"\n\n#: admin/includes/menus/welcome.php:92\nmsgid \"Your theme is automatically supported. No additional setup is needed.\"\nmsgstr \"\"\n\"Dein Theme wird automatisch unterstützt. Es sind keine zusätzlichen \"\n\"Einstellungen notwendig.\"\n\n#: admin/includes/menus/welcome.php:94\nmsgid \"\"\n\"Editus will place a small menu on the bottom of your site. While on a single \"\n\"post or page, click the \\\"pen\\\" icon to go into edit mode. Press escape to \"\n\"get out of edit mode.\"\nmsgstr \"\"\n\"Editus wird ein kleines Menü unten auf deiner Webseite platzieren. Wenn du \"\n\"auf einem Beitrag oder einer Seite bist, klicke das „Stift“-Symbol, um in \"\n\"den Bearbeitungsmodus zu wechseln. Drücke „Esc“ um den Bearbeitungsmodus zu \"\n\"verlassen.\"\n\n#: admin/includes/menus/welcome.php:117\nmsgid \"Welcome to Editus\"\nmsgstr \"Willkommen bei Editus\"\n\n#: admin/includes/menus/welcome.php:123\nmsgid \"Help\"\nmsgstr \"Hilfe\"\n\n#: admin/includes/menus/welcome.php:124\nmsgid \"Twitter\"\nmsgstr \"Twitter\"\n\n#: admin/includes/menus/welcome.php:125\nmsgid \"Facebook\"\nmsgstr \"Facebook\"\n\n#: admin/includes/menus/welcome.php:158\nmsgid \"Article CSS Class Needed!\"\nmsgstr \"Beitrags CSS Klasse wird benötigt!\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"Before using Editus,\"\nmsgstr \"\"\n\"Vor der Verwendung von Editus die CSS Klasse des Containers, der den Inhalt \"\n\"der Seiten und Beiträge enthält,\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"enter and save\"\nmsgstr \"eingeben und speichern\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"\"\n\"the CSS class of the container that holds your post and page content. You \"\n\"can <a href=\\\"https://dl.dropboxusercontent.com/u/5594632/lasso-media/doc-\"\n\"movies/using-inspector-lasso.gif\\\" target=\\\"_blank\\\">use a tool like \"\n\"inspector</a> in Chrome or Firefox to find this CSS class, or \"\nmsgstr \"\"\n\". Du kannst <a href=\\\"https://dl.dropboxusercontent.com/u/5594632/lasso-\"\n\"media/doc-movies/using-inspector-lasso.gif\\\" target=\\\"_blank\\\">ein Tool wie \"\n\"den Inspektor</a> in Chrome oder Firefox benutzen um die CSS Klasse zu \"\n\"finden oder \"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"email us.\"\nmsgstr \"sende uns eine E-Mail\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"with a link to a public URL with the theme and we'll find it for you.\"\nmsgstr \"\"\n\"mit einem Link zu einer öffentlichen Seite mit dem Theme und wir werden sie \"\n\"für dich finden.\"\n\n#: admin/includes/menus/welcome.php:166\nmsgid \"\"\n\"Just a heads up that the WP REST API isn't activated. This is required to \"\n\"list the posts and pages on the front-end.\"\nmsgstr \"\"\n\"Nur ein Hinweis, dass die WP REST API nicht aktiviert ist. Dies ist \"\n\"erforderlich, um die Beiträge und Seiten im Frontend aufzulisten.\"\n\n#: admin/includes/menus/welcome.php:173\nmsgid \"Just a heads up that \"\nmsgstr \"Nur ein Hinweis \"\n\n#: admin/includes/menus/welcome.php:174 admin/includes/menus/welcome.php:211\nmsgid \"Aesop Story Engine\"\nmsgstr \"Aesop Story Engine\"\n\n#: admin/includes/menus/welcome.php:174\nmsgid \"\"\n\"isn't activated. It's not required to use Editus, but you won't get the cool \"\n\"drag and drop components without it activated. It's free!\"\nmsgstr \"\"\n\"ist nicht aktiviert. Diese ist nicht erforderlich um Editus zu verwenden, \"\n\"aber dann sind die coolen Drag & Drop-Komponenten nicht verfügbar. Es ist \"\n\"kostenlos!\"\n\n#: admin/includes/menus/welcome.php:180\nmsgid \"WP Side Comments Compatibility Warning!\"\nmsgstr \"WP Side Comments Kompatibilitätswarnung!\"\n\n#: admin/includes/menus/welcome.php:181\nmsgid \"\"\n\"Since Editus saves the HTML of a post, this may cause undesired issues. \"\n\"We're working to resolve incompatibilities faster than a jack rabbit in a \"\n\"hot greasy griddle in the middle of August.\"\nmsgstr \"\"\n\"Da Editus den HTML-Code eines Beitrags speichert, kann dies zu unerwünschten \"\n\"Problemen führen. Wir arbeiten daran, Inkompatibilitäten so schnell wie \"\n\"möglich zu lösen.\"\n\n#: admin/includes/menus/welcome.php:187\nmsgid \"License Key Not Activated\"\nmsgstr \"Lizenzschlüssel nicht aktiviert\"\n\n#: admin/includes/menus/welcome.php:188\nmsgid \"\"\n\"Just a heads up, your license key isn't activated. Enter your license key \"\n\"into the License tab on the left in order to receive plugin update \"\n\"notifications.\"\nmsgstr \"\"\n\"Nur ein Hinweis, dein Lizenzschlüssel ist nicht aktiviert. Gib deinen \"\n\"Lizenzschlüssel in der Registerkarte \\\"Lizenz\\\" links ein, um \"\n\"Benachrichtigungen zu Plugin-Updates zu erhalten.\"\n\n#: admin/includes/menus/welcome.php:192\nmsgid \"License Key Invalid\"\nmsgstr \"Lizenzschlüssel ungültig\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \"The license key that you entered is \"\nmsgstr \"Der eingegebene Lizenzschlüssel ist \"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \"invalid\"\nmsgstr \"ungültig\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \". It may have been entered incorreclty, or may have expired.\"\nmsgstr \"\"\n\". Er wurde möglicherweise falsch eingegeben oder könnte abgelaufen sein.\"\n\n#: admin/includes/menus/welcome.php:243\n#, php-format\nmsgid \"All plugins installed and activated successfully. %s\"\nmsgstr \"Alle Plugins wurden installiert und erfolgreich aktiviert. %s\"\n\n#: includes/process/gallery.php:40\nmsgid \"Save and refresh to view gallery.\"\nmsgstr \"Speichern und aktualisieren um die Galerie anzuzeigen.\"\n\n#: includes/process/gallery.php:199\nmsgid \"Delete From Gallery\"\nmsgstr \"Aus der Galerie löschen\"\n\n#: includes/process/gallery.php:200\nmsgid \"Edit Image Caption\"\nmsgstr \"Bildunterschrift bearbeiten\"\n\n#: internal-api/auth.php:67\nmsgid \"Unauthorized action\"\nmsgstr \"Unberechtigte Aktion\"\n\n#: internal-api/auth.php:71\nmsgid \"\"\n\"All callback classes used for processing the Editus Internal API must \"\n\"implement the lasso\\\\internal_api\\\\api_action interface.\"\nmsgstr \"\"\n\"Alle Callback-Klassen, die zur Verarbeitung der internen API von Editus \"\n\"verwendet werden, müssen die Schnittstelle lasso \\\\ internal_api pi_action \"\n\"implementieren.\"\n\n#: internal-api/auth.php:76\nmsgid \"Nonce invalid\"\nmsgstr \"Nonce ungültig\"\n\n#: internal-api/route.php:30\nmsgid \"Editus API Error.\"\nmsgstr \"Editus API-Fehler.\"\n\n#: internal-api/route.php:66\nmsgid \"Nonce not set.\"\nmsgstr \"Nonce nicht gesetzt.\"\n\n#: lasso.php:130\n#, fuzzy\n#| msgid \"Insert Component\"\nmsgid \"Insert Column\"\nmsgstr \"Komponente einfügen\"\n\n#: lasso.php:131\n#, fuzzy\n#| msgid \"Insert\"\nmsgid \"Insert Row\"\nmsgstr \"Einfügen\"\n\n#: lasso.php:132\n#, fuzzy\n#| msgid \"Delete Post\"\nmsgid \"Delete Column\"\nmsgstr \"Beitrag löschen\"\n\n#: lasso.php:133\n#, fuzzy\n#| msgid \"Delete Post\"\nmsgid \"Delete Row\"\nmsgstr \"Beitrag löschen\"\n\n#: lasso.php:134\n#, fuzzy\n#| msgid \"Delete Image\"\nmsgid \"Delete Table\"\nmsgstr \"Bild löschen\"\n\n#: lasso.php:149 lasso.php:159\n#, fuzzy\n#| msgid \"Table\"\nmsgid \"HTML Table\"\nmsgstr \"Tabelle\"\n\n#: lasso.php:192 lasso.php:220\nmsgid \"HTML Paragraph\"\nmsgstr \"\"\n\n#: public/includes/assets.php:146 public/includes/editor-modules.php:713\n#: public/includes/option-engine.php:132\nmsgid \"Save\"\nmsgstr \"Speichern\"\n\n#: public/includes/assets.php:147\nmsgid \"Please Select Text First.\"\nmsgstr \"Bitte zuerst Text auswählen.\"\n\n#: public/includes/assets.php:148 public/includes/editor-modules.php:439\n#: public/includes/editor-modules.php:706\n#: public/includes/editor-modules.php:788\n#: public/includes/editor-modules.php:1329\nmsgid \"Cancel\"\nmsgstr \"Abbrechen\"\n\n#: public/includes/assets.php:149\nmsgid \"Exit Editor\"\nmsgstr \"Editor verlassen\"\n\n#: public/includes/assets.php:150\nmsgid \"Saving...\"\nmsgstr \"Speichere…\"\n\n#: public/includes/assets.php:151\nmsgid \"Saved!\"\nmsgstr \"Gespeichert!\"\n\n#: public/includes/assets.php:152\nmsgid \"Adding...\"\nmsgstr \"Füge hinzu…\"\n\n#: public/includes/assets.php:153\nmsgid \"Added!\"\nmsgstr \"Hinzugefügt!\"\n\n#: public/includes/assets.php:154\nmsgid \"Loading...\"\nmsgstr \"Lade...\"\n\n#: public/includes/assets.php:155\nmsgid \"Load More\"\nmsgstr \"Weitere laden\"\n\n#: public/includes/assets.php:156 public/includes/helpers.php:457\nmsgid \"Close\"\nmsgstr \"Schließen\"\n\n#: public/includes/assets.php:157\nmsgid \"No more posts found\"\nmsgstr \"Keine weiteren Beiträge gefunden\"\n\n#: public/includes/assets.php:158\nmsgid \"Fetching failed.\"\nmsgstr \"Fehler beim Abrufen.\"\n\n#: public/includes/assets.php:159\nmsgid \"Gallery Created!\"\nmsgstr \"Galerie erstellt!\"\n\n#: public/includes/assets.php:160\nmsgid \"Gallery Updated!\"\nmsgstr \"Galerie aktualisiert!\"\n\n#: public/includes/assets.php:161\nmsgid \"Just write...\"\nmsgstr \"Einfach schreiben…\"\n\n#: public/includes/assets.php:162\nmsgid \"Choose an image\"\nmsgstr \"Bild wählen\"\n\n#: public/includes/assets.php:163\nmsgid \"Update Image\"\nmsgstr \"Bild aktualisieren\"\n\n#: public/includes/assets.php:164\nmsgid \"Insert Image\"\nmsgstr \"Bild einfügen\"\n\n#: public/includes/assets.php:165\nmsgid \"Select Image\"\nmsgstr \"Bild auswählen\"\n\n#: public/includes/assets.php:166\nmsgid \"Remove featured image?\"\nmsgstr \"Beitragsbild entfernen?\"\n\n#: public/includes/assets.php:167\nmsgid \"Update Selected Image\"\nmsgstr \"Ausgewähltes Bild aktualisieren\"\n\n#: public/includes/assets.php:168\nmsgid \"Choose images\"\nmsgstr \"Bilder auswählen\"\n\n#: public/includes/assets.php:169\nmsgid \"Edit Image\"\nmsgstr \"Bild bearbeiten\"\n\n#: public/includes/assets.php:170\n#: public/includes/editor-modules--gallery.php:28\nmsgid \"Add Images\"\nmsgstr \"Bilder hinzufügen\"\n\n#: public/includes/assets.php:171\nmsgid \"Add New Gallery\"\nmsgstr \"Neue Galerie hinzufügen\"\n\n#: public/includes/assets.php:172\nmsgid \"Select Editus Gallery Image\"\nmsgstr \"Eine Editus Galerie-Bild auswählen\"\n\n#: public/includes/assets.php:173\nmsgid \"Use Selected Images\"\nmsgstr \"Ausgewählte Bilder verwenden\"\n\n#: public/includes/assets.php:174\nmsgid \"Publish Post?\"\nmsgstr \"Beitrag veröffentlichen?\"\n\n#: public/includes/assets.php:175\nmsgid \"Yes, publish it!\"\nmsgstr \"Ja, veröffentlichen!\"\n\n#: public/includes/assets.php:176\nmsgid \"Trash Post?\"\nmsgstr \"Beitrag löschen?\"\n\n#: public/includes/assets.php:177\nmsgid \"Yes, trash it!\"\nmsgstr \"Ja, löschen!\"\n\n#: public/includes/assets.php:178\nmsgid \"Oh snap!\"\nmsgstr \"Oh Mist!\"\n\n#: public/includes/assets.php:179\nmsgid \"O.K. got it!\"\nmsgstr \"OK, verstanden!\"\n\n#: public/includes/assets.php:180\nmsgid \"\"\n\"It looks like we are either missing the Article CSS class, or it is \"\n\"configured incorrectly. Editus will not function correctly without this CSS \"\n\"class.\"\nmsgstr \"\"\n\"Es scheint, dass entweder die Artikel-CSS-Klasse nicht vorhanden ist oder \"\n\"diese falsch konfiguriert wurde. Ohne diese CSS-Klasse wird Editus nicht \"\n\"einwandfrei funktionieren.\"\n\n#: public/includes/assets.php:181\nmsgid \"Update Settings\"\nmsgstr \"Einstellungen aktualisieren\"\n\n#: public/includes/assets.php:182\nmsgid \"one more letter\"\nmsgstr \"ein weiterer Buchstabe\"\n\n#: public/includes/assets.php:183\nmsgid \"You are currently editing a backup copy of this post.\"\nmsgstr \"Du bearbeitest gerade eine Sicherungskopie dieses Beitrags.\"\n\n#: public/includes/assets.php:185\nmsgid \"add categories...\"\nmsgstr \"Kategorien hinzufügen...\"\n\n#: public/includes/assets.php:186\nmsgid \"add tags...\"\nmsgstr \"Schlagwörter hinzufügen...\"\n\n#: public/includes/assets.php:187\n#, fuzzy\n#| msgid \"add categories...\"\nmsgid \"add taxonomy terms...\"\nmsgstr \"Kategorien hinzufügen...\"\n\n#: public/includes/assets.php:188\nmsgid \"Edit Shortcode\"\nmsgstr \"Shortcode bearbeiten\"\n\n#: public/includes/components.php:19 public/includes/editor-modules.php:352\nmsgid \"Quote\"\nmsgstr \"Zitat\"\n\n#: public/includes/components.php:23 public/includes/editor-modules.php:350\n#: public/includes/editor-modules.php:1103\n#: public/includes/editor-modules.php:1154\n#: public/includes/editor-modules.php:1218\nmsgid \"Image\"\nmsgstr \"Bild\"\n\n#: public/includes/components.php:27\n#: public/includes/editor-modules--gallery.php:74\n#: public/includes/editor-modules.php:355\nmsgid \"Parallax\"\nmsgstr \"Parallax\"\n\n#: public/includes/components.php:31 public/includes/editor-modules.php:356\nmsgid \"Audio\"\nmsgstr \"Audio\"\n\n#: public/includes/components.php:35 public/includes/editor-modules.php:353\n#: public/includes/editor-modules.php:1080\nmsgid \"Content\"\nmsgstr \"Inhalt\"\n\n#: public/includes/components.php:39 public/includes/editor-modules.php:351\nmsgid \"Character\"\nmsgstr \"Zeichen\"\n\n#: public/includes/components.php:43 public/includes/editor-modules.php:361\nmsgid \"Collection\"\nmsgstr \"Sammlung\"\n\n#: public/includes/components.php:47 public/includes/editor-modules.php:360\nmsgid \"Document\"\nmsgstr \"Dokument\"\n\n#: public/includes/components.php:51 public/includes/editor-modules.php:362\nmsgid \"Gallery\"\nmsgstr \"Galerie\"\n\n#: public/includes/components.php:55 public/includes/editor-modules.php:354\nmsgid \"Chapter\"\nmsgstr \"Kapitel\"\n\n#: public/includes/components.php:59 public/includes/editor-modules.php:358\nmsgid \"Map\"\nmsgstr \"Karte\"\n\n#: public/includes/components.php:63 public/includes/editor-modules.php:359\nmsgid \"Timeline\"\nmsgstr \"Zeitleiste\"\n\n#: public/includes/components.php:67 public/includes/editor-modules.php:357\nmsgid \"Video\"\nmsgstr \"Video\"\n\n#: public/includes/components.php:71 public/includes/components.php:91\n#: public/includes/editor-modules.php:371\n#: public/includes/editor-modules.php:373\nmsgid \"WordPress Image\"\nmsgstr \"WordPress Bild\"\n\n#: public/includes/components.php:75\n#, fuzzy\n#| msgid \"WordPress Image\"\nmsgid \"WordPress Image Block\"\nmsgstr \"WordPress Bild\"\n\n#: public/includes/components.php:79 public/includes/editor-modules.php:375\nmsgid \"WordPress Quote\"\nmsgstr \"WordPress Zitat\"\n\n#: public/includes/components.php:83 public/includes/editor-modules.php:364\nmsgid \"Gallery Pop\"\nmsgstr \"Galerie Pop\"\n\n#: public/includes/components.php:87\nmsgid \"Events\"\nmsgstr \"Veranstaltungen\"\n\n#: public/includes/editor-modules--gallery.php:19\nmsgid \"Create gallery\"\nmsgstr \"Galerie erstellen\"\n\n#: public/includes/editor-modules--gallery.php:27\nmsgid \"Manage Images\"\nmsgstr \"Bilder verwalten\"\n\n#: public/includes/editor-modules--gallery.php:31\nmsgid \"Rearrange or edit the images in this gallery.\"\nmsgstr \"Bilder in dieser Galerie anordnen oder bearbeiten.\"\n\n#: public/includes/editor-modules--gallery.php:47\nmsgid \"Create a Gallery\"\nmsgstr \"Galerie erstellen\"\n\n#: public/includes/editor-modules--gallery.php:51\nmsgid \"Select images to create a gallery.\"\nmsgstr \"Wähle Bilder aus um eine Galerie zu erstellen.\"\n\n#: public/includes/editor-modules--gallery.php:52\nmsgid \"Select Images\"\nmsgstr \"Bilder auswählen\"\n\n#: public/includes/editor-modules--gallery.php:56\nmsgid \"Create Gallery\"\nmsgstr \"Galerie erstellen\"\n\n#: public/includes/editor-modules--gallery.php:67\nmsgid \"Gallery Type\"\nmsgstr \"Galerie Typ\"\n\n#: public/includes/editor-modules--gallery.php:68\nmsgid \"Select the type of gallery.\"\nmsgstr \"Wähle die Galerie-Art.\"\n\n#: public/includes/editor-modules--gallery.php:70\nmsgid \"Grid\"\nmsgstr \"Raster\"\n\n#: public/includes/editor-modules--gallery.php:71\nmsgid \"Thumbnail\"\nmsgstr \"Vorschaubild\"\n\n#: public/includes/editor-modules--gallery.php:73\nmsgid \"Photoset\"\nmsgstr \"Bildauswahl\"\n\n#: public/includes/editor-modules--gallery.php:84\nmsgid \"Grid Item Width\"\nmsgstr \"Rasterbreite\"\n\n#: public/includes/editor-modules--gallery.php:85\nmsgid \"\"\n\"Adjust the width of the individual grid items, only if using Grid gallery \"\n\"style. Default is 400.\"\nmsgstr \"\"\n\"Passe die Breite der einzelnen Rasterelemente an (nur wenn Grid-Galerie-Stil \"\n\"verwendet werden). Standardwert ist 400.\"\n\n#: public/includes/editor-modules--gallery.php:95\nmsgid \"Gallery Transition\"\nmsgstr \"Galerie-Übergang\"\n\n#: public/includes/editor-modules--gallery.php:96\nmsgid \"\"\n\"Adjust the transition effect for the Thumbnail gallery. Default is slide.\"\nmsgstr \"\"\n\"Passe den Übergangseffekt für die Vorschaubilder-Galerie an. Standardwert \"\n\"ist Slider.\"\n\n#: public/includes/editor-modules--gallery.php:98\nmsgid \"Fade\"\nmsgstr \"Einblenden\"\n\n#: public/includes/editor-modules--gallery.php:99\nmsgid \"Slide\"\nmsgstr \"Slide\"\n\n#: public/includes/editor-modules--gallery.php:100\nmsgid \"Dissolve\"\nmsgstr \"Auflösen\"\n\n#: public/includes/editor-modules--gallery.php:105\nmsgid \"Gallery Transition Speed\"\nmsgstr \"Galerie Übergangsgeschwindigkeit\"\n\n#: public/includes/editor-modules--gallery.php:106\nmsgid \"\"\n\"Activate slideshow by setting a speed for the transition.5000 = 5 seconds.\"\nmsgstr \"\"\n\"Diashow aktivieren, durch Wahl einer Übergangsgeschwindigkeit. 5000 = 5 \"\n\"Sekunden.\"\n\n#: public/includes/editor-modules--gallery.php:112\nmsgid \"Hide Gallery Thumbnails\"\nmsgstr \"Galerie-Vorschaubilder ausblenden\"\n\n#: public/includes/editor-modules--gallery.php:121\nmsgid \"Gallery Layout\"\nmsgstr \"Galerie-Layout\"\n\n#: public/includes/editor-modules--gallery.php:122\nmsgid \"\"\n\"Let's say you have 4 images in this gallery. If you enter 121 you will have \"\n\"one image on the top row, two images on the second row, and one image on the \"\n\"third row.\"\nmsgstr \"\"\n\"Angenommen, du hast 4 Bilder in dieser Galerie. Wenn du 121 eingibst, hast \"\n\"du ein Bild in der oberen Reihe, zwei Bilder in der zweiten Reihe und ein \"\n\"Bild in der dritten Reihe.\"\n\n#: public/includes/editor-modules--gallery.php:137\nmsgid \"Main Gallery Height\"\nmsgstr \"Haupt-Galerie Höhe\"\n\n#: public/includes/editor-modules--gallery.php:138\n#, php-format\nmsgid \"\"\n\"Adjust the overall height of the gallery. Acceptable values include 500px or \"\n\"50% etc.\"\nmsgstr \"\"\n\"Passen Sie die Höhe der Galerie an. Die zulässigen Werte sind 500px oder \"\n\"50% usw.\"\n\n#: public/includes/editor-modules--gallery.php:148\nmsgid \"Main Gallery Width\"\nmsgstr \"Haupt-Galerie Breite\"\n\n#: public/includes/editor-modules--gallery.php:149\n#, php-format\nmsgid \"\"\n\"Adjust the overall width of the gallery. Acceptable values include 500px or \"\n\"50% etc.\"\nmsgstr \"\"\n\"Passen Sie die Gesamtbreite der Galerie an. Die zulässigen Werte sind \\\"500px\"\n\"\\\" oder \\\"50 %\\\" usw.\"\n\n#: public/includes/editor-modules--gallery.php:153\nmsgid \"Gallery Caption\"\nmsgstr \"Galerie Bildunterschrift\"\n\n#: public/includes/editor-modules--gallery.php:154\nmsgid \"Add an optional caption for the gallery.\"\nmsgstr \"Füge eine optionale Bildunterschrift zur Galerie hinzu.\"\n\n#: public/includes/editor-modules.php:60 public/includes/editor-modules.php:437\nmsgid \"Table\"\nmsgstr \"Tabelle\"\n\n#: public/includes/editor-modules.php:137\n#: public/includes/underscore-templates.php:23\n#: public/includes/underscore-templates.php:41\nmsgid \"Edit Post\"\nmsgstr \"Beitrag bearbeiten\"\n\n#: public/includes/editor-modules.php:140\n#: public/includes/editor-modules.php:164\n#: public/includes/editor-modules.php:457\nmsgid \"Post Settings\"\nmsgstr \"Beitragseinstellungen\"\n\n#: public/includes/editor-modules.php:145\nmsgid \"All Posts\"\nmsgstr \"Alle Beiträge\"\n\n#: public/includes/editor-modules.php:148\n#: public/includes/editor-modules.php:1323\nmsgid \"Revisions\"\nmsgstr \"Revisionen\"\n\n#: public/includes/editor-modules.php:152\nmsgid \"Add Post\"\nmsgstr \"Neuen Beitrag erstellen\"\n\n#: public/includes/editor-modules.php:163\n#: public/includes/editor-modules.php:456\n#: public/includes/underscore-templates.php:25\n#: public/includes/underscore-templates.php:43\nmsgid \"Delete Post\"\nmsgstr \"Beitrag löschen\"\n\n#: public/includes/editor-modules.php:167\n#: public/includes/editor-modules.php:459\nmsgid \"Save Post\"\nmsgstr \"Beitrag speichern\"\n\n#: public/includes/editor-modules.php:170\n#: public/includes/editor-modules.php:462\nmsgid \"Publish Post\"\nmsgstr \"Beitrag veröffentlichen\"\n\n#: public/includes/editor-modules.php:170\nmsgid \"Submit For Review\"\nmsgstr \"Zur Überprüfung einreichen\"\n\n#: public/includes/editor-modules.php:249\n#: public/includes/editor-modules.php:342\nmsgid \"Bold\"\nmsgstr \"Fett\"\n\n#: public/includes/editor-modules.php:250\n#: public/includes/editor-modules.php:343\nmsgid \"Underline\"\nmsgstr \"Unterstrichen\"\n\n#: public/includes/editor-modules.php:251\n#: public/includes/editor-modules.php:344\nmsgid \"Italicize\"\nmsgstr \"Kursiv\"\n\n#: public/includes/editor-modules.php:252\n#: public/includes/editor-modules.php:345\nmsgid \"Strikethrough\"\nmsgstr \"Durchgestrichen\"\n\n#: public/includes/editor-modules.php:255\n#: public/includes/editor-modules.php:384\n#: public/includes/editor-modules.php:431\nmsgid \"H2 Heading\"\nmsgstr \"Überschrift H2\"\n\n#: public/includes/editor-modules.php:256\n#: public/includes/editor-modules.php:385\n#: public/includes/editor-modules.php:432\nmsgid \"H3 Heading\"\nmsgstr \"Überschrift H3\"\n\n#: public/includes/editor-modules.php:262\n#: public/includes/editor-modules.php:391\nmsgid \"H4 Heading\"\nmsgstr \"Überschrift H4\"\n\n#: public/includes/editor-modules.php:263\n#: public/includes/editor-modules.php:392\nmsgid \"H5 Heading\"\nmsgstr \"Überschrift H5\"\n\n#: public/includes/editor-modules.php:264\n#: public/includes/editor-modules.php:393\nmsgid \"H6 Heading\"\nmsgstr \"Überschrift H6\"\n\n#: public/includes/editor-modules.php:268\n#: public/includes/editor-modules.php:397\nmsgid \"Set Color for Selected Text\"\nmsgstr \"Textfarbe für markierten Text festlegen\"\n\n#: public/includes/editor-modules.php:269\n#: public/includes/editor-modules.php:398\nmsgid \"Choose Color\"\nmsgstr \"Farbe wählen\"\n\n#: public/includes/editor-modules.php:273\n#: public/includes/editor-modules.php:402\n#: public/includes/editor-modules.php:434\nmsgid \"Ordered List\"\nmsgstr \"Nummerierte Liste\"\n\n#: public/includes/editor-modules.php:274\n#: public/includes/editor-modules.php:403\n#: public/includes/editor-modules.php:435\nmsgid \"Unordered List\"\nmsgstr \"Aufzählung\"\n\n#: public/includes/editor-modules.php:278\n#: public/includes/editor-modules.php:407\nmsgid \"Anchor Link\"\nmsgstr \"Link\"\n\n#: public/includes/editor-modules.php:280\n#: public/includes/editor-modules.php:409\nmsgid \"http://url.com\"\nmsgstr \"http://url.com\"\n\n#: public/includes/editor-modules.php:281\n#: public/includes/editor-modules.php:410\nmsgid \"Create Link\"\nmsgstr \"Link erstellen\"\n\n#: public/includes/editor-modules.php:283\n#: public/includes/editor-modules.php:412\nmsgid \"Open in a New Tab\"\nmsgstr \"In einem neuen Tab öffnen\"\n\n#: public/includes/editor-modules.php:347\nmsgid \"Insert Component\"\nmsgstr \"Komponente einfügen\"\n\n#: public/includes/editor-modules.php:367\nmsgid \"Event\"\nmsgstr \"Veranstaltung\"\n\n#: public/includes/editor-modules.php:376\nmsgid \"WordPress Video\"\nmsgstr \"WordPress Video\"\n\n#: public/includes/editor-modules.php:419\n#: public/includes/editor-modules.php:440\nmsgid \"Insert HTML or Code\"\nmsgstr \"HTML oder Code einfügen\"\n\n#: public/includes/editor-modules.php:421\n#: public/includes/editor-modules.php:424\nmsgid \"Enter HTML to insert\"\nmsgstr \"HTML eingeben zum einfügen\"\n\n#: public/includes/editor-modules.php:425\nmsgid \"You can also use Shortcodes\"\nmsgstr \"Du kannst auch Shortcodes verwenden\"\n\n#: public/includes/editor-modules.php:426\nmsgid \"\"\n\"You can also enter a URL to embed, such as Youtube, Vimeo and Twitter URLs.\"\nmsgstr \"Du kannst auch eine URL von YouTube, Vimeo oder Twitter eingeben.\"\n\n#: public/includes/editor-modules.php:440\nmsgid \"Insert\"\nmsgstr \"Einfügen\"\n\n#: public/includes/editor-modules.php:446\nmsgid \"Text Left Align\"\nmsgstr \"Linksbündig\"\n\n#: public/includes/editor-modules.php:447\nmsgid \"Text Center Align\"\nmsgstr \"Text zentrieren\"\n\n#: public/includes/editor-modules.php:448\nmsgid \"Text Right Align\"\nmsgstr \"Rechtsbündig\"\n\n#: public/includes/editor-modules.php:492\n#: public/includes/editor-modules.php:890\n#: public/includes/editor-modules.php:908\n#: public/includes/editor-modules.php:927\nmsgid \"Move\"\nmsgstr \"Verschieben\"\n\n#: public/includes/editor-modules.php:494\n#: public/includes/editor-modules.php:896\n#: public/includes/editor-modules.php:910\n#: public/includes/editor-modules.php:929\nmsgid \"Clone\"\nmsgstr \"Duplizieren\"\n\n#: public/includes/editor-modules.php:495\n#: public/includes/editor-modules.php:897\n#: public/includes/editor-modules.php:911\n#: public/includes/editor-modules.php:930\nmsgid \"Delete\"\nmsgstr \"Löschen\"\n\n#: public/includes/editor-modules.php:517\nmsgid \"Replace Image\"\nmsgstr \"Bild ersetzen\"\n\n#: public/includes/editor-modules.php:518\nmsgid \"Delete Image\"\nmsgstr \"Bild löschen\"\n\n#: public/includes/editor-modules.php:519\nmsgid \"save\"\nmsgstr \"speichern\"\n\n#: public/includes/editor-modules.php:593\nmsgid \"Featured Image\"\nmsgstr \"Beitragsbild\"\n\n#: public/includes/editor-modules.php:593\nmsgid \"Change the featured image for this post.\"\nmsgstr \"Beitragsbild für diesen Beitrag ändern.\"\n\n#: public/includes/editor-modules.php:597\nmsgid \"Change Featured Image\"\nmsgstr \"Beitragsbild ändern\"\n\n#: public/includes/editor-modules.php:598\nmsgid \"Delete Featured Image\"\nmsgstr \"Beitragsbild löschen\"\n\n#: public/includes/editor-modules.php:614\nmsgid \"Change the status of the post to draft or publish.\"\nmsgstr \"Beitragsstatus auf Entwurf oder Veröffentlicht ändern.\"\n\n#: public/includes/editor-modules.php:616\nmsgid \"Draft\"\nmsgstr \"Entwurf\"\n\n#: public/includes/editor-modules.php:618\nmsgid \"Pending\"\nmsgstr \"Ausstehend\"\n\n#: public/includes/editor-modules.php:620\nmsgid \"Publish\"\nmsgstr \"Veröffentlichen\"\n\n#: public/includes/editor-modules.php:630\nmsgid \"Post URL\"\nmsgstr \"Beitrags-URL\"\n\n#: public/includes/editor-modules.php:630\nmsgid \"Change the URL (slug) of this post.\"\nmsgstr \"URL-Titelform (slug) dieses Beitrags ändern.\"\n\n#: public/includes/editor-modules.php:640\nmsgid \"Categories\"\nmsgstr \"Kategorien\"\n\n#: public/includes/editor-modules.php:640\nmsgid \"Type a category name and press enter.\"\nmsgstr \"Kategorie eingeben und mit Enter bestätigen.\"\n\n#: public/includes/editor-modules.php:645\nmsgid \"Tags\"\nmsgstr \"Schlagwörter\"\n\n#: public/includes/editor-modules.php:645\nmsgid \"Type a tag name and press enter.\"\nmsgstr \"Schlagwort eingeben und mit Enter bestätigen.\"\n\n#: public/includes/editor-modules.php:653\nmsgid \"Custom Taxonomy\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:653\nmsgid \"Choose custom taxonomy.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:670\nmsgid \"Excerpt\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:670\nmsgid \"Edit excerpt\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:679\nmsgid \"Post Date\"\nmsgstr \"Veröffentlichungsdatum\"\n\n#: public/includes/editor-modules.php:681\nmsgid \"Set to Now\"\nmsgstr \"Auf Jetzt eingestellt\"\n\n#: public/includes/editor-modules.php:762\nmsgid \"New <span>post</span> title\"\nmsgstr \"Titel des neuen <span>Beitrags</span>\"\n\n#: public/includes/editor-modules.php:762\nmsgid \"Specify title for new post, then save to edit.\"\nmsgstr \"Gib einen Titel für den neuen Beitrag an.\"\n\n#: public/includes/editor-modules.php:763\nmsgid \"Type Your Title Here\"\nmsgstr \"Titel hier eingeben\"\n\n#: public/includes/editor-modules.php:800\nmsgid \"Create\"\nmsgstr \"Erstellen\"\n\n#: public/includes/editor-modules.php:839\nmsgid \"results found\"\nmsgstr \"Ergebnisse gefunden\"\n\n#: public/includes/editor-modules.php:952\nmsgid \"Save Locations\"\nmsgstr \"Locations speichern\"\n\n#: public/includes/editor-modules.php:970\nmsgid \"Save this post and refesh the page to see these changes.\"\nmsgstr \"\"\n\"Speichere diesen Beitrag und aktualisiere die Seite um die Änderungen zu \"\n\"sehen.\"\n\n#: public/includes/editor-modules.php:1109\n#: public/includes/editor-modules.php:1224\n#: public/includes/editor-modules.php:1289\n#, fuzzy\n#| msgid \"Image\"\nmsgid \"Image URL\"\nmsgstr \"Bild\"\n\n#: public/includes/editor-modules.php:1110\n#: public/includes/editor-modules.php:1225\n#: public/includes/editor-modules.php:1290\nmsgid \"\"\n\"URL for the image. Click <em>Select Media</em> to open the WordPress Media \"\n\"Library.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1117\n#: public/includes/editor-modules.php:1232\nmsgid \"Center\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1121\n#: public/includes/editor-modules.php:1236\nmsgid \"Left\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1125\n#: public/includes/editor-modules.php:1240\nmsgid \"Right\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1129\n#: public/includes/editor-modules.php:1244\nmsgid \"Alignment\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1136\n#, fuzzy\n#| msgid \"Image\"\nmsgid \"Image Width\"\nmsgstr \"Bild\"\n\n#: public/includes/editor-modules.php:1137\nmsgid \"\"\n\"Width of the image. You can enter the size in pixels or percentage such as \"\n\"<code>40%</code> or <code>500px</code>.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1142\nmsgid \"Image Height\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1143\nmsgid \"\"\n\"Used only for the Panorama mode. Can be set using pixel values such as \"\n\"<code>500px</code>. If unspecified, the original height would be used. \"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1150\nmsgid \"None\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1158\nmsgid \"URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1162\nmsgid \"Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1163\nmsgid \"Click leads to:\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1169\nmsgid \"URL Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1170\nmsgid \"URL link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1175\n#: public/includes/editor-modules.php:1250\n#, fuzzy\n#| msgid \"Image\"\nmsgid \"Image ALT\"\nmsgstr \"Bild\"\n\n#: public/includes/editor-modules.php:1176\n#: public/includes/editor-modules.php:1251\nmsgid \"ALT tag used for the image. Primarily used for SEO purposes.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1182\n#: public/includes/editor-modules.php:1256\n#, fuzzy\n#| msgid \"Gallery Caption\"\nmsgid \"Caption\"\nmsgstr \"Galerie Bildunterschrift\"\n\n#: public/includes/editor-modules.php:1183\n#: public/includes/editor-modules.php:1257\n#, fuzzy\n#| msgid \"Add an optional caption for the gallery.\"\nmsgid \"Optional caption for the image.\"\nmsgstr \"Füge eine optionale Bildunterschrift zur Galerie hinzu.\"\n\n#: public/includes/editor-modules.php:1188\n#, fuzzy\n#| msgid \"Add Images\"\nmsgid \"An image.\"\nmsgstr \"Bilder hinzufügen\"\n\n#: public/includes/editor-modules.php:1262\nmsgid \"Link URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1263\nmsgid \"Optional URL to link.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1268\nmsgid \"A WP Image Block.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1283\nmsgid \"Cover\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1294\nmsgid \"A WP Cover Block.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1323\nmsgid \"Use the slider to view the revision live on the page.\"\nmsgstr \"\"\n\"Verwende den Schieberegler um die Revision in Echtzeit auf der Seite \"\n\"anzuzeigen.\"\n\n#: public/includes/editor-modules.php:1330\nmsgid \"Select\"\nmsgstr \"Auswählen\"\n\n#: public/includes/helpers.php:449\nmsgid \"No posts to show\"\nmsgstr \"Keine anzuzeigenden Beiträge\"\n\n#: public/includes/helpers.php:455\nmsgid \"No revisions found\"\nmsgstr \"Keine Revisionen gefunden\"\n\n#: public/includes/lasso.php:292\nmsgid \"Post being edited by \"\nmsgstr \"\"\n\n#: public/includes/tour.php:67\nmsgid \"Don't show this again\"\nmsgstr \"Diese Meldung nicht wieder anzeigen\"\n\n#: public/includes/tour.php:71\nmsgid \"Okay, got it!\"\nmsgstr \"OK, verstanden!\"\n\n#: public/includes/tour.php:96\nmsgid \"\"\n\"Access posts by clicking the list icon. Create a new post by clicking the \"\n\"new post icon.\"\nmsgstr \"\"\n\"Greife auf Beiträge zu indem Du auf das Listen-Symbol klickst. Erstelle \"\n\"einen neuen Beitrag indem Du auf das „Neuer Beitrag“-Symbol klickst.\"\n\n#: public/includes/tour.php:99\nmsgid \"\"\n\"While on a single post, edit by clicking the Pen icon. Access post settings \"\n\"with the settings icon. Press escape to exit any modal.\"\nmsgstr \"\"\n\"Auf einer Beitragsseite klicke auf das Stift-Symbol um den Beitrag zu \"\n\"bearbeiten. Bearbeite die Beitrags-Einstellungen mit dem Zahnrad-Symbol. \"\n\"Drücke „Esc“ um jedes Fenster zu verlassen.\"\n\n#: public/includes/tour.php:102\nmsgid \"\"\n\"Highlight a piece of text, and click on a formatting option to style it. \"\n\"Click the Disk icon or CMD-S to save. Click the orange \\\"X\\\" button to exit \"\n\"the editor.\"\nmsgstr \"\"\n\"Markiere einen Textabschnitt und klicke auf eine der Formatoptionen um ihn \"\n\"zu gestalten. Klicke das Disketten-Symbol oder drücke Strg+S um zu \"\n\"speichern. Klicke den orangen „X“-Button um den Editor zu verlassen.\"\n\n#: public/includes/tour.php:105\nmsgid \"\"\n\"Story components can be added by clicking the plus icon, and dragging any \"\n\"component from the component tray into the story.\"\nmsgstr \"\"\n\"Beitragskomponenten (Aesop Story Engine-Komponenten) können durch klicken \"\n\"des Plus-Symbols hinzugefügt werden. Ziehen Sie eine beliebige Komponente in \"\n\"den Beitrag um sie zu verwenden.\"\n\n#~ msgid \"\"\n#~ \"Currently Editus does not support Gutenberg. It will be disabled on \"\n#~ \"Gutenberg enabled posts.\"\n#~ msgstr \"\"\n#~ \"Derzeit unterstützt Editus Gutenberg nicht. Es wird für Beiträge, die mit \"\n#~ \"Gutenberg bearbeitet werden, deaktiviert.\"\n\n#, fuzzy\n#~| msgid \"Unordered List\"\n#~ msgid \"Unordered\"\n#~ msgstr \"Aufzählung\"\n\n#~ msgid \"This theme requires the following plugin: %1$s.\"\n#~ msgid_plural \"This theme requires the following plugins: %1$s.\"\n#~ msgstr[0] \"Dieses Thema benötigt das folgende Plugin: %1$s.\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"This theme recommends the following plugin: %1$s.\"\n#~ msgid_plural \"This theme recommends the following plugins: %1$s.\"\n#~ msgstr[0] \"Dieses Theme empfiehlt das folgende Plugin: %1$s.\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"\"\n#~ \"Sorry, but you do not have the correct permissions to install the %1$s \"\n#~ \"plugin.\"\n#~ msgid_plural \"\"\n#~ \"Sorry, but you do not have the correct permissions to install the %1$s \"\n#~ \"plugins.\"\n#~ msgstr[0] \"\"\n#~ \"Pardon, aber Sie haben nicht die erforderlichen Berechtigungen, um dieses \"\n#~ \"%1$s Plugin zu installieren.\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"\"\n#~ \"The following plugin needs to be updated to its latest version to ensure \"\n#~ \"maximum compatibility with this theme: %1$s.\"\n#~ msgid_plural \"\"\n#~ \"The following plugins need to be updated to their latest version to \"\n#~ \"ensure maximum compatibility with this theme: %1$s.\"\n#~ msgstr[0] \"\"\n#~ \"Das folgende Plugin muss auf die neueste Version aktualisiert werden, um \"\n#~ \"maximale Kompatibilität mit diesem Thema zu sicher zu stellen: %1$s.\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"There is an update available for: %1$s.\"\n#~ msgid_plural \"There are updates available for the following plugins: %1$s.\"\n#~ msgstr[0] \"Es ist ein Update verfügbar für:%1$s.\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"\"\n#~ \"Sorry, but you do not have the correct permissions to update the %1$s \"\n#~ \"plugin.\"\n#~ msgid_plural \"\"\n#~ \"Sorry, but you do not have the correct permissions to update the %1$s \"\n#~ \"plugins.\"\n#~ msgstr[0] \"\"\n#~ \"Sorry, aber Sie haben nicht die erforderlichen Berechtigungen, um das \"\n#~ \"%1$s Plugin zu aktualisieren.\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"The following required plugin is currently inactive: %1$s.\"\n#~ msgid_plural \"The following required plugins are currently inactive: %1$s.\"\n#~ msgstr[0] \"Das folgende erforderliche Plugin ist derzeit inaktiv: %1$s.\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"The following recommended plugin is currently inactive: %1$s.\"\n#~ msgid_plural \"\"\n#~ \"The following recommended plugins are currently inactive: %1$s.\"\n#~ msgstr[0] \"Das folgende empfohlene Plugin ist derzeit inaktiv: %1$s.\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"\"\n#~ \"Sorry, but you do not have the correct permissions to activate the %1$s \"\n#~ \"plugin.\"\n#~ msgid_plural \"\"\n#~ \"Sorry, but you do not have the correct permissions to activate the %1$s \"\n#~ \"plugins.\"\n#~ msgstr[0] \"\"\n#~ \"Pardon, aber Sie haben nicht die erforderlichen Berechtigungen, um dieses \"\n#~ \"%1$s Plugin zu aktivieren.\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"Begin installing plugin\"\n#~ msgid_plural \"Begin installing plugins\"\n#~ msgstr[0] \"Beginne mit der Installation des Plugins\"\n#~ msgstr[1] \"Beginne mit der Installation der Plugins\"\n\n#~ msgid \"Begin updating plugin\"\n#~ msgid_plural \"Begin updating plugins\"\n#~ msgstr[0] \"Beginne mit der Aktualisierung des Plugins\"\n#~ msgstr[1] \"Beginne mit der Aktualisierung der Plugins\"\n\n#~ msgid \"Begin activating plugin\"\n#~ msgid_plural \"Begin activating plugins\"\n#~ msgstr[0] \"Beginne mit der Aktivierung des Plugins\"\n#~ msgstr[1] \"Beginne mit der Aktivierung ders Plugins\"\n\n#~ msgid \"This plugin needs to be updated to be compatible with your theme.\"\n#~ msgstr \"\"\n#~ \"Dieses Plugin muss aktualisiert werden, um mit Deinem Theme kompatibel zu \"\n#~ \"sein.\"\n\n#~ msgid \"Update Required\"\n#~ msgstr \"Aktualisierung erforderlich\"\n\n#~ msgid \"Set the parent_slug config variable instead.\"\n#~ msgstr \"Stattdessen die parent_slug-Konfigurationsvariable setzen.\"\n\n#~ msgid \"Return to the Dashboard\"\n#~ msgstr \"Zurüch zum Dashboard\"\n\n#~ msgid \"\"\n#~ \"The remote plugin package does not contain a folder with the desired slug \"\n#~ \"and renaming did not work.\"\n#~ msgstr \"\"\n#~ \"Das externe Plugin-Paket enthält keinen Ordner mit der erforderlichen \"\n#~ \"Bezeichnung und eine Umbenennung war nicht möglich.\"\n\n#~ msgid \"\"\n#~ \"Please contact the plugin provider and ask them to package their plugin \"\n#~ \"according to the WordPress guidelines.\"\n#~ msgstr \"\"\n#~ \"Bitte wende Dich an den Anbieter des Plugins, um eine Plugin-Version nach \"\n#~ \"den WordPress-Richtlinien zu erhalten.\"\n\n#~ msgid \"\"\n#~ \"The remote plugin package consists of more than one file, but the files \"\n#~ \"are not packaged in a folder.\"\n#~ msgstr \"\"\n#~ \"Das externe Plugin-Paket besteht aus mehreren Dateien, die jedoch nicht \"\n#~ \"in einem Ordner gepackt wurden.\"\n\n#~ msgctxt \"plugin A *and* plugin B\"\n#~ msgid \"and\"\n#~ msgstr \"Plugin A*und* Plugin B und\"\n\n#~ msgctxt \"%s = version number\"\n#~ msgid \"TGMPA v%s\"\n#~ msgstr \"TGMPA v% s\"\n\n#~ msgctxt \"%1$s = install status, %2$s = update status\"\n#~ msgid \"%1$s, %2$s\"\n#~ msgstr \"%1$s, %2$s\"\n\n#~ msgctxt \"plugins\"\n#~ msgid \"All <span class=\\\"count\\\">(%s)</span>\"\n#~ msgid_plural \"All <span class=\\\"count\\\">(%s)</span>\"\n#~ msgstr[0] \"Alle <span class=\\\"count\\\">(%s)</span>\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"To Install <span class=\\\"count\\\">(%s)</span>\"\n#~ msgid_plural \"To Install <span class=\\\"count\\\">(%s)</span>\"\n#~ msgstr[0] \"<span class=„event_booking_status pending“>%s</span>\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"Update Available <span class=\\\"count\\\">(%s)</span>\"\n#~ msgid_plural \"Update Available <span class=\\\"count\\\">(%s)</span>\"\n#~ msgstr[0] \"Aktualisierung verfügbar <span class=\\\"count\\\">(%s)</span>\"\n#~ msgstr[1] \"\"\n\n#~ msgid \"To Activate <span class=\\\"count\\\">(%s)</span>\"\n#~ msgid_plural \"To Activate <span class=\\\"count\\\">(%s)</span>\"\n#~ msgstr[0] \"Zum Aktivieren <span class=\\\"count\\\">(%s)</span>\"\n#~ msgstr[1] \"\"\n\n#~ msgctxt \"as in: \\\"version nr unknown\\\"\"\n#~ msgid \"unknown\"\n#~ msgstr \"unbekannt\"\n\n#~ msgctxt \"%2$s = plugin name in screen reader markup\"\n#~ msgid \"Install %2$s\"\n#~ msgstr \"Installiere %2$s\"\n\n#~ msgctxt \"%2$s = plugin name in screen reader markup\"\n#~ msgid \"Update %2$s\"\n#~ msgstr \"Aktualisiere %2$s\"\n\n#~ msgctxt \"%2$s = plugin name in screen reader markup\"\n#~ msgid \"Activate %2$s\"\n#~ msgstr \"Aktiviere %2$s\"\n\n#~ msgid \"Upgrade message from the plugin author:\"\n#~ msgstr \"Upgrade-Nachricht vom Plugin Autor:\"\n\n#~ msgid \"No plugins were selected to be activated. No action taken.\"\n#~ msgstr \"\"\n#~ \"Es wurden keine Plugins zur Aktivierung ausgewählt. Es wurde daher nichts \"\n#~ \"unternommen.\"\n\n#~ msgid \"No plugins are available to be activated at this time.\"\n#~ msgstr \"Derzeit stehen keine Plugins zur Aktivierung zur Verfügung.\"\n\n#~ msgid \"Show Details\"\n#~ msgstr \"Weitere Details\"\n\n#~ msgid \"Hide Details\"\n#~ msgstr \"Details verbergen\"\n\n#~ msgid \"%1$s installed successfully.\"\n#~ msgstr \"%1$s erfolgreich installiert.\"\n\n#~ msgid \"This plugin requires the following plugin: %1$s.\"\n#~ msgid_plural \"This plugin requires the following plugins: %1$s.\"\n#~ msgstr[0] \"Dieses Plugin erfordert das folgende Plugin:%1$s.\"\n#~ msgstr[1] \"Dieses Plugin erfordert die folgenden Plugin:%1$s.\"\n\n#~ msgid \"This plugin recommends the following plugin: %1$s.\"\n#~ msgid_plural \"This plugin recommends the following plugins: %1$s.\"\n#~ msgstr[0] \"Dieses Plugin empfiehlt die folgende Plugin: %1$s.\"\n#~ msgstr[1] \"Dieses Plugin empfiehlt die folgende Plugins: %1$s.\"\n\n#~ msgid \"\"\n#~ \"Sorry, but you do not have the correct permissions to install the %s \"\n#~ \"plugin. Contact the administrator of this site for help on getting the \"\n#~ \"plugin installed.\"\n#~ msgid_plural \"\"\n#~ \"Sorry, but you do not have the correct permissions to install the %s \"\n#~ \"plugins. Contact the administrator of this site for help on getting the \"\n#~ \"plugins installed.\"\n#~ msgstr[0] \"\"\n#~ \"Sorry, aber Sie haben nicht die richtigen Berechtigungen, um das %s \"\n#~ \"Plugin zu installieren. Wenden Sie sich an den Administrator dieser \"\n#~ \"Website, um Hilfe bei der Installation des Plugins zu erhalten.\"\n#~ msgstr[1] \"\"\n#~ \"Sorry, aber Sie haben nicht die richtigen Berechtigungen, um das %s \"\n#~ \"Plugin zu installieren. Wenden Sie sich an den Administrator dieser \"\n#~ \"Website, um Hilfe bei der Installation des Plugins zu erhalten.\"\n\n#~ msgid \"\"\n#~ \"Sorry, but you do not have the correct permissions to activate the %s \"\n#~ \"plugin. Contact the administrator of this site for help on getting the \"\n#~ \"plugin activated.\"\n#~ msgid_plural \"\"\n#~ \"Sorry, but you do not have the correct permissions to activate the %s \"\n#~ \"plugins. Contact the administrator of this site for help on getting the \"\n#~ \"plugins activated.\"\n#~ msgstr[0] \"\"\n#~ \"Entschuldigung, aber Du hast nicht die Berechtigung zum Aktivieren des %s \"\n#~ \"Plugin. Wenden Sie sich an den Administrator dieser Website, um Hilfe bei \"\n#~ \"der Aktivierung der Plugins zu erhalten.\"\n#~ msgstr[1] \"\"\n#~ \"Entschuldigung, aber Du hast nicht die Berechtigung zum Aktivieren der %s \"\n#~ \"Plugins. Wenden Sie sich an den Administrator dieser Website, um Hilfe \"\n#~ \"bei der Aktivierung der Plugins zu erhalten.\"\n\n#~ msgid \"\"\n#~ \"The following plugin needs to be updated to its latest version to ensure \"\n#~ \"maximum compatibility with this plugin: %1$s.\"\n#~ msgid_plural \"\"\n#~ \"The following plugins need to be updated to their latest version to \"\n#~ \"ensure maximum compatibility with this plugin: %1$s.\"\n#~ msgstr[0] \"\"\n#~ \"Das folgende Plugin muss auf die neueste Version aktualisiert werden, um \"\n#~ \"maximale Kompatibilität mit diesem Theme sicher zu stellen: %1$s.\"\n#~ msgstr[1] \"\"\n#~ \"Das folgenden Plugins müssen auf die neueste Version aktualisiert werden, \"\n#~ \"um maximale Kompatibilität mit diesem Theme sicher zu stellen: %1$s.\"\n\n#~ msgid \"\"\n#~ \"Sorry, but you do not have the correct permissions to update the %s \"\n#~ \"plugin. Contact the administrator of this site for help on getting the \"\n#~ \"plugin updated.\"\n#~ msgid_plural \"\"\n#~ \"Sorry, but you do not have the correct permissions to update the %s \"\n#~ \"plugins. Contact the administrator of this site for help on getting the \"\n#~ \"plugins updated.\"\n#~ msgstr[0] \"\"\n#~ \"Entschuldigung, aber du hast nicht die richtigen Berechtigungen, um das \"\n#~ \"%s Plugin zu aktualisieren. Wende dich an den Administrator dieser \"\n#~ \"Website, um Hilfe zum Aktualisieren des Plugins zu erhalten.\"\n#~ msgstr[1] \"\"\n#~ \"Entschuldigung, aber du hast nicht die richtigen Berechtigungen, um diese \"\n#~ \"%s Plugin zu aktualisieren. Wende dich an den Administrator dieser \"\n#~ \"Website, um Hilfe zum Aktualisieren des Plugins zu erhalten.\"\n"
  },
  {
    "path": "languages/lasso-es_ES.po",
    "content": "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Editus\\n\"\n\"POT-Creation-Date: 2022-08-02 15:42-0400\\n\"\n\"PO-Revision-Date: 2022-08-02 15:43-0400\\n\"\n\"Last-Translator: \\n\"\n\"Language-Team: \\n\"\n\"Language: es_ES\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1);\\n\"\n\"X-Generator: Poedit 3.1.1\\n\"\n\"X-Poedit-Basepath: ..\\n\"\n\"X-Poedit-KeywordsList: __;_e;esc_attr_e\\n\"\n\"X-Poedit-SourceCharset: UTF-8\\n\"\n\"X-Poedit-SearchPath-0: .\\n\"\n\"X-Poedit-SearchPathExcluded-0: node_modules\\n\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:177\n#, php-format\nmsgid \"\"\n\"There is a new version of %1$s available. <a target=\\\"_blank\\\" class=\"\n\"\\\"thickbox\\\" href=\\\"%2$s\\\">View version %3$s details</a>.\"\nmsgstr \"\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:184\n#, php-format\nmsgid \"\"\n\"There is a new version of %1$s available. <a target=\\\"_blank\\\" class=\"\n\"\\\"thickbox\\\" href=\\\"%2$s\\\">View version %3$s details</a> or <a href=\\\"%4$s\"\n\"\\\">update now</a>.\"\nmsgstr \"\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:324\nmsgid \"You do not have permission to install plugin updates\"\nmsgstr \"\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:324\nmsgid \"Error\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:333\n#: admin/includes/menus/welcome.php:227\nmsgid \"Install Required Plugins\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:334\n#: admin/includes/menus/welcome.php:228\nmsgid \"Install Plugins\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:335\n#: admin/includes/menus/welcome.php:229\n#, php-format\nmsgid \"Installing Plugin: %s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:336\n#: admin/includes/menus/welcome.php:230\nmsgid \"Something went wrong with the plugin API.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:397\n#: admin/includes/menus/welcome.php:241\nmsgid \"Return to Required Plugins Installer\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:398\nmsgid \"Return to the dashboard\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:399\n#: admin/includes/class-tgm-plugin-activation.php:3029\n#: admin/includes/menus/welcome.php:242\nmsgid \"Plugin activated successfully.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:400\nmsgid \"The following plugin was activated successfully:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:401\n#, php-format\nmsgid \"No action taken. Plugin %1$s was already active.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:402\n#, php-format\nmsgid \"\"\n\"Plugin not activated. A higher version of %s is needed for this theme. \"\n\"Please update the plugin.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:403\n#, php-format\nmsgid \"All plugins installed and activated successfully. %1$s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:404\nmsgid \"Dismiss this notice\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:405\nmsgid \"Please contact the administrator of this site for help.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2167\nmsgid \"Required\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2170\nmsgid \"Recommended\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2186\nmsgid \"WordPress Repository\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2189\nmsgid \"External Source\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2192\nmsgid \"Pre-Packaged\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2209\nmsgid \"Not Installed\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2213\nmsgid \"Installed But Not Activated\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2215\nmsgid \"Active\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2221\nmsgid \"Required Update not Available\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2224\nmsgid \"Requires Update\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2227\nmsgid \"Update recommended\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2379\nmsgid \"Installed version:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2387\nmsgid \"Minimum required version:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2399\nmsgid \"Available version:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2422\n#, php-format\nmsgid \"\"\n\"No plugins to install, update or activate. <a href=\\\"%1$s\\\">Return to the \"\n\"Dashboard</a>\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2436\nmsgid \"Plugin\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2437\nmsgid \"Source\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2438\nmsgid \"Type\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2442\n#: admin/includes/menus/welcome.php:118\nmsgid \"Version\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2443\n#: admin/includes/menus/welcome.php:49 public/includes/editor-modules.php:614\nmsgid \"Status\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2603\nmsgid \"Install\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2609\nmsgid \"Update\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2612\nmsgid \"Activate\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2643\nmsgid \"No plugins were selected to be installed. No action taken.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2645\nmsgid \"No plugins were selected to be updated. No action taken.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2681\nmsgid \"No plugins are available to be installed at this time.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2683\nmsgid \"No plugins are available to be updated at this time.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3028\nmsgid \"Plugin activation failed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3362\n#, php-format\nmsgid \"Updating Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3364\n#, php-format\nmsgid \"An error occurred while installing %1$s: <strong>%2$s</strong>.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3365\n#, php-format\nmsgid \"The installation of %1$s failed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3369\nmsgid \"\"\n\"The installation and activation process is starting. This process may take a \"\n\"while on some hosts, so please be patient.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3370\n#, php-format\nmsgid \"%1$s installed and activated successfully.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3371\nmsgid \"All installations and activations have been completed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3372\n#, php-format\nmsgid \"Installing and Activating Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3375\nmsgid \"\"\n\"The installation process is starting. This process may take a while on some \"\n\"hosts, so please be patient.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3377\nmsgid \"All installations have been completed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3378\n#, php-format\nmsgid \"Installing Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"\"\n\n#: admin/includes/load_admin.php:151\nmsgid \"Dismiss this notice.\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:30\nmsgid \"Aesopinteractive LLC\"\nmsgstr \"Aesopinteractive LLC\"\n\n#: admin/includes/menus/license.php:38 admin/includes/menus/license.php:57\nmsgid \"License Key\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:38\nmsgid \"License\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:47\nmsgid \"Editus License\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:48\nmsgid \"\"\n\"Input the license key you recieved with your purchase to ensure your version \"\n\"of Editus stays updated.\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:66 admin/includes/menus/license.php:75\nmsgid \"Activate License\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:70\nmsgid \"active\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:72\nmsgid \"Deactivate License\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:26 public/includes/editor-modules.php:493\n#: public/includes/editor-modules.php:892\n#: public/includes/editor-modules.php:894\n#: public/includes/editor-modules.php:909\n#: public/includes/editor-modules.php:928\nmsgid \"Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:169\nmsgid \"Editus Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:177\nmsgid \"Enable for:\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:181\nmsgid \"Enable Editus for the following post types.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:203\nmsgid \"Internal Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:206\nmsgid \"Article Class\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:207\nmsgid \"\"\n\"Provide the CSS class (including the preceding dot) of container that holds \"\n\"the post. This should be the first parent container class that holds \"\n\"the_content.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:212\nmsgid \"Featured Image Class\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:213\nmsgid \"\"\n\"Provide the CSS class that uses a featured image as a background image. This \"\n\"currently only supports themes that have the featured image set as \"\n\"background image.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:218\nmsgid \"Article Title Class\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:219\nmsgid \"\"\n\"Provide the CSS class for the post title. This will enable you to update the \"\n\"title of the post by clicking and typing.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:224\nmsgid \"Ignored Items to Save\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:225\nmsgid \"\"\n\"If your post container holds additional markup, list the css class names \"\n\"(comma separated, including the dot) of those items. When you enter the \"\n\"editor, Editus will remove (NOT delete) these items so that it does not save \"\n\"them as HTML.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:230\nmsgid \"Read Only Items\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:231\nmsgid \"\"\n\"If your post has items that should not be editable, list the css class names \"\n\"(comma separated, including the dot) of those items.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:237\nmsgid \"Show Ignored Items\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:238\nmsgid \"\"\n\"By default the ignored items are hidden. Check this to show ignored items \"\n\"while keeping them uneditable.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:242\nmsgid \"Editor UI\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:246\nmsgid \"Use the Old Toolbar\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:247\nmsgid \"\"\n\"Use this option to disable the new color options and use the pre-1.0 toolbar.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:251\nmsgid \"Editor Bar Color Top\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:252\nmsgid \"Editor Bar Color Bottom\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:253\nmsgid \"Dialog Color\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:254\nmsgid \"Icon/Text Color\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:256\nmsgid \"Default Colors\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:261\nmsgid \"Enable H2 and H3 Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:262\nmsgid \"Show the buttons to set H2 and H3 settings.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:267\nmsgid \"Enable H4/H5/H6 Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:268\nmsgid \"Show the buttons to set H4/H5/H6 settings.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:274\nmsgid \"Enable OL/UL Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:275\nmsgid \"\"\n\"Show the buttons to create Ordered and Unordered Lists from text selection.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:280\nmsgid \"Enable Text Color Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:281\nmsgid \"Show the buttons to set text colors.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:286\nmsgid \"Enable Text Align Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:287\nmsgid \"Show the buttons to set text alignment.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:293\nmsgid \"Make links editable under the Editing Mode\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:294\nmsgid \"\"\n\"Make links editable under the Editing Mode. Turning this on will make the \"\n\"links non-clickable while editing.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:298\nmsgid \"Insert Component UI\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:299\nmsgid \"UI mechanism to insert components\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:301\nmsgid \"Drag and Drop\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:304\nmsgid \"Click\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:307\nmsgid \"Auto Button on Empty Paragraph. medium.com-like UI.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:313\nmsgid \"Popup When Text is Selected\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:314\nmsgid \"\"\n\"Instead of using the bottom toolbar to format texts, use a popup box to \"\n\"format texts.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:320\nmsgid \"Component\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:324\nmsgid \"Additional Component: Table\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:325\nmsgid \"Allow user to add and edit tables.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:331\nmsgid \"Additional Component: Paragraph\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:332\nmsgid \"Plain HTML Paragraph.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:363\nmsgid \"Use Simple Image\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:364\nmsgid \"Use Simple Image Component without Extra Options.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:371\nmsgid \"Use WP Image Block\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:372\nmsgid \"\"\n\"Use WP Image Block as the image component. Gutenberg Block Editor needs to \"\n\"be enabled.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:379\nmsgid \"Post Settings UI\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:383\nmsgid \"Disable Post Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:384\nmsgid \"\"\n\"Check this to disable users from being able to edit post settings from the \"\n\"front-end.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:389\nmsgid \"Allow Changing Post Date\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:390\nmsgid \"\"\n\"Add the date selector to change the post's date to the Post Setting dialog\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:395\nmsgid \"Allow Editing Excerpt\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:396\nmsgid \"Allow the post's excerpt to be edited in the Post Setting dialog\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:401\nmsgid \"Allow Adding New Category\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:402\nmsgid \"\"\n\"Add the user to create new, previously non-existing categories for posts.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:407\nmsgid \"Do Not Allow \\\"Pending\\\" Status\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:408\nmsgid \"Remove the Option to Set the Status to Pending.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:413\nmsgid \"Remove POST URL Option\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:414\nmsgid \"Remove the Option to Set the URL for the Post.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:419\nmsgid \"Disable Post Adding\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:420\nmsgid \"\"\n\"Check this box to disable users from being able to add new posts from the \"\n\"front-end.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:425\nmsgid \"Support Custom Taxonomy\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:426\nmsgid \"Allow editing custom taxonomies.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:432\nmsgid \"Misc\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:436\nmsgid \"Do Not Show Tour Dialog\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:437\nmsgid \"Check this box to disable the tour dialog box for all users.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:441\nmsgid \"Placeholder Text for New Post\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:442\nmsgid \"Placeholder text to be displayed when a new post is created.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:443 includes/process/new_object.php:38\n#: public/includes/assets.php:248\nmsgid \"Once upon a time...\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:448\nmsgid \"Do Not Allow Shortcode Editing\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:449\nmsgid \"Check this box to disable frontend editing of shortcodes.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:453\nmsgid \"\\\"Bold\\\" Tag\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:454\nmsgid \"Choose the HTML tag used for the \\\"Bold\\\" style.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:459\nmsgid \"\\\"Italic\\\" Tag\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:460\nmsgid \"Choose the HTML tag used for the \\\"Italic\\\" style.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:466\nmsgid \"Auto Prefix HTTP to links\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:467\nmsgid \"\"\n\"When user adds a hyperlink, automatically add http:// if the user does not \"\n\"specify it explicitly.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:471\nmsgid \"Advanced Options\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:472\nmsgid \"\"\n\"Suggested not to turn these options on without consulting the developer.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:477\nmsgid \"Disable Aesop Component Conversion\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:478\nmsgid \"\"\n\"Check this box to disable the conversion process used on Aesop Story Engine \"\n\"components.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:483\nmsgid \"Enable Auto Save\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:484\nmsgid \"Check this box to enable auto save.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:489\nmsgid \"Disable Post Saving\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:490\nmsgid \"\"\n\"By default the editor will update the database with the post or page it is \"\n\"being used on. Check this box to disable this. If you check this box, it is \"\n\"assumed that you will be using the provided filters to save your own content.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:496\nmsgid \"Disable Post Editing\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:497\nmsgid \"\"\n\"You may use this option if you only want to edit custom fields. Refer <a \"\n\"href=\\\"https://edituswp.com/editing-and-updating-custom-fields-from-frontend/\"\n\"\\\">here</a> for more information. The custom fields you specify will be \"\n\"still editable under the editing mode.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:503\nmsgid \"Don't Use REST API to Save\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:504\nmsgid \"\"\n\"By default the editor will use REST API to save posts. Check this box to use \"\n\"custom AJAX calls instead.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:510\nmsgid \"Don't Wrap Shortcodes\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:511\nmsgid \"\"\n\"By default Editus wraps shortcodes so they can be preserved. Disable this \"\n\"behavior.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:521\nmsgid \"Save Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:48\nmsgid \"Editus\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:49\nmsgid \"Welcome\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:71\nmsgid \"\"\n\"We will check the current theme on every site in your network and give you a \"\n\"quick status feedback here. You can see the status by visiting the Editus \"\n\"menu on each site.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:90\nmsgid \"You're Ready to Rock!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:92\nmsgid \"Your theme is automatically supported. No additional setup is needed.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:94\nmsgid \"\"\n\"Editus will place a small menu on the bottom of your site. While on a single \"\n\"post or page, click the \\\"pen\\\" icon to go into edit mode. Press escape to \"\n\"get out of edit mode.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:117\nmsgid \"Welcome to Editus\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:123\nmsgid \"Help\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:124\nmsgid \"Twitter\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:125\nmsgid \"Facebook\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:158\nmsgid \"Article CSS Class Needed!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"Before using Editus,\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"enter and save\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"\"\n\"the CSS class of the container that holds your post and page content. You \"\n\"can <a href=\\\"https://dl.dropboxusercontent.com/u/5594632/lasso-media/doc-\"\n\"movies/using-inspector-lasso.gif\\\" target=\\\"_blank\\\">use a tool like \"\n\"inspector</a> in Chrome or Firefox to find this CSS class, or \"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"email us.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"with a link to a public URL with the theme and we'll find it for you.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:166\nmsgid \"\"\n\"Just a heads up that the WP REST API isn't activated. This is required to \"\n\"list the posts and pages on the front-end.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:173\nmsgid \"Just a heads up that \"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:174 admin/includes/menus/welcome.php:211\nmsgid \"Aesop Story Engine\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:174\nmsgid \"\"\n\"isn't activated. It's not required to use Editus, but you won't get the cool \"\n\"drag and drop components without it activated. It's free!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:180\nmsgid \"WP Side Comments Compatibility Warning!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:181\nmsgid \"\"\n\"Since Editus saves the HTML of a post, this may cause undesired issues. \"\n\"We're working to resolve incompatibilities faster than a jack rabbit in a \"\n\"hot greasy griddle in the middle of August.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:187\nmsgid \"License Key Not Activated\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:188\nmsgid \"\"\n\"Just a heads up, your license key isn't activated. Enter your license key \"\n\"into the License tab on the left in order to receive plugin update \"\n\"notifications.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:192\nmsgid \"License Key Invalid\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \"The license key that you entered is \"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \"invalid\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \". It may have been entered incorreclty, or may have expired.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:243\n#, php-format\nmsgid \"All plugins installed and activated successfully. %s\"\nmsgstr \"\"\n\n#: includes/process/gallery.php:40\nmsgid \"Save and refresh to view gallery.\"\nmsgstr \"\"\n\n#: includes/process/gallery.php:199\nmsgid \"Delete From Gallery\"\nmsgstr \"\"\n\n#: includes/process/gallery.php:200\nmsgid \"Edit Image Caption\"\nmsgstr \"\"\n\n#: internal-api/auth.php:67\nmsgid \"Unauthorized action\"\nmsgstr \"\"\n\n#: internal-api/auth.php:71\nmsgid \"\"\n\"All callback classes used for processing the Editus Internal API must \"\n\"implement the lasso\\\\internal_api\\\\api_action interface.\"\nmsgstr \"\"\n\n#: internal-api/auth.php:76\nmsgid \"Nonce invalid\"\nmsgstr \"\"\n\n#: internal-api/route.php:30\nmsgid \"Editus API Error.\"\nmsgstr \"\"\n\n#: internal-api/route.php:66\nmsgid \"Nonce not set.\"\nmsgstr \"\"\n\n#: lasso.php:130\nmsgid \"Insert Column\"\nmsgstr \"\"\n\n#: lasso.php:131\nmsgid \"Insert Row\"\nmsgstr \"\"\n\n#: lasso.php:132\nmsgid \"Delete Column\"\nmsgstr \"\"\n\n#: lasso.php:133\nmsgid \"Delete Row\"\nmsgstr \"\"\n\n#: lasso.php:134\nmsgid \"Delete Table\"\nmsgstr \"\"\n\n#: lasso.php:149 lasso.php:159\nmsgid \"HTML Table\"\nmsgstr \"\"\n\n#: lasso.php:192 lasso.php:220\nmsgid \"HTML Paragraph\"\nmsgstr \"\"\n\n#: public/includes/assets.php:146 public/includes/editor-modules.php:713\n#: public/includes/option-engine.php:132\nmsgid \"Save\"\nmsgstr \"\"\n\n#: public/includes/assets.php:147\nmsgid \"Please Select Text First.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:148 public/includes/editor-modules.php:439\n#: public/includes/editor-modules.php:706\n#: public/includes/editor-modules.php:788\n#: public/includes/editor-modules.php:1329\nmsgid \"Cancel\"\nmsgstr \"Cancelar\"\n\n#: public/includes/assets.php:149\nmsgid \"Exit Editor\"\nmsgstr \"\"\n\n#: public/includes/assets.php:150\nmsgid \"Saving...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:151\nmsgid \"Saved!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:152\nmsgid \"Adding...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:153\nmsgid \"Added!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:154\nmsgid \"Loading...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:155\nmsgid \"Load More\"\nmsgstr \"\"\n\n#: public/includes/assets.php:156 public/includes/helpers.php:457\nmsgid \"Close\"\nmsgstr \"Cerra\"\n\n#: public/includes/assets.php:157\nmsgid \"No more posts found\"\nmsgstr \"\"\n\n#: public/includes/assets.php:158\nmsgid \"Fetching failed.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:159\nmsgid \"Gallery Created!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:160\nmsgid \"Gallery Updated!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:161\nmsgid \"Just write...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:162\nmsgid \"Choose an image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:163\nmsgid \"Update Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:164\nmsgid \"Insert Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:165\nmsgid \"Select Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:166\nmsgid \"Remove featured image?\"\nmsgstr \"\"\n\n#: public/includes/assets.php:167\nmsgid \"Update Selected Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:168\nmsgid \"Choose images\"\nmsgstr \"\"\n\n#: public/includes/assets.php:169\nmsgid \"Edit Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:170\n#: public/includes/editor-modules--gallery.php:28\nmsgid \"Add Images\"\nmsgstr \"\"\n\n#: public/includes/assets.php:171\nmsgid \"Add New Gallery\"\nmsgstr \"\"\n\n#: public/includes/assets.php:172\nmsgid \"Select Editus Gallery Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:173\nmsgid \"Use Selected Images\"\nmsgstr \"\"\n\n#: public/includes/assets.php:174\nmsgid \"Publish Post?\"\nmsgstr \"\"\n\n#: public/includes/assets.php:175\nmsgid \"Yes, publish it!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:176\nmsgid \"Trash Post?\"\nmsgstr \"\"\n\n#: public/includes/assets.php:177\nmsgid \"Yes, trash it!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:178\nmsgid \"Oh snap!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:179\nmsgid \"O.K. got it!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:180\nmsgid \"\"\n\"It looks like we are either missing the Article CSS class, or it is \"\n\"configured incorrectly. Editus will not function correctly without this CSS \"\n\"class.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:181\nmsgid \"Update Settings\"\nmsgstr \"\"\n\n#: public/includes/assets.php:182\nmsgid \"one more letter\"\nmsgstr \"\"\n\n#: public/includes/assets.php:183\nmsgid \"You are currently editing a backup copy of this post.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:185\nmsgid \"add categories...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:186\nmsgid \"add tags...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:187\nmsgid \"add taxonomy terms...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:188\nmsgid \"Edit Shortcode\"\nmsgstr \"\"\n\n#: public/includes/components.php:19 public/includes/editor-modules.php:352\nmsgid \"Quote\"\nmsgstr \"\"\n\n#: public/includes/components.php:23 public/includes/editor-modules.php:350\n#: public/includes/editor-modules.php:1103\n#: public/includes/editor-modules.php:1154\n#: public/includes/editor-modules.php:1218\nmsgid \"Image\"\nmsgstr \"\"\n\n#: public/includes/components.php:27\n#: public/includes/editor-modules--gallery.php:74\n#: public/includes/editor-modules.php:355\nmsgid \"Parallax\"\nmsgstr \"\"\n\n#: public/includes/components.php:31 public/includes/editor-modules.php:356\nmsgid \"Audio\"\nmsgstr \"\"\n\n#: public/includes/components.php:35 public/includes/editor-modules.php:353\n#: public/includes/editor-modules.php:1080\nmsgid \"Content\"\nmsgstr \"\"\n\n#: public/includes/components.php:39 public/includes/editor-modules.php:351\nmsgid \"Character\"\nmsgstr \"\"\n\n#: public/includes/components.php:43 public/includes/editor-modules.php:361\nmsgid \"Collection\"\nmsgstr \"\"\n\n#: public/includes/components.php:47 public/includes/editor-modules.php:360\nmsgid \"Document\"\nmsgstr \"\"\n\n#: public/includes/components.php:51 public/includes/editor-modules.php:362\nmsgid \"Gallery\"\nmsgstr \"\"\n\n#: public/includes/components.php:55 public/includes/editor-modules.php:354\nmsgid \"Chapter\"\nmsgstr \"\"\n\n#: public/includes/components.php:59 public/includes/editor-modules.php:358\nmsgid \"Map\"\nmsgstr \"Mapa\"\n\n#: public/includes/components.php:63 public/includes/editor-modules.php:359\nmsgid \"Timeline\"\nmsgstr \"\"\n\n#: public/includes/components.php:67 public/includes/editor-modules.php:357\nmsgid \"Video\"\nmsgstr \"\"\n\n#: public/includes/components.php:71 public/includes/components.php:91\n#: public/includes/editor-modules.php:371\n#: public/includes/editor-modules.php:373\nmsgid \"WordPress Image\"\nmsgstr \"\"\n\n#: public/includes/components.php:75\nmsgid \"WordPress Image Block\"\nmsgstr \"\"\n\n#: public/includes/components.php:79 public/includes/editor-modules.php:375\nmsgid \"WordPress Quote\"\nmsgstr \"\"\n\n#: public/includes/components.php:83 public/includes/editor-modules.php:364\nmsgid \"Gallery Pop\"\nmsgstr \"\"\n\n#: public/includes/components.php:87\nmsgid \"Events\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:19\nmsgid \"Create gallery\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:27\nmsgid \"Manage Images\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:31\nmsgid \"Rearrange or edit the images in this gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:47\nmsgid \"Create a Gallery\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:51\nmsgid \"Select images to create a gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:52\nmsgid \"Select Images\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:56\nmsgid \"Create Gallery\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:67\nmsgid \"Gallery Type\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:68\nmsgid \"Select the type of gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:70\nmsgid \"Grid\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:71\nmsgid \"Thumbnail\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:73\nmsgid \"Photoset\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:84\nmsgid \"Grid Item Width\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:85\nmsgid \"\"\n\"Adjust the width of the individual grid items, only if using Grid gallery \"\n\"style. Default is 400.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:95\nmsgid \"Gallery Transition\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:96\nmsgid \"\"\n\"Adjust the transition effect for the Thumbnail gallery. Default is slide.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:98\nmsgid \"Fade\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:99\nmsgid \"Slide\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:100\nmsgid \"Dissolve\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:105\nmsgid \"Gallery Transition Speed\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:106\nmsgid \"\"\n\"Activate slideshow by setting a speed for the transition.5000 = 5 seconds.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:112\nmsgid \"Hide Gallery Thumbnails\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:121\nmsgid \"Gallery Layout\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:122\nmsgid \"\"\n\"Let's say you have 4 images in this gallery. If you enter 121 you will have \"\n\"one image on the top row, two images on the second row, and one image on the \"\n\"third row.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:137\nmsgid \"Main Gallery Height\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:138\n#, php-format\nmsgid \"\"\n\"Adjust the overall height of the gallery. Acceptable values include 500px or \"\n\"50% etc.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:148\nmsgid \"Main Gallery Width\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:149\n#, php-format\nmsgid \"\"\n\"Adjust the overall width of the gallery. Acceptable values include 500px or \"\n\"50% etc.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:153\nmsgid \"Gallery Caption\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:154\nmsgid \"Add an optional caption for the gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:60 public/includes/editor-modules.php:437\nmsgid \"Table\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:137\n#: public/includes/underscore-templates.php:23\n#: public/includes/underscore-templates.php:41\nmsgid \"Edit Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:140\n#: public/includes/editor-modules.php:164\n#: public/includes/editor-modules.php:457\nmsgid \"Post Settings\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:145\nmsgid \"All Posts\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:148\n#: public/includes/editor-modules.php:1323\nmsgid \"Revisions\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:152\nmsgid \"Add Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:163\n#: public/includes/editor-modules.php:456\n#: public/includes/underscore-templates.php:25\n#: public/includes/underscore-templates.php:43\nmsgid \"Delete Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:167\n#: public/includes/editor-modules.php:459\nmsgid \"Save Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:170\n#: public/includes/editor-modules.php:462\nmsgid \"Publish Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:170\nmsgid \"Submit For Review\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:249\n#: public/includes/editor-modules.php:342\nmsgid \"Bold\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:250\n#: public/includes/editor-modules.php:343\nmsgid \"Underline\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:251\n#: public/includes/editor-modules.php:344\nmsgid \"Italicize\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:252\n#: public/includes/editor-modules.php:345\nmsgid \"Strikethrough\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:255\n#: public/includes/editor-modules.php:384\n#: public/includes/editor-modules.php:431\nmsgid \"H2 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:256\n#: public/includes/editor-modules.php:385\n#: public/includes/editor-modules.php:432\nmsgid \"H3 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:262\n#: public/includes/editor-modules.php:391\nmsgid \"H4 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:263\n#: public/includes/editor-modules.php:392\nmsgid \"H5 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:264\n#: public/includes/editor-modules.php:393\nmsgid \"H6 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:268\n#: public/includes/editor-modules.php:397\nmsgid \"Set Color for Selected Text\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:269\n#: public/includes/editor-modules.php:398\nmsgid \"Choose Color\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:273\n#: public/includes/editor-modules.php:402\n#: public/includes/editor-modules.php:434\nmsgid \"Ordered List\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:274\n#: public/includes/editor-modules.php:403\n#: public/includes/editor-modules.php:435\nmsgid \"Unordered List\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:278\n#: public/includes/editor-modules.php:407\nmsgid \"Anchor Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:280\n#: public/includes/editor-modules.php:409\nmsgid \"http://url.com\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:281\n#: public/includes/editor-modules.php:410\nmsgid \"Create Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:283\n#: public/includes/editor-modules.php:412\nmsgid \"Open in a New Tab\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:347\nmsgid \"Insert Component\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:367\nmsgid \"Event\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:376\nmsgid \"WordPress Video\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:419\n#: public/includes/editor-modules.php:440\nmsgid \"Insert HTML or Code\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:421\n#: public/includes/editor-modules.php:424\nmsgid \"Enter HTML to insert\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:425\nmsgid \"You can also use Shortcodes\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:426\nmsgid \"\"\n\"You can also enter a URL to embed, such as Youtube, Vimeo and Twitter URLs.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:440\nmsgid \"Insert\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:446\nmsgid \"Text Left Align\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:447\nmsgid \"Text Center Align\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:448\nmsgid \"Text Right Align\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:492\n#: public/includes/editor-modules.php:890\n#: public/includes/editor-modules.php:908\n#: public/includes/editor-modules.php:927\nmsgid \"Move\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:494\n#: public/includes/editor-modules.php:896\n#: public/includes/editor-modules.php:910\n#: public/includes/editor-modules.php:929\nmsgid \"Clone\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:495\n#: public/includes/editor-modules.php:897\n#: public/includes/editor-modules.php:911\n#: public/includes/editor-modules.php:930\nmsgid \"Delete\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:517\nmsgid \"Replace Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:518\nmsgid \"Delete Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:519\nmsgid \"save\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:593\nmsgid \"Featured Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:593\nmsgid \"Change the featured image for this post.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:597\nmsgid \"Change Featured Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:598\nmsgid \"Delete Featured Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:614\nmsgid \"Change the status of the post to draft or publish.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:616\nmsgid \"Draft\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:618\nmsgid \"Pending\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:620\nmsgid \"Publish\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:630\nmsgid \"Post URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:630\nmsgid \"Change the URL (slug) of this post.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:640\nmsgid \"Categories\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:640\nmsgid \"Type a category name and press enter.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:645\nmsgid \"Tags\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:645\nmsgid \"Type a tag name and press enter.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:653\nmsgid \"Custom Taxonomy\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:653\nmsgid \"Choose custom taxonomy.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:670\nmsgid \"Excerpt\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:670\nmsgid \"Edit excerpt\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:679\nmsgid \"Post Date\"\nmsgstr \"Fecha del Artículo\"\n\n#: public/includes/editor-modules.php:681\nmsgid \"Set to Now\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:762\nmsgid \"New <span>post</span> title\"\nmsgstr \"Escribe el nombre de tu <span> entrada/proyecto </ span>\"\n\n#: public/includes/editor-modules.php:762\nmsgid \"Specify title for new post, then save to edit.\"\nmsgstr \"\"\n\"Especificar el título de mensaje nuevo, a continuación, guardar editar.\"\n\n#: public/includes/editor-modules.php:763\nmsgid \"Type Your Title Here\"\nmsgstr \"Aquí titulo de tu entrada/proyecto\"\n\n#: public/includes/editor-modules.php:800\nmsgid \"Create\"\nmsgstr \"Crear\"\n\n#: public/includes/editor-modules.php:839\nmsgid \"results found\"\nmsgstr \"resultados encontrados\"\n\n#: public/includes/editor-modules.php:952\nmsgid \"Save Locations\"\nmsgstr \"guardar ubicaciones\"\n\n#: public/includes/editor-modules.php:970\nmsgid \"Save this post and refesh the page to see these changes.\"\nmsgstr \"Guarde este post y refesh la página para ver los cambios.\"\n\n#: public/includes/editor-modules.php:1109\n#: public/includes/editor-modules.php:1224\n#: public/includes/editor-modules.php:1289\nmsgid \"Image URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1110\n#: public/includes/editor-modules.php:1225\n#: public/includes/editor-modules.php:1290\nmsgid \"\"\n\"URL for the image. Click <em>Select Media</em> to open the WordPress Media \"\n\"Library.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1117\n#: public/includes/editor-modules.php:1232\nmsgid \"Center\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1121\n#: public/includes/editor-modules.php:1236\nmsgid \"Left\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1125\n#: public/includes/editor-modules.php:1240\nmsgid \"Right\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1129\n#: public/includes/editor-modules.php:1244\nmsgid \"Alignment\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1136\nmsgid \"Image Width\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1137\nmsgid \"\"\n\"Width of the image. You can enter the size in pixels or percentage such as \"\n\"<code>40%</code> or <code>500px</code>.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1142\nmsgid \"Image Height\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1143\nmsgid \"\"\n\"Used only for the Panorama mode. Can be set using pixel values such as \"\n\"<code>500px</code>. If unspecified, the original height would be used. \"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1150\nmsgid \"None\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1158\nmsgid \"URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1162\nmsgid \"Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1163\nmsgid \"Click leads to:\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1169\nmsgid \"URL Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1170\nmsgid \"URL link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1175\n#: public/includes/editor-modules.php:1250\nmsgid \"Image ALT\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1176\n#: public/includes/editor-modules.php:1251\nmsgid \"ALT tag used for the image. Primarily used for SEO purposes.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1182\n#: public/includes/editor-modules.php:1256\nmsgid \"Caption\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1183\n#: public/includes/editor-modules.php:1257\nmsgid \"Optional caption for the image.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1188\nmsgid \"An image.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1262\nmsgid \"Link URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1263\nmsgid \"Optional URL to link.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1268\nmsgid \"A WP Image Block.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1283\nmsgid \"Cover\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1294\nmsgid \"A WP Cover Block.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1323\nmsgid \"Use the slider to view the revision live on the page.\"\nmsgstr \"\"\n\"Utilice el control deslizante para ver la revisión en vivo en la página.\"\n\n#: public/includes/editor-modules.php:1330\nmsgid \"Select\"\nmsgstr \"\"\n\n#: public/includes/helpers.php:449\nmsgid \"No posts to show\"\nmsgstr \"No hay publicaciones para mostrar\"\n\n#: public/includes/helpers.php:455\nmsgid \"No revisions found\"\nmsgstr \"No hay revisiones encontrados\"\n\n#: public/includes/lasso.php:292\nmsgid \"Post being edited by \"\nmsgstr \"\"\n\n#: public/includes/tour.php:67\nmsgid \"Don't show this again\"\nmsgstr \"No mostrar de nuevo.\"\n\n#: public/includes/tour.php:71\nmsgid \"Okay, got it!\"\nmsgstr \"OK. Entendido.\"\n\n#: public/includes/tour.php:96\nmsgid \"\"\n\"Access posts by clicking the list icon. Create a new post by clicking the \"\n\"new post icon.\"\nmsgstr \"\"\n\"Puede crear una nueva entrada/proyecto clickando sobre el icono simbolizado \"\n\"con una hoja con un plus. Este botón lo puede encontrar en la parte inferior \"\n\"de su pantalla.\"\n\n#: public/includes/tour.php:99\nmsgid \"\"\n\"While on a single post, edit by clicking the Pen icon. Access post settings \"\n\"with the settings icon. Press escape to exit any modal.\"\nmsgstr \"\"\n\"Clickando sobre el botón de la pluma, puede empezar a escribir o editar su \"\n\"entrada // proyecto.\"\n\n#: public/includes/tour.php:102\nmsgid \"\"\n\"Highlight a piece of text, and click on a formatting option to style it. \"\n\"Click the Disk icon or CMD-S to save. Click the orange \\\"X\\\" button to exit \"\n\"the editor.\"\nmsgstr \"\"\n\"Esta será su barra de edición de textos, con ella podrá editar el formato de \"\n\"sus textos mientras escribe ( texto en negrita, subrayado, italic, tachado, \"\n\"añadir enlaces, codigo y mucho más...\"\n\n#: public/includes/tour.php:105\nmsgid \"\"\n\"Story components can be added by clicking the plus icon, and dragging any \"\n\"component from the component tray into the story.\"\nmsgstr \"\"\n\"Clickando sobre el botón más, podra arrastrar estos componentes a sus \"\n\"publicaciones (imágenes, audios, videos, galerias de imagenes, mapa con \"\n\"localización, citas de autor....)\"\n\n#~ msgid \"Grump Wizards Make Toxic Brew\"\n#~ msgstr \"Aquí titulo de tu entrada/proyecto\"\n"
  },
  {
    "path": "languages/lasso-ko_KR.po",
    "content": "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Editus\\n\"\n\"POT-Creation-Date: 2022-08-02 15:43-0400\\n\"\n\"PO-Revision-Date: 2022-08-02 15:43-0400\\n\"\n\"Last-Translator: \\n\"\n\"Language-Team: \\n\"\n\"Language: ko_KR\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1);\\n\"\n\"X-Generator: Poedit 3.1.1\\n\"\n\"X-Poedit-Basepath: ..\\n\"\n\"X-Poedit-KeywordsList: __;_e;esc_attr_e\\n\"\n\"X-Poedit-SourceCharset: UTF-8\\n\"\n\"X-Poedit-SearchPath-0: .\\n\"\n\"X-Poedit-SearchPathExcluded-0: node_modules\\n\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:177\n#, php-format\nmsgid \"\"\n\"There is a new version of %1$s available. <a target=\\\"_blank\\\" class=\"\n\"\\\"thickbox\\\" href=\\\"%2$s\\\">View version %3$s details</a>.\"\nmsgstr \"\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:184\n#, php-format\nmsgid \"\"\n\"There is a new version of %1$s available. <a target=\\\"_blank\\\" class=\"\n\"\\\"thickbox\\\" href=\\\"%2$s\\\">View version %3$s details</a> or <a href=\\\"%4$s\"\n\"\\\">update now</a>.\"\nmsgstr \"\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:324\nmsgid \"You do not have permission to install plugin updates\"\nmsgstr \"\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:324\nmsgid \"Error\"\nmsgstr \"에러\"\n\n#: admin/includes/class-tgm-plugin-activation.php:333\n#: admin/includes/menus/welcome.php:227\nmsgid \"Install Required Plugins\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:334\n#: admin/includes/menus/welcome.php:228\nmsgid \"Install Plugins\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:335\n#: admin/includes/menus/welcome.php:229\n#, php-format\nmsgid \"Installing Plugin: %s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:336\n#: admin/includes/menus/welcome.php:230\nmsgid \"Something went wrong with the plugin API.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:397\n#: admin/includes/menus/welcome.php:241\nmsgid \"Return to Required Plugins Installer\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:398\nmsgid \"Return to the dashboard\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:399\n#: admin/includes/class-tgm-plugin-activation.php:3029\n#: admin/includes/menus/welcome.php:242\nmsgid \"Plugin activated successfully.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:400\nmsgid \"The following plugin was activated successfully:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:401\n#, php-format\nmsgid \"No action taken. Plugin %1$s was already active.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:402\n#, php-format\nmsgid \"\"\n\"Plugin not activated. A higher version of %s is needed for this theme. \"\n\"Please update the plugin.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:403\n#, php-format\nmsgid \"All plugins installed and activated successfully. %1$s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:404\nmsgid \"Dismiss this notice\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:405\nmsgid \"Please contact the administrator of this site for help.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2167\nmsgid \"Required\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2170\nmsgid \"Recommended\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2186\nmsgid \"WordPress Repository\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2189\nmsgid \"External Source\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2192\nmsgid \"Pre-Packaged\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2209\nmsgid \"Not Installed\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2213\nmsgid \"Installed But Not Activated\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2215\nmsgid \"Active\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2221\nmsgid \"Required Update not Available\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2224\nmsgid \"Requires Update\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2227\nmsgid \"Update recommended\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2379\nmsgid \"Installed version:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2387\nmsgid \"Minimum required version:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2399\nmsgid \"Available version:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2422\n#, php-format\nmsgid \"\"\n\"No plugins to install, update or activate. <a href=\\\"%1$s\\\">Return to the \"\n\"Dashboard</a>\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2436\nmsgid \"Plugin\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2437\nmsgid \"Source\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2438\nmsgid \"Type\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2442\n#: admin/includes/menus/welcome.php:118\nmsgid \"Version\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2443\n#: admin/includes/menus/welcome.php:49 public/includes/editor-modules.php:614\nmsgid \"Status\"\nmsgstr \"상태\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2603\nmsgid \"Install\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2609\nmsgid \"Update\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2612\nmsgid \"Activate\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2643\nmsgid \"No plugins were selected to be installed. No action taken.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2645\nmsgid \"No plugins were selected to be updated. No action taken.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2681\nmsgid \"No plugins are available to be installed at this time.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2683\nmsgid \"No plugins are available to be updated at this time.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3028\nmsgid \"Plugin activation failed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3362\n#, php-format\nmsgid \"Updating Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3364\n#, php-format\nmsgid \"An error occurred while installing %1$s: <strong>%2$s</strong>.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3365\n#, php-format\nmsgid \"The installation of %1$s failed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3369\nmsgid \"\"\n\"The installation and activation process is starting. This process may take a \"\n\"while on some hosts, so please be patient.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3370\n#, php-format\nmsgid \"%1$s installed and activated successfully.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3371\nmsgid \"All installations and activations have been completed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3372\n#, php-format\nmsgid \"Installing and Activating Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3375\nmsgid \"\"\n\"The installation process is starting. This process may take a while on some \"\n\"hosts, so please be patient.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3377\nmsgid \"All installations have been completed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3378\n#, php-format\nmsgid \"Installing Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"\"\n\n#: admin/includes/load_admin.php:151\nmsgid \"Dismiss this notice.\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:30\nmsgid \"Aesopinteractive LLC\"\nmsgstr \"Aesopinteractive LLC\"\n\n#: admin/includes/menus/license.php:38 admin/includes/menus/license.php:57\nmsgid \"License Key\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:38\nmsgid \"License\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:47\nmsgid \"Editus License\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:48\nmsgid \"\"\n\"Input the license key you recieved with your purchase to ensure your version \"\n\"of Editus stays updated.\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:66 admin/includes/menus/license.php:75\nmsgid \"Activate License\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:70\nmsgid \"active\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:72\nmsgid \"Deactivate License\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:26 public/includes/editor-modules.php:493\n#: public/includes/editor-modules.php:892\n#: public/includes/editor-modules.php:894\n#: public/includes/editor-modules.php:909\n#: public/includes/editor-modules.php:928\nmsgid \"Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:169\nmsgid \"Editus Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:177\nmsgid \"Enable for:\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:181\nmsgid \"Enable Editus for the following post types.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:203\nmsgid \"Internal Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:206\nmsgid \"Article Class\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:207\nmsgid \"\"\n\"Provide the CSS class (including the preceding dot) of container that holds \"\n\"the post. This should be the first parent container class that holds \"\n\"the_content.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:212\nmsgid \"Featured Image Class\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:213\nmsgid \"\"\n\"Provide the CSS class that uses a featured image as a background image. This \"\n\"currently only supports themes that have the featured image set as \"\n\"background image.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:218\nmsgid \"Article Title Class\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:219\nmsgid \"\"\n\"Provide the CSS class for the post title. This will enable you to update the \"\n\"title of the post by clicking and typing.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:224\nmsgid \"Ignored Items to Save\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:225\nmsgid \"\"\n\"If your post container holds additional markup, list the css class names \"\n\"(comma separated, including the dot) of those items. When you enter the \"\n\"editor, Editus will remove (NOT delete) these items so that it does not save \"\n\"them as HTML.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:230\nmsgid \"Read Only Items\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:231\nmsgid \"\"\n\"If your post has items that should not be editable, list the css class names \"\n\"(comma separated, including the dot) of those items.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:237\nmsgid \"Show Ignored Items\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:238\nmsgid \"\"\n\"By default the ignored items are hidden. Check this to show ignored items \"\n\"while keeping them uneditable.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:242\nmsgid \"Editor UI\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:246\nmsgid \"Use the Old Toolbar\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:247\nmsgid \"\"\n\"Use this option to disable the new color options and use the pre-1.0 toolbar.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:251\nmsgid \"Editor Bar Color Top\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:252\nmsgid \"Editor Bar Color Bottom\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:253\nmsgid \"Dialog Color\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:254\nmsgid \"Icon/Text Color\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:256\nmsgid \"Default Colors\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:261\nmsgid \"Enable H2 and H3 Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:262\nmsgid \"Show the buttons to set H2 and H3 settings.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:267\nmsgid \"Enable H4/H5/H6 Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:268\nmsgid \"Show the buttons to set H4/H5/H6 settings.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:274\nmsgid \"Enable OL/UL Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:275\nmsgid \"\"\n\"Show the buttons to create Ordered and Unordered Lists from text selection.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:280\nmsgid \"Enable Text Color Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:281\nmsgid \"Show the buttons to set text colors.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:286\nmsgid \"Enable Text Align Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:287\nmsgid \"Show the buttons to set text alignment.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:293\nmsgid \"Make links editable under the Editing Mode\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:294\nmsgid \"\"\n\"Make links editable under the Editing Mode. Turning this on will make the \"\n\"links non-clickable while editing.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:298\nmsgid \"Insert Component UI\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:299\nmsgid \"UI mechanism to insert components\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:301\nmsgid \"Drag and Drop\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:304\nmsgid \"Click\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:307\nmsgid \"Auto Button on Empty Paragraph. medium.com-like UI.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:313\nmsgid \"Popup When Text is Selected\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:314\nmsgid \"\"\n\"Instead of using the bottom toolbar to format texts, use a popup box to \"\n\"format texts.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:320\nmsgid \"Component\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:324\nmsgid \"Additional Component: Table\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:325\nmsgid \"Allow user to add and edit tables.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:331\nmsgid \"Additional Component: Paragraph\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:332\nmsgid \"Plain HTML Paragraph.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:363\n#, fuzzy\n#| msgid \"Replace Image\"\nmsgid \"Use Simple Image\"\nmsgstr \"이미지변경\"\n\n#: admin/includes/menus/settings.php:364\nmsgid \"Use Simple Image Component without Extra Options.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:371\nmsgid \"Use WP Image Block\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:372\nmsgid \"\"\n\"Use WP Image Block as the image component. Gutenberg Block Editor needs to \"\n\"be enabled.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:379\nmsgid \"Post Settings UI\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:383\nmsgid \"Disable Post Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:384\nmsgid \"\"\n\"Check this to disable users from being able to edit post settings from the \"\n\"front-end.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:389\nmsgid \"Allow Changing Post Date\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:390\nmsgid \"\"\n\"Add the date selector to change the post's date to the Post Setting dialog\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:395\nmsgid \"Allow Editing Excerpt\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:396\nmsgid \"Allow the post's excerpt to be edited in the Post Setting dialog\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:401\nmsgid \"Allow Adding New Category\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:402\nmsgid \"\"\n\"Add the user to create new, previously non-existing categories for posts.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:407\nmsgid \"Do Not Allow \\\"Pending\\\" Status\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:408\nmsgid \"Remove the Option to Set the Status to Pending.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:413\nmsgid \"Remove POST URL Option\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:414\nmsgid \"Remove the Option to Set the URL for the Post.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:419\nmsgid \"Disable Post Adding\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:420\nmsgid \"\"\n\"Check this box to disable users from being able to add new posts from the \"\n\"front-end.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:425\nmsgid \"Support Custom Taxonomy\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:426\nmsgid \"Allow editing custom taxonomies.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:432\nmsgid \"Misc\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:436\nmsgid \"Do Not Show Tour Dialog\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:437\nmsgid \"Check this box to disable the tour dialog box for all users.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:441\nmsgid \"Placeholder Text for New Post\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:442\nmsgid \"Placeholder text to be displayed when a new post is created.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:443 includes/process/new_object.php:38\n#: public/includes/assets.php:248\nmsgid \"Once upon a time...\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:448\nmsgid \"Do Not Allow Shortcode Editing\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:449\nmsgid \"Check this box to disable frontend editing of shortcodes.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:453\nmsgid \"\\\"Bold\\\" Tag\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:454\nmsgid \"Choose the HTML tag used for the \\\"Bold\\\" style.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:459\nmsgid \"\\\"Italic\\\" Tag\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:460\nmsgid \"Choose the HTML tag used for the \\\"Italic\\\" style.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:466\nmsgid \"Auto Prefix HTTP to links\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:467\nmsgid \"\"\n\"When user adds a hyperlink, automatically add http:// if the user does not \"\n\"specify it explicitly.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:471\nmsgid \"Advanced Options\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:472\nmsgid \"\"\n\"Suggested not to turn these options on without consulting the developer.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:477\nmsgid \"Disable Aesop Component Conversion\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:478\nmsgid \"\"\n\"Check this box to disable the conversion process used on Aesop Story Engine \"\n\"components.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:483\nmsgid \"Enable Auto Save\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:484\nmsgid \"Check this box to enable auto save.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:489\nmsgid \"Disable Post Saving\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:490\nmsgid \"\"\n\"By default the editor will update the database with the post or page it is \"\n\"being used on. Check this box to disable this. If you check this box, it is \"\n\"assumed that you will be using the provided filters to save your own content.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:496\nmsgid \"Disable Post Editing\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:497\nmsgid \"\"\n\"You may use this option if you only want to edit custom fields. Refer <a \"\n\"href=\\\"https://edituswp.com/editing-and-updating-custom-fields-from-frontend/\"\n\"\\\">here</a> for more information. The custom fields you specify will be \"\n\"still editable under the editing mode.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:503\nmsgid \"Don't Use REST API to Save\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:504\nmsgid \"\"\n\"By default the editor will use REST API to save posts. Check this box to use \"\n\"custom AJAX calls instead.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:510\n#, fuzzy\n#| msgid \"You can also use Shortcodes\"\nmsgid \"Don't Wrap Shortcodes\"\nmsgstr \"또는 워드프레스 숏코드\"\n\n#: admin/includes/menus/settings.php:511\nmsgid \"\"\n\"By default Editus wraps shortcodes so they can be preserved. Disable this \"\n\"behavior.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:521\nmsgid \"Save Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:48\nmsgid \"Editus\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:49\nmsgid \"Welcome\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:71\nmsgid \"\"\n\"We will check the current theme on every site in your network and give you a \"\n\"quick status feedback here. You can see the status by visiting the Editus \"\n\"menu on each site.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:90\nmsgid \"You're Ready to Rock!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:92\nmsgid \"Your theme is automatically supported. No additional setup is needed.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:94\nmsgid \"\"\n\"Editus will place a small menu on the bottom of your site. While on a single \"\n\"post or page, click the \\\"pen\\\" icon to go into edit mode. Press escape to \"\n\"get out of edit mode.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:117\nmsgid \"Welcome to Editus\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:123\nmsgid \"Help\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:124\nmsgid \"Twitter\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:125\nmsgid \"Facebook\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:158\nmsgid \"Article CSS Class Needed!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"Before using Editus,\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"enter and save\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"\"\n\"the CSS class of the container that holds your post and page content. You \"\n\"can <a href=\\\"https://dl.dropboxusercontent.com/u/5594632/lasso-media/doc-\"\n\"movies/using-inspector-lasso.gif\\\" target=\\\"_blank\\\">use a tool like \"\n\"inspector</a> in Chrome or Firefox to find this CSS class, or \"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"email us.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"with a link to a public URL with the theme and we'll find it for you.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:166\nmsgid \"\"\n\"Just a heads up that the WP REST API isn't activated. This is required to \"\n\"list the posts and pages on the front-end.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:173\nmsgid \"Just a heads up that \"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:174 admin/includes/menus/welcome.php:211\nmsgid \"Aesop Story Engine\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:174\nmsgid \"\"\n\"isn't activated. It's not required to use Editus, but you won't get the cool \"\n\"drag and drop components without it activated. It's free!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:180\nmsgid \"WP Side Comments Compatibility Warning!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:181\nmsgid \"\"\n\"Since Editus saves the HTML of a post, this may cause undesired issues. \"\n\"We're working to resolve incompatibilities faster than a jack rabbit in a \"\n\"hot greasy griddle in the middle of August.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:187\nmsgid \"License Key Not Activated\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:188\nmsgid \"\"\n\"Just a heads up, your license key isn't activated. Enter your license key \"\n\"into the License tab on the left in order to receive plugin update \"\n\"notifications.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:192\nmsgid \"License Key Invalid\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \"The license key that you entered is \"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \"invalid\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \". It may have been entered incorreclty, or may have expired.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:243\n#, php-format\nmsgid \"All plugins installed and activated successfully. %s\"\nmsgstr \"\"\n\n#: includes/process/gallery.php:40\nmsgid \"Save and refresh to view gallery.\"\nmsgstr \"\"\n\n#: includes/process/gallery.php:199\nmsgid \"Delete From Gallery\"\nmsgstr \"\"\n\n#: includes/process/gallery.php:200\nmsgid \"Edit Image Caption\"\nmsgstr \"\"\n\n#: internal-api/auth.php:67\nmsgid \"Unauthorized action\"\nmsgstr \"\"\n\n#: internal-api/auth.php:71\nmsgid \"\"\n\"All callback classes used for processing the Editus Internal API must \"\n\"implement the lasso\\\\internal_api\\\\api_action interface.\"\nmsgstr \"\"\n\n#: internal-api/auth.php:76\nmsgid \"Nonce invalid\"\nmsgstr \"\"\n\n#: internal-api/route.php:30\nmsgid \"Editus API Error.\"\nmsgstr \"\"\n\n#: internal-api/route.php:66\nmsgid \"Nonce not set.\"\nmsgstr \"\"\n\n#: lasso.php:130\n#, fuzzy\n#| msgid \"Insert\"\nmsgid \"Insert Column\"\nmsgstr \"삽입\"\n\n#: lasso.php:131\n#, fuzzy\n#| msgid \"Insert\"\nmsgid \"Insert Row\"\nmsgstr \"삽입\"\n\n#: lasso.php:132\n#, fuzzy\n#| msgid \"Delete Post\"\nmsgid \"Delete Column\"\nmsgstr \"글 삭제\"\n\n#: lasso.php:133\n#, fuzzy\n#| msgid \"Delete Post\"\nmsgid \"Delete Row\"\nmsgstr \"글 삭제\"\n\n#: lasso.php:134\n#, fuzzy\n#| msgid \"Delete Image\"\nmsgid \"Delete Table\"\nmsgstr \"이미지 삭제\"\n\n#: lasso.php:149 lasso.php:159\nmsgid \"HTML Table\"\nmsgstr \"\"\n\n#: lasso.php:192 lasso.php:220\nmsgid \"HTML Paragraph\"\nmsgstr \"\"\n\n#: public/includes/assets.php:146 public/includes/editor-modules.php:713\n#: public/includes/option-engine.php:132\nmsgid \"Save\"\nmsgstr \"저장\"\n\n#: public/includes/assets.php:147\nmsgid \"Please Select Text First.\"\nmsgstr \"텍스트를 먼저 선택하십시요.\"\n\n#: public/includes/assets.php:148 public/includes/editor-modules.php:439\n#: public/includes/editor-modules.php:706\n#: public/includes/editor-modules.php:788\n#: public/includes/editor-modules.php:1329\nmsgid \"Cancel\"\nmsgstr \"취소\"\n\n#: public/includes/assets.php:149\nmsgid \"Exit Editor\"\nmsgstr \"에디터 종료\"\n\n#: public/includes/assets.php:150\nmsgid \"Saving...\"\nmsgstr \"저장중\"\n\n#: public/includes/assets.php:151\nmsgid \"Saved!\"\nmsgstr \"저장완료\"\n\n#: public/includes/assets.php:152\nmsgid \"Adding...\"\nmsgstr \"추가중\"\n\n#: public/includes/assets.php:153\nmsgid \"Added!\"\nmsgstr \"추가완료\"\n\n#: public/includes/assets.php:154\nmsgid \"Loading...\"\nmsgstr \"로딩\"\n\n#: public/includes/assets.php:155\nmsgid \"Load More\"\nmsgstr \"더보기\"\n\n#: public/includes/assets.php:156 public/includes/helpers.php:457\nmsgid \"Close\"\nmsgstr \"닫기\"\n\n#: public/includes/assets.php:157\nmsgid \"No more posts found\"\nmsgstr \"더 글이 없습니다.\"\n\n#: public/includes/assets.php:158\nmsgid \"Fetching failed.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:159\nmsgid \"Gallery Created!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:160\nmsgid \"Gallery Updated!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:161\nmsgid \"Just write...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:162\nmsgid \"Choose an image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:163\nmsgid \"Update Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:164\nmsgid \"Insert Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:165\nmsgid \"Select Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:166\nmsgid \"Remove featured image?\"\nmsgstr \"대표 이미지를 뺄까요?\"\n\n#: public/includes/assets.php:167\nmsgid \"Update Selected Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:168\nmsgid \"Choose images\"\nmsgstr \"\"\n\n#: public/includes/assets.php:169\nmsgid \"Edit Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:170\n#: public/includes/editor-modules--gallery.php:28\nmsgid \"Add Images\"\nmsgstr \"\"\n\n#: public/includes/assets.php:171\nmsgid \"Add New Gallery\"\nmsgstr \"\"\n\n#: public/includes/assets.php:172\nmsgid \"Select Editus Gallery Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:173\nmsgid \"Use Selected Images\"\nmsgstr \"\"\n\n#: public/includes/assets.php:174\nmsgid \"Publish Post?\"\nmsgstr \"글을 공개할까요?\"\n\n#: public/includes/assets.php:175\nmsgid \"Yes, publish it!\"\nmsgstr \"예\"\n\n#: public/includes/assets.php:176\nmsgid \"Trash Post?\"\nmsgstr \"글을 삭제할까요?\"\n\n#: public/includes/assets.php:177\nmsgid \"Yes, trash it!\"\nmsgstr \"예\"\n\n#: public/includes/assets.php:178\nmsgid \"Oh snap!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:179\nmsgid \"O.K. got it!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:180\nmsgid \"\"\n\"It looks like we are either missing the Article CSS class, or it is \"\n\"configured incorrectly. Editus will not function correctly without this CSS \"\n\"class.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:181\nmsgid \"Update Settings\"\nmsgstr \"\"\n\n#: public/includes/assets.php:182\nmsgid \"one more letter\"\nmsgstr \"\"\n\n#: public/includes/assets.php:183\nmsgid \"You are currently editing a backup copy of this post.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:185\n#, fuzzy\n#| msgid \"Categories\"\nmsgid \"add categories...\"\nmsgstr \"카테고리\"\n\n#: public/includes/assets.php:186\nmsgid \"add tags...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:187\n#, fuzzy\n#| msgid \"Categories\"\nmsgid \"add taxonomy terms...\"\nmsgstr \"카테고리\"\n\n#: public/includes/assets.php:188\n#, fuzzy\n#| msgid \"Edit Post\"\nmsgid \"Edit Shortcode\"\nmsgstr \"글 편집\"\n\n#: public/includes/components.php:19 public/includes/editor-modules.php:352\nmsgid \"Quote\"\nmsgstr \"\"\n\n#: public/includes/components.php:23 public/includes/editor-modules.php:350\n#: public/includes/editor-modules.php:1103\n#: public/includes/editor-modules.php:1154\n#: public/includes/editor-modules.php:1218\nmsgid \"Image\"\nmsgstr \"이미지\"\n\n#: public/includes/components.php:27\n#: public/includes/editor-modules--gallery.php:74\n#: public/includes/editor-modules.php:355\nmsgid \"Parallax\"\nmsgstr \"\"\n\n#: public/includes/components.php:31 public/includes/editor-modules.php:356\nmsgid \"Audio\"\nmsgstr \"\"\n\n#: public/includes/components.php:35 public/includes/editor-modules.php:353\n#: public/includes/editor-modules.php:1080\nmsgid \"Content\"\nmsgstr \"\"\n\n#: public/includes/components.php:39 public/includes/editor-modules.php:351\nmsgid \"Character\"\nmsgstr \"\"\n\n#: public/includes/components.php:43 public/includes/editor-modules.php:361\nmsgid \"Collection\"\nmsgstr \"\"\n\n#: public/includes/components.php:47 public/includes/editor-modules.php:360\nmsgid \"Document\"\nmsgstr \"\"\n\n#: public/includes/components.php:51 public/includes/editor-modules.php:362\nmsgid \"Gallery\"\nmsgstr \"\"\n\n#: public/includes/components.php:55 public/includes/editor-modules.php:354\nmsgid \"Chapter\"\nmsgstr \"\"\n\n#: public/includes/components.php:59 public/includes/editor-modules.php:358\nmsgid \"Map\"\nmsgstr \"지도\"\n\n#: public/includes/components.php:63 public/includes/editor-modules.php:359\nmsgid \"Timeline\"\nmsgstr \"\"\n\n#: public/includes/components.php:67 public/includes/editor-modules.php:357\nmsgid \"Video\"\nmsgstr \"동영상\"\n\n#: public/includes/components.php:71 public/includes/components.php:91\n#: public/includes/editor-modules.php:371\n#: public/includes/editor-modules.php:373\nmsgid \"WordPress Image\"\nmsgstr \"이미지\"\n\n#: public/includes/components.php:75\n#, fuzzy\n#| msgid \"WordPress Image\"\nmsgid \"WordPress Image Block\"\nmsgstr \"이미지\"\n\n#: public/includes/components.php:79 public/includes/editor-modules.php:375\nmsgid \"WordPress Quote\"\nmsgstr \"인용구\"\n\n#: public/includes/components.php:83 public/includes/editor-modules.php:364\nmsgid \"Gallery Pop\"\nmsgstr \"\"\n\n#: public/includes/components.php:87\nmsgid \"Events\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:19\nmsgid \"Create gallery\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:27\nmsgid \"Manage Images\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:31\nmsgid \"Rearrange or edit the images in this gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:47\nmsgid \"Create a Gallery\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:51\nmsgid \"Select images to create a gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:52\nmsgid \"Select Images\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:56\nmsgid \"Create Gallery\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:67\nmsgid \"Gallery Type\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:68\nmsgid \"Select the type of gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:70\nmsgid \"Grid\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:71\nmsgid \"Thumbnail\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:73\nmsgid \"Photoset\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:84\nmsgid \"Grid Item Width\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:85\nmsgid \"\"\n\"Adjust the width of the individual grid items, only if using Grid gallery \"\n\"style. Default is 400.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:95\nmsgid \"Gallery Transition\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:96\nmsgid \"\"\n\"Adjust the transition effect for the Thumbnail gallery. Default is slide.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:98\nmsgid \"Fade\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:99\nmsgid \"Slide\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:100\nmsgid \"Dissolve\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:105\nmsgid \"Gallery Transition Speed\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:106\nmsgid \"\"\n\"Activate slideshow by setting a speed for the transition.5000 = 5 seconds.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:112\nmsgid \"Hide Gallery Thumbnails\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:121\nmsgid \"Gallery Layout\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:122\nmsgid \"\"\n\"Let's say you have 4 images in this gallery. If you enter 121 you will have \"\n\"one image on the top row, two images on the second row, and one image on the \"\n\"third row.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:137\nmsgid \"Main Gallery Height\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:138\n#, php-format\nmsgid \"\"\n\"Adjust the overall height of the gallery. Acceptable values include 500px or \"\n\"50% etc.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:148\nmsgid \"Main Gallery Width\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:149\n#, php-format\nmsgid \"\"\n\"Adjust the overall width of the gallery. Acceptable values include 500px or \"\n\"50% etc.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:153\nmsgid \"Gallery Caption\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:154\nmsgid \"Add an optional caption for the gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:60 public/includes/editor-modules.php:437\nmsgid \"Table\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:137\n#: public/includes/underscore-templates.php:23\n#: public/includes/underscore-templates.php:41\nmsgid \"Edit Post\"\nmsgstr \"글 편집\"\n\n#: public/includes/editor-modules.php:140\n#: public/includes/editor-modules.php:164\n#: public/includes/editor-modules.php:457\nmsgid \"Post Settings\"\nmsgstr \"글 세팅\"\n\n#: public/includes/editor-modules.php:145\nmsgid \"All Posts\"\nmsgstr \"글 목록\"\n\n#: public/includes/editor-modules.php:148\n#: public/includes/editor-modules.php:1323\nmsgid \"Revisions\"\nmsgstr \"리비젼\"\n\n#: public/includes/editor-modules.php:152\nmsgid \"Add Post\"\nmsgstr \"새글\"\n\n#: public/includes/editor-modules.php:163\n#: public/includes/editor-modules.php:456\n#: public/includes/underscore-templates.php:25\n#: public/includes/underscore-templates.php:43\nmsgid \"Delete Post\"\nmsgstr \"글 삭제\"\n\n#: public/includes/editor-modules.php:167\n#: public/includes/editor-modules.php:459\nmsgid \"Save Post\"\nmsgstr \"글저장\"\n\n#: public/includes/editor-modules.php:170\n#: public/includes/editor-modules.php:462\nmsgid \"Publish Post\"\nmsgstr \"글공개\"\n\n#: public/includes/editor-modules.php:170\nmsgid \"Submit For Review\"\nmsgstr \"검토글로 저장\"\n\n#: public/includes/editor-modules.php:249\n#: public/includes/editor-modules.php:342\nmsgid \"Bold\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:250\n#: public/includes/editor-modules.php:343\nmsgid \"Underline\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:251\n#: public/includes/editor-modules.php:344\nmsgid \"Italicize\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:252\n#: public/includes/editor-modules.php:345\nmsgid \"Strikethrough\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:255\n#: public/includes/editor-modules.php:384\n#: public/includes/editor-modules.php:431\nmsgid \"H2 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:256\n#: public/includes/editor-modules.php:385\n#: public/includes/editor-modules.php:432\nmsgid \"H3 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:262\n#: public/includes/editor-modules.php:391\nmsgid \"H4 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:263\n#: public/includes/editor-modules.php:392\nmsgid \"H5 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:264\n#: public/includes/editor-modules.php:393\nmsgid \"H6 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:268\n#: public/includes/editor-modules.php:397\nmsgid \"Set Color for Selected Text\"\nmsgstr \"선택된 텍스트색 설정\"\n\n#: public/includes/editor-modules.php:269\n#: public/includes/editor-modules.php:398\nmsgid \"Choose Color\"\nmsgstr \"색 변경\"\n\n#: public/includes/editor-modules.php:273\n#: public/includes/editor-modules.php:402\n#: public/includes/editor-modules.php:434\nmsgid \"Ordered List\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:274\n#: public/includes/editor-modules.php:403\n#: public/includes/editor-modules.php:435\nmsgid \"Unordered List\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:278\n#: public/includes/editor-modules.php:407\nmsgid \"Anchor Link\"\nmsgstr \"링크\"\n\n#: public/includes/editor-modules.php:280\n#: public/includes/editor-modules.php:409\nmsgid \"http://url.com\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:281\n#: public/includes/editor-modules.php:410\nmsgid \"Create Link\"\nmsgstr \"링크\"\n\n#: public/includes/editor-modules.php:283\n#: public/includes/editor-modules.php:412\nmsgid \"Open in a New Tab\"\nmsgstr \"새 탭에서 열기\"\n\n#: public/includes/editor-modules.php:347\nmsgid \"Insert Component\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:367\nmsgid \"Event\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:376\nmsgid \"WordPress Video\"\nmsgstr \"코드\"\n\n#: public/includes/editor-modules.php:419\n#: public/includes/editor-modules.php:440\nmsgid \"Insert HTML or Code\"\nmsgstr \"코드\"\n\n#: public/includes/editor-modules.php:421\n#: public/includes/editor-modules.php:424\nmsgid \"Enter HTML to insert\"\nmsgstr \"삽입할 HTML코드\"\n\n#: public/includes/editor-modules.php:425\nmsgid \"You can also use Shortcodes\"\nmsgstr \"또는 워드프레스 숏코드\"\n\n#: public/includes/editor-modules.php:426\nmsgid \"\"\n\"You can also enter a URL to embed, such as Youtube, Vimeo and Twitter URLs.\"\nmsgstr \"아니면 삽입할 URL을 입력하세요. 유튜브나 트위터등을 지원합니다.\"\n\n#: public/includes/editor-modules.php:440\nmsgid \"Insert\"\nmsgstr \"삽입\"\n\n#: public/includes/editor-modules.php:446\nmsgid \"Text Left Align\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:447\nmsgid \"Text Center Align\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:448\nmsgid \"Text Right Align\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:492\n#: public/includes/editor-modules.php:890\n#: public/includes/editor-modules.php:908\n#: public/includes/editor-modules.php:927\nmsgid \"Move\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:494\n#: public/includes/editor-modules.php:896\n#: public/includes/editor-modules.php:910\n#: public/includes/editor-modules.php:929\nmsgid \"Clone\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:495\n#: public/includes/editor-modules.php:897\n#: public/includes/editor-modules.php:911\n#: public/includes/editor-modules.php:930\nmsgid \"Delete\"\nmsgstr \"삭제\"\n\n#: public/includes/editor-modules.php:517\nmsgid \"Replace Image\"\nmsgstr \"이미지변경\"\n\n#: public/includes/editor-modules.php:518\nmsgid \"Delete Image\"\nmsgstr \"이미지 삭제\"\n\n#: public/includes/editor-modules.php:519\nmsgid \"save\"\nmsgstr \"저장\"\n\n#: public/includes/editor-modules.php:593\nmsgid \"Featured Image\"\nmsgstr \"대표 이미지\"\n\n#: public/includes/editor-modules.php:593\nmsgid \"Change the featured image for this post.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:597\nmsgid \"Change Featured Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:598\nmsgid \"Delete Featured Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:614\nmsgid \"Change the status of the post to draft or publish.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:616\nmsgid \"Draft\"\nmsgstr \"비공개\"\n\n#: public/includes/editor-modules.php:618\nmsgid \"Pending\"\nmsgstr \"검토\"\n\n#: public/includes/editor-modules.php:620\nmsgid \"Publish\"\nmsgstr \"공개\"\n\n#: public/includes/editor-modules.php:630\nmsgid \"Post URL\"\nmsgstr \"글주소\"\n\n#: public/includes/editor-modules.php:630\nmsgid \"Change the URL (slug) of this post.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:640\nmsgid \"Categories\"\nmsgstr \"카테고리\"\n\n#: public/includes/editor-modules.php:640\nmsgid \"Type a category name and press enter.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:645\nmsgid \"Tags\"\nmsgstr \"태그\"\n\n#: public/includes/editor-modules.php:645\nmsgid \"Type a tag name and press enter.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:653\nmsgid \"Custom Taxonomy\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:653\nmsgid \"Choose custom taxonomy.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:670\nmsgid \"Excerpt\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:670\nmsgid \"Edit excerpt\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:679\nmsgid \"Post Date\"\nmsgstr \"글쓴날짜\"\n\n#: public/includes/editor-modules.php:681\nmsgid \"Set to Now\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:762\nmsgid \"New <span>post</span> title\"\nmsgstr \"새글 제목\"\n\n#: public/includes/editor-modules.php:762\nmsgid \"Specify title for new post, then save to edit.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:763\nmsgid \"Type Your Title Here\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:800\nmsgid \"Create\"\nmsgstr \"만들기\"\n\n#: public/includes/editor-modules.php:839\nmsgid \"results found\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:952\nmsgid \"Save Locations\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:970\nmsgid \"Save this post and refesh the page to see these changes.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1109\n#: public/includes/editor-modules.php:1224\n#: public/includes/editor-modules.php:1289\n#, fuzzy\n#| msgid \"Image\"\nmsgid \"Image URL\"\nmsgstr \"이미지\"\n\n#: public/includes/editor-modules.php:1110\n#: public/includes/editor-modules.php:1225\n#: public/includes/editor-modules.php:1290\nmsgid \"\"\n\"URL for the image. Click <em>Select Media</em> to open the WordPress Media \"\n\"Library.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1117\n#: public/includes/editor-modules.php:1232\nmsgid \"Center\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1121\n#: public/includes/editor-modules.php:1236\nmsgid \"Left\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1125\n#: public/includes/editor-modules.php:1240\nmsgid \"Right\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1129\n#: public/includes/editor-modules.php:1244\nmsgid \"Alignment\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1136\n#, fuzzy\n#| msgid \"Image\"\nmsgid \"Image Width\"\nmsgstr \"이미지\"\n\n#: public/includes/editor-modules.php:1137\nmsgid \"\"\n\"Width of the image. You can enter the size in pixels or percentage such as \"\n\"<code>40%</code> or <code>500px</code>.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1142\nmsgid \"Image Height\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1143\nmsgid \"\"\n\"Used only for the Panorama mode. Can be set using pixel values such as \"\n\"<code>500px</code>. If unspecified, the original height would be used. \"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1150\nmsgid \"None\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1158\nmsgid \"URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1162\nmsgid \"Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1163\nmsgid \"Click leads to:\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1169\nmsgid \"URL Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1170\nmsgid \"URL link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1175\n#: public/includes/editor-modules.php:1250\n#, fuzzy\n#| msgid \"Image\"\nmsgid \"Image ALT\"\nmsgstr \"이미지\"\n\n#: public/includes/editor-modules.php:1176\n#: public/includes/editor-modules.php:1251\nmsgid \"ALT tag used for the image. Primarily used for SEO purposes.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1182\n#: public/includes/editor-modules.php:1256\nmsgid \"Caption\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1183\n#: public/includes/editor-modules.php:1257\nmsgid \"Optional caption for the image.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1188\nmsgid \"An image.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1262\nmsgid \"Link URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1263\nmsgid \"Optional URL to link.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1268\nmsgid \"A WP Image Block.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1283\nmsgid \"Cover\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1294\nmsgid \"A WP Cover Block.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1323\nmsgid \"Use the slider to view the revision live on the page.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1330\nmsgid \"Select\"\nmsgstr \"선택\"\n\n#: public/includes/helpers.php:449\nmsgid \"No posts to show\"\nmsgstr \"\"\n\n#: public/includes/helpers.php:455\nmsgid \"No revisions found\"\nmsgstr \"\"\n\n#: public/includes/lasso.php:292\nmsgid \"Post being edited by \"\nmsgstr \"\"\n\n#: public/includes/tour.php:67\nmsgid \"Don't show this again\"\nmsgstr \"다시보지 않기\"\n\n#: public/includes/tour.php:71\nmsgid \"Okay, got it!\"\nmsgstr \"OK. \"\n\n#: public/includes/tour.php:96\nmsgid \"\"\n\"Access posts by clicking the list icon. Create a new post by clicking the \"\n\"new post icon.\"\nmsgstr \"\"\n\n#: public/includes/tour.php:99\nmsgid \"\"\n\"While on a single post, edit by clicking the Pen icon. Access post settings \"\n\"with the settings icon. Press escape to exit any modal.\"\nmsgstr \"\"\n\n#: public/includes/tour.php:102\nmsgid \"\"\n\"Highlight a piece of text, and click on a formatting option to style it. \"\n\"Click the Disk icon or CMD-S to save. Click the orange \\\"X\\\" button to exit \"\n\"the editor.\"\nmsgstr \"\"\n\n#: public/includes/tour.php:105\nmsgid \"\"\n\"Story components can be added by clicking the plus icon, and dragging any \"\n\"component from the component tray into the story.\"\nmsgstr \"\"\n\n#~ msgid \"Grump Wizards Make Toxic Brew\"\n#~ msgstr \"제목\"\n"
  },
  {
    "path": "languages/lasso.pot",
    "content": "# Copyright (C) 2015 Aesopinteractive LLC\n# This file is distributed under the same license as the Lasso (beta) package.\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Lasso (beta) 0.9.3\\n\"\n\"Report-Msgid-Bugs-To: http://lasso.is\\n\"\n\"POT-Creation-Date: 2022-08-02 15:42-0400\\n\"\n\"PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language-Team: LANGUAGE <LL@li.org>\\n\"\n\"Language: en_US\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1);\\n\"\n\"X-Generator: Poedit 3.1.1\\n\"\n\"X-Poedit-KeywordsList: __;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;\"\n\"_nx_noop:1,2,3c;esc_attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;\"\n\"esc_html_x:1,2c\\n\"\n\"X-Poedit-SourceCharset: UTF-8\\n\"\n\"X-Poedit-Basepath: ..\\n\"\n\"X-Textdomain-Support: yes\\n\"\n\"X-Poedit-SearchPath-0: .\\n\"\n\"X-Poedit-SearchPathExcluded-0: node_modules\\n\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:177\n#, php-format\nmsgid \"\"\n\"There is a new version of %1$s available. <a target=\\\"_blank\\\" class=\\\"thickbox\"\n\"\\\" href=\\\"%2$s\\\">View version %3$s details</a>.\"\nmsgstr \"\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:184\n#, php-format\nmsgid \"\"\n\"There is a new version of %1$s available. <a target=\\\"_blank\\\" class=\\\"thickbox\"\n\"\\\" href=\\\"%2$s\\\">View version %3$s details</a> or <a href=\\\"%4$s\\\">update now</\"\n\"a>.\"\nmsgstr \"\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:324\nmsgid \"You do not have permission to install plugin updates\"\nmsgstr \"\"\n\n#: admin/includes/EDD_SL_Plugin_Updater.php:324\nmsgid \"Error\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:333\n#: admin/includes/menus/welcome.php:227\nmsgid \"Install Required Plugins\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:334\n#: admin/includes/menus/welcome.php:228\nmsgid \"Install Plugins\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:335\n#: admin/includes/menus/welcome.php:229\n#, php-format\nmsgid \"Installing Plugin: %s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:336\n#: admin/includes/menus/welcome.php:230\nmsgid \"Something went wrong with the plugin API.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:338\n#, php-format\nmsgid \"This theme requires the following plugin: %1$s.\"\nmsgid_plural \"This theme requires the following plugins: %1$s.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:343\n#, php-format\nmsgid \"This theme recommends the following plugin: %1$s.\"\nmsgid_plural \"This theme recommends the following plugins: %1$s.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:348\n#, php-format\nmsgid \"\"\n\"Sorry, but you do not have the correct permissions to install the %1$s plugin.\"\nmsgid_plural \"\"\n\"Sorry, but you do not have the correct permissions to install the %1$s plugins.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:353\n#, php-format\nmsgid \"\"\n\"The following plugin needs to be updated to its latest version to ensure \"\n\"maximum compatibility with this theme: %1$s.\"\nmsgid_plural \"\"\n\"The following plugins need to be updated to their latest version to ensure \"\n\"maximum compatibility with this theme: %1$s.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:358\n#, php-format\nmsgid \"There is an update available for: %1$s.\"\nmsgid_plural \"There are updates available for the following plugins: %1$s.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:363\n#, php-format\nmsgid \"\"\n\"Sorry, but you do not have the correct permissions to update the %1$s plugin.\"\nmsgid_plural \"\"\n\"Sorry, but you do not have the correct permissions to update the %1$s plugins.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:368\n#: admin/includes/menus/welcome.php:234\n#, php-format\nmsgid \"The following required plugin is currently inactive: %1$s.\"\nmsgid_plural \"The following required plugins are currently inactive: %1$s.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:373\n#: admin/includes/menus/welcome.php:235\n#, php-format\nmsgid \"The following recommended plugin is currently inactive: %1$s.\"\nmsgid_plural \"The following recommended plugins are currently inactive: %1$s.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:378\n#, php-format\nmsgid \"\"\n\"Sorry, but you do not have the correct permissions to activate the %1$s plugin.\"\nmsgid_plural \"\"\n\"Sorry, but you do not have the correct permissions to activate the %1$s plugins.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:383\n#: admin/includes/menus/welcome.php:239\nmsgid \"Begin installing plugin\"\nmsgid_plural \"Begin installing plugins\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:388\nmsgid \"Begin updating plugin\"\nmsgid_plural \"Begin updating plugins\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:393\n#: admin/includes/menus/welcome.php:240\nmsgid \"Begin activating plugin\"\nmsgid_plural \"Begin activating plugins\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:397\n#: admin/includes/menus/welcome.php:241\nmsgid \"Return to Required Plugins Installer\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:398\nmsgid \"Return to the dashboard\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:399\n#: admin/includes/class-tgm-plugin-activation.php:3029\n#: admin/includes/menus/welcome.php:242\nmsgid \"Plugin activated successfully.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:400\n#: admin/includes/class-tgm-plugin-activation.php:2832\nmsgid \"The following plugin was activated successfully:\"\nmsgid_plural \"The following plugins were activated successfully:\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:401\n#, php-format\nmsgid \"No action taken. Plugin %1$s was already active.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:402\n#, php-format\nmsgid \"\"\n\"Plugin not activated. A higher version of %s is needed for this theme. Please \"\n\"update the plugin.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:403\n#, php-format\nmsgid \"All plugins installed and activated successfully. %1$s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:404\nmsgid \"Dismiss this notice\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:405\nmsgid \"Please contact the administrator of this site for help.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:520\nmsgid \"This plugin needs to be updated to be compatible with your theme.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:521\nmsgid \"Update Required\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:635\nmsgid \"Set the parent_slug config variable instead.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:828\n#: admin/includes/class-tgm-plugin-activation.php:3438\nmsgid \"Return to the Dashboard\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:935\nmsgid \"\"\n\"The remote plugin package does not contain a folder with the desired slug and \"\n\"renaming did not work.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:935\n#: admin/includes/class-tgm-plugin-activation.php:938\nmsgid \"\"\n\"Please contact the plugin provider and ask them to package their plugin \"\n\"according to the WordPress guidelines.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:938\nmsgid \"\"\n\"The remote plugin package consists of more than one file, but the files are not \"\n\"packaged in a folder.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:1116\n#: admin/includes/class-tgm-plugin-activation.php:2828\nmsgctxt \"plugin A *and* plugin B\"\nmsgid \"and\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:1881\n#, php-format\nmsgctxt \"%s = version number\"\nmsgid \"TGMPA v%s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2167\nmsgid \"Required\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2170\nmsgid \"Recommended\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2186\nmsgid \"WordPress Repository\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2189\nmsgid \"External Source\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2192\nmsgid \"Pre-Packaged\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2209\nmsgid \"Not Installed\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2213\nmsgid \"Installed But Not Activated\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2215\nmsgid \"Active\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2221\nmsgid \"Required Update not Available\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2224\nmsgid \"Requires Update\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2227\nmsgid \"Update recommended\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2235\n#, php-format\nmsgctxt \"%1$s = install status, %2$s = update status\"\nmsgid \"%1$s, %2$s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2280\n#, php-format\nmsgctxt \"plugins\"\nmsgid \"All <span class=\\\"count\\\">(%s)</span>\"\nmsgid_plural \"All <span class=\\\"count\\\">(%s)</span>\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2283\n#, php-format\nmsgid \"To Install <span class=\\\"count\\\">(%s)</span>\"\nmsgid_plural \"To Install <span class=\\\"count\\\">(%s)</span>\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2286\n#, php-format\nmsgid \"Update Available <span class=\\\"count\\\">(%s)</span>\"\nmsgid_plural \"Update Available <span class=\\\"count\\\">(%s)</span>\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2289\n#, php-format\nmsgid \"To Activate <span class=\\\"count\\\">(%s)</span>\"\nmsgid_plural \"To Activate <span class=\\\"count\\\">(%s)</span>\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2371\nmsgctxt \"as in: \\\"version nr unknown\\\"\"\nmsgid \"unknown\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2379\nmsgid \"Installed version:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2387\nmsgid \"Minimum required version:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2399\nmsgid \"Available version:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2422\n#, php-format\nmsgid \"\"\n\"No plugins to install, update or activate. <a href=\\\"%1$s\\\">Return to the \"\n\"Dashboard</a>\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2436\nmsgid \"Plugin\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2437\nmsgid \"Source\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2438\nmsgid \"Type\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2442\n#: admin/includes/menus/welcome.php:118\nmsgid \"Version\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2443\n#: admin/includes/menus/welcome.php:49 public/includes/editor-modules.php:614\nmsgid \"Status\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2491\n#, php-format\nmsgctxt \"%2$s = plugin name in screen reader markup\"\nmsgid \"Install %2$s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2495\n#, php-format\nmsgctxt \"%2$s = plugin name in screen reader markup\"\nmsgid \"Update %2$s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2500\n#, php-format\nmsgctxt \"%2$s = plugin name in screen reader markup\"\nmsgid \"Activate %2$s\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2570\nmsgid \"Upgrade message from the plugin author:\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2603\nmsgid \"Install\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2609\nmsgid \"Update\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2612\nmsgid \"Activate\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2643\nmsgid \"No plugins were selected to be installed. No action taken.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2645\nmsgid \"No plugins were selected to be updated. No action taken.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2681\nmsgid \"No plugins are available to be installed at this time.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2683\nmsgid \"No plugins are available to be updated at this time.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2788\nmsgid \"No plugins were selected to be activated. No action taken.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:2814\nmsgid \"No plugins are available to be activated at this time.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3028\nmsgid \"Plugin activation failed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3362\n#, php-format\nmsgid \"Updating Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3364\n#, php-format\nmsgid \"An error occurred while installing %1$s: <strong>%2$s</strong>.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3365\n#, php-format\nmsgid \"The installation of %1$s failed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3369\nmsgid \"\"\n\"The installation and activation process is starting. This process may take a \"\n\"while on some hosts, so please be patient.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3370\n#, php-format\nmsgid \"%1$s installed and activated successfully.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3370\n#: admin/includes/class-tgm-plugin-activation.php:3376\nmsgid \"Show Details\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3370\n#: admin/includes/class-tgm-plugin-activation.php:3376\nmsgid \"Hide Details\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3371\nmsgid \"All installations and activations have been completed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3372\n#, php-format\nmsgid \"Installing and Activating Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3375\nmsgid \"\"\n\"The installation process is starting. This process may take a while on some \"\n\"hosts, so please be patient.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3376\n#, php-format\nmsgid \"%1$s installed successfully.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3377\nmsgid \"All installations have been completed.\"\nmsgstr \"\"\n\n#: admin/includes/class-tgm-plugin-activation.php:3378\n#, php-format\nmsgid \"Installing Plugin %1$s (%2$d/%3$d)\"\nmsgstr \"\"\n\n#: admin/includes/load_admin.php:151\nmsgid \"Dismiss this notice.\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:30\nmsgid \"Aesopinteractive LLC\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:38 admin/includes/menus/license.php:57\nmsgid \"License Key\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:38\nmsgid \"License\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:47\nmsgid \"Editus License\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:48\nmsgid \"\"\n\"Input the license key you recieved with your purchase to ensure your version of \"\n\"Editus stays updated.\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:66 admin/includes/menus/license.php:75\nmsgid \"Activate License\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:70\nmsgid \"active\"\nmsgstr \"\"\n\n#: admin/includes/menus/license.php:72\nmsgid \"Deactivate License\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:26 public/includes/editor-modules.php:493\n#: public/includes/editor-modules.php:892 public/includes/editor-modules.php:894\n#: public/includes/editor-modules.php:909 public/includes/editor-modules.php:928\nmsgid \"Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:169\nmsgid \"Editus Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:177\nmsgid \"Enable for:\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:181\nmsgid \"Enable Editus for the following post types.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:203\nmsgid \"Internal Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:206\nmsgid \"Article Class\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:207\nmsgid \"\"\n\"Provide the CSS class (including the preceding dot) of container that holds the \"\n\"post. This should be the first parent container class that holds the_content.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:212\nmsgid \"Featured Image Class\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:213\nmsgid \"\"\n\"Provide the CSS class that uses a featured image as a background image. This \"\n\"currently only supports themes that have the featured image set as background \"\n\"image.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:218\nmsgid \"Article Title Class\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:219\nmsgid \"\"\n\"Provide the CSS class for the post title. This will enable you to update the \"\n\"title of the post by clicking and typing.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:224\nmsgid \"Ignored Items to Save\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:225\nmsgid \"\"\n\"If your post container holds additional markup, list the css class names (comma \"\n\"separated, including the dot) of those items. When you enter the editor, Editus \"\n\"will remove (NOT delete) these items so that it does not save them as HTML.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:230\nmsgid \"Read Only Items\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:231\nmsgid \"\"\n\"If your post has items that should not be editable, list the css class names \"\n\"(comma separated, including the dot) of those items.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:237\nmsgid \"Show Ignored Items\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:238\nmsgid \"\"\n\"By default the ignored items are hidden. Check this to show ignored items while \"\n\"keeping them uneditable.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:242\nmsgid \"Editor UI\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:246\nmsgid \"Use the Old Toolbar\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:247\nmsgid \"\"\n\"Use this option to disable the new color options and use the pre-1.0 toolbar.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:251\nmsgid \"Editor Bar Color Top\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:252\nmsgid \"Editor Bar Color Bottom\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:253\nmsgid \"Dialog Color\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:254\nmsgid \"Icon/Text Color\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:256\nmsgid \"Default Colors\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:261\nmsgid \"Enable H2 and H3 Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:262\nmsgid \"Show the buttons to set H2 and H3 settings.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:267\nmsgid \"Enable H4/H5/H6 Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:268\nmsgid \"Show the buttons to set H4/H5/H6 settings.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:274\nmsgid \"Enable OL/UL Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:275\nmsgid \"\"\n\"Show the buttons to create Ordered and Unordered Lists from text selection.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:280\nmsgid \"Enable Text Color Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:281\nmsgid \"Show the buttons to set text colors.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:286\nmsgid \"Enable Text Align Buttons\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:287\nmsgid \"Show the buttons to set text alignment.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:293\nmsgid \"Make links editable under the Editing Mode\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:294\nmsgid \"\"\n\"Make links editable under the Editing Mode. Turning this on will make the links \"\n\"non-clickable while editing.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:298\nmsgid \"Insert Component UI\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:299\nmsgid \"UI mechanism to insert components\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:301\nmsgid \"Drag and Drop\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:304\nmsgid \"Click\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:307\nmsgid \"Auto Button on Empty Paragraph. medium.com-like UI.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:313\nmsgid \"Popup When Text is Selected\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:314\nmsgid \"\"\n\"Instead of using the bottom toolbar to format texts, use a popup box to format \"\n\"texts.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:320\nmsgid \"Component\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:324\nmsgid \"Additional Component: Table\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:325\nmsgid \"Allow user to add and edit tables.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:331\nmsgid \"Additional Component: Paragraph\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:332\nmsgid \"Plain HTML Paragraph.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:363\nmsgid \"Use Simple Image\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:364\nmsgid \"Use Simple Image Component without Extra Options.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:371\nmsgid \"Use WP Image Block\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:372\nmsgid \"\"\n\"Use WP Image Block as the image component. Gutenberg Block Editor needs to be \"\n\"enabled.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:379\nmsgid \"Post Settings UI\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:383\nmsgid \"Disable Post Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:384\nmsgid \"\"\n\"Check this to disable users from being able to edit post settings from the \"\n\"front-end.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:389\nmsgid \"Allow Changing Post Date\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:390\nmsgid \"Add the date selector to change the post's date to the Post Setting dialog\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:395\nmsgid \"Allow Editing Excerpt\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:396\nmsgid \"Allow the post's excerpt to be edited in the Post Setting dialog\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:401\nmsgid \"Allow Adding New Category\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:402\nmsgid \"Add the user to create new, previously non-existing categories for posts.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:407\nmsgid \"Do Not Allow \\\"Pending\\\" Status\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:408\nmsgid \"Remove the Option to Set the Status to Pending.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:413\nmsgid \"Remove POST URL Option\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:414\nmsgid \"Remove the Option to Set the URL for the Post.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:419\nmsgid \"Disable Post Adding\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:420\nmsgid \"\"\n\"Check this box to disable users from being able to add new posts from the front-\"\n\"end.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:425\nmsgid \"Support Custom Taxonomy\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:426\nmsgid \"Allow editing custom taxonomies.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:432\nmsgid \"Misc\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:436\nmsgid \"Do Not Show Tour Dialog\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:437\nmsgid \"Check this box to disable the tour dialog box for all users.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:441\nmsgid \"Placeholder Text for New Post\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:442\nmsgid \"Placeholder text to be displayed when a new post is created.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:443 includes/process/new_object.php:38\n#: public/includes/assets.php:248\nmsgid \"Once upon a time...\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:448\nmsgid \"Do Not Allow Shortcode Editing\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:449\nmsgid \"Check this box to disable frontend editing of shortcodes.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:453\nmsgid \"\\\"Bold\\\" Tag\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:454\nmsgid \"Choose the HTML tag used for the \\\"Bold\\\" style.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:459\nmsgid \"\\\"Italic\\\" Tag\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:460\nmsgid \"Choose the HTML tag used for the \\\"Italic\\\" style.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:466\nmsgid \"Auto Prefix HTTP to links\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:467\nmsgid \"\"\n\"When user adds a hyperlink, automatically add http:// if the user does not \"\n\"specify it explicitly.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:471\nmsgid \"Advanced Options\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:472\nmsgid \"Suggested not to turn these options on without consulting the developer.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:477\nmsgid \"Disable Aesop Component Conversion\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:478\nmsgid \"\"\n\"Check this box to disable the conversion process used on Aesop Story Engine \"\n\"components.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:483\nmsgid \"Enable Auto Save\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:484\nmsgid \"Check this box to enable auto save.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:489\nmsgid \"Disable Post Saving\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:490\nmsgid \"\"\n\"By default the editor will update the database with the post or page it is \"\n\"being used on. Check this box to disable this. If you check this box, it is \"\n\"assumed that you will be using the provided filters to save your own content.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:496\nmsgid \"Disable Post Editing\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:497\nmsgid \"\"\n\"You may use this option if you only want to edit custom fields. Refer <a href=\"\n\"\\\"https://edituswp.com/editing-and-updating-custom-fields-from-frontend/\"\n\"\\\">here</a> for more information. The custom fields you specify will be still \"\n\"editable under the editing mode.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:503\nmsgid \"Don't Use REST API to Save\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:504\nmsgid \"\"\n\"By default the editor will use REST API to save posts. Check this box to use \"\n\"custom AJAX calls instead.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:510\nmsgid \"Don't Wrap Shortcodes\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:511\nmsgid \"\"\n\"By default Editus wraps shortcodes so they can be preserved. Disable this \"\n\"behavior.\"\nmsgstr \"\"\n\n#: admin/includes/menus/settings.php:521\nmsgid \"Save Settings\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:48\nmsgid \"Editus\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:49\nmsgid \"Welcome\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:71\nmsgid \"\"\n\"We will check the current theme on every site in your network and give you a \"\n\"quick status feedback here. You can see the status by visiting the Editus menu \"\n\"on each site.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:90\nmsgid \"You're Ready to Rock!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:92\nmsgid \"Your theme is automatically supported. No additional setup is needed.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:94\nmsgid \"\"\n\"Editus will place a small menu on the bottom of your site. While on a single \"\n\"post or page, click the \\\"pen\\\" icon to go into edit mode. Press escape to get \"\n\"out of edit mode.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:117\nmsgid \"Welcome to Editus\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:123\nmsgid \"Help\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:124\nmsgid \"Twitter\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:125\nmsgid \"Facebook\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:158\nmsgid \"Article CSS Class Needed!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"Before using Editus,\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"enter and save\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"\"\n\"the CSS class of the container that holds your post and page content. You can \"\n\"<a href=\\\"https://dl.dropboxusercontent.com/u/5594632/lasso-media/doc-movies/\"\n\"using-inspector-lasso.gif\\\" target=\\\"_blank\\\">use a tool like inspector</a> in \"\n\"Chrome or Firefox to find this CSS class, or \"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"email us.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:159\nmsgid \"with a link to a public URL with the theme and we'll find it for you.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:166\nmsgid \"\"\n\"Just a heads up that the WP REST API isn't activated. This is required to list \"\n\"the posts and pages on the front-end.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:173\nmsgid \"Just a heads up that \"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:174 admin/includes/menus/welcome.php:211\nmsgid \"Aesop Story Engine\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:174\nmsgid \"\"\n\"isn't activated. It's not required to use Editus, but you won't get the cool \"\n\"drag and drop components without it activated. It's free!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:180\nmsgid \"WP Side Comments Compatibility Warning!\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:181\nmsgid \"\"\n\"Since Editus saves the HTML of a post, this may cause undesired issues. We're \"\n\"working to resolve incompatibilities faster than a jack rabbit in a hot greasy \"\n\"griddle in the middle of August.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:187\nmsgid \"License Key Not Activated\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:188\nmsgid \"\"\n\"Just a heads up, your license key isn't activated. Enter your license key into \"\n\"the License tab on the left in order to receive plugin update notifications.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:192\nmsgid \"License Key Invalid\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \"The license key that you entered is \"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \"invalid\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:193\nmsgid \". It may have been entered incorreclty, or may have expired.\"\nmsgstr \"\"\n\n#: admin/includes/menus/welcome.php:231\n#, php-format\nmsgid \"This plugin requires the following plugin: %1$s.\"\nmsgid_plural \"This plugin requires the following plugins: %1$s.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/menus/welcome.php:232\n#, php-format\nmsgid \"This plugin recommends the following plugin: %1$s.\"\nmsgid_plural \"This plugin recommends the following plugins: %1$s.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/menus/welcome.php:233\n#, php-format\nmsgid \"\"\n\"Sorry, but you do not have the correct permissions to install the %s plugin. \"\n\"Contact the administrator of this site for help on getting the plugin installed.\"\nmsgid_plural \"\"\n\"Sorry, but you do not have the correct permissions to install the %s plugins. \"\n\"Contact the administrator of this site for help on getting the plugins \"\n\"installed.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/menus/welcome.php:236\n#, php-format\nmsgid \"\"\n\"Sorry, but you do not have the correct permissions to activate the %s plugin. \"\n\"Contact the administrator of this site for help on getting the plugin activated.\"\nmsgid_plural \"\"\n\"Sorry, but you do not have the correct permissions to activate the %s plugins. \"\n\"Contact the administrator of this site for help on getting the plugins \"\n\"activated.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/menus/welcome.php:237\n#, php-format\nmsgid \"\"\n\"The following plugin needs to be updated to its latest version to ensure \"\n\"maximum compatibility with this plugin: %1$s.\"\nmsgid_plural \"\"\n\"The following plugins need to be updated to their latest version to ensure \"\n\"maximum compatibility with this plugin: %1$s.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/menus/welcome.php:238\n#, php-format\nmsgid \"\"\n\"Sorry, but you do not have the correct permissions to update the %s plugin. \"\n\"Contact the administrator of this site for help on getting the plugin updated.\"\nmsgid_plural \"\"\n\"Sorry, but you do not have the correct permissions to update the %s plugins. \"\n\"Contact the administrator of this site for help on getting the plugins updated.\"\nmsgstr[0] \"\"\nmsgstr[1] \"\"\n\n#: admin/includes/menus/welcome.php:243\n#, php-format\nmsgid \"All plugins installed and activated successfully. %s\"\nmsgstr \"\"\n\n#: includes/process/gallery.php:40\nmsgid \"Save and refresh to view gallery.\"\nmsgstr \"\"\n\n#: includes/process/gallery.php:199\nmsgid \"Delete From Gallery\"\nmsgstr \"\"\n\n#: includes/process/gallery.php:200\nmsgid \"Edit Image Caption\"\nmsgstr \"\"\n\n#: internal-api/auth.php:67\nmsgid \"Unauthorized action\"\nmsgstr \"\"\n\n#: internal-api/auth.php:71\nmsgid \"\"\n\"All callback classes used for processing the Editus Internal API must implement \"\n\"the lasso\\\\internal_api\\\\api_action interface.\"\nmsgstr \"\"\n\n#: internal-api/auth.php:76\nmsgid \"Nonce invalid\"\nmsgstr \"\"\n\n#: internal-api/route.php:30\nmsgid \"Editus API Error.\"\nmsgstr \"\"\n\n#: internal-api/route.php:66\nmsgid \"Nonce not set.\"\nmsgstr \"\"\n\n#: lasso.php:130\nmsgid \"Insert Column\"\nmsgstr \"\"\n\n#: lasso.php:131\nmsgid \"Insert Row\"\nmsgstr \"\"\n\n#: lasso.php:132\nmsgid \"Delete Column\"\nmsgstr \"\"\n\n#: lasso.php:133\nmsgid \"Delete Row\"\nmsgstr \"\"\n\n#: lasso.php:134\nmsgid \"Delete Table\"\nmsgstr \"\"\n\n#: lasso.php:149 lasso.php:159\nmsgid \"HTML Table\"\nmsgstr \"\"\n\n#: lasso.php:192 lasso.php:220\nmsgid \"HTML Paragraph\"\nmsgstr \"\"\n\n#: public/includes/assets.php:146 public/includes/editor-modules.php:713\n#: public/includes/option-engine.php:132\nmsgid \"Save\"\nmsgstr \"\"\n\n#: public/includes/assets.php:147\nmsgid \"Please Select Text First.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:148 public/includes/editor-modules.php:439\n#: public/includes/editor-modules.php:706 public/includes/editor-modules.php:788\n#: public/includes/editor-modules.php:1329\nmsgid \"Cancel\"\nmsgstr \"\"\n\n#: public/includes/assets.php:149\nmsgid \"Exit Editor\"\nmsgstr \"\"\n\n#: public/includes/assets.php:150\nmsgid \"Saving...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:151\nmsgid \"Saved!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:152\nmsgid \"Adding...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:153\nmsgid \"Added!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:154\nmsgid \"Loading...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:155\nmsgid \"Load More\"\nmsgstr \"\"\n\n#: public/includes/assets.php:156 public/includes/helpers.php:457\nmsgid \"Close\"\nmsgstr \"\"\n\n#: public/includes/assets.php:157\nmsgid \"No more posts found\"\nmsgstr \"\"\n\n#: public/includes/assets.php:158\nmsgid \"Fetching failed.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:159\nmsgid \"Gallery Created!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:160\nmsgid \"Gallery Updated!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:161\nmsgid \"Just write...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:162\nmsgid \"Choose an image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:163\nmsgid \"Update Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:164\nmsgid \"Insert Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:165\nmsgid \"Select Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:166\nmsgid \"Remove featured image?\"\nmsgstr \"\"\n\n#: public/includes/assets.php:167\nmsgid \"Update Selected Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:168\nmsgid \"Choose images\"\nmsgstr \"\"\n\n#: public/includes/assets.php:169\nmsgid \"Edit Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:170 public/includes/editor-modules--gallery.php:28\nmsgid \"Add Images\"\nmsgstr \"\"\n\n#: public/includes/assets.php:171\nmsgid \"Add New Gallery\"\nmsgstr \"\"\n\n#: public/includes/assets.php:172\nmsgid \"Select Editus Gallery Image\"\nmsgstr \"\"\n\n#: public/includes/assets.php:173\nmsgid \"Use Selected Images\"\nmsgstr \"\"\n\n#: public/includes/assets.php:174\nmsgid \"Publish Post?\"\nmsgstr \"\"\n\n#: public/includes/assets.php:175\nmsgid \"Yes, publish it!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:176\nmsgid \"Trash Post?\"\nmsgstr \"\"\n\n#: public/includes/assets.php:177\nmsgid \"Yes, trash it!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:178\nmsgid \"Oh snap!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:179\nmsgid \"O.K. got it!\"\nmsgstr \"\"\n\n#: public/includes/assets.php:180\nmsgid \"\"\n\"It looks like we are either missing the Article CSS class, or it is configured \"\n\"incorrectly. Editus will not function correctly without this CSS class.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:181\nmsgid \"Update Settings\"\nmsgstr \"\"\n\n#: public/includes/assets.php:182\nmsgid \"one more letter\"\nmsgstr \"\"\n\n#: public/includes/assets.php:183\nmsgid \"You are currently editing a backup copy of this post.\"\nmsgstr \"\"\n\n#: public/includes/assets.php:185\nmsgid \"add categories...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:186\nmsgid \"add tags...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:187\nmsgid \"add taxonomy terms...\"\nmsgstr \"\"\n\n#: public/includes/assets.php:188\nmsgid \"Edit Shortcode\"\nmsgstr \"\"\n\n#: public/includes/components.php:19 public/includes/editor-modules.php:352\nmsgid \"Quote\"\nmsgstr \"\"\n\n#: public/includes/components.php:23 public/includes/editor-modules.php:350\n#: public/includes/editor-modules.php:1103 public/includes/editor-modules.php:1154\n#: public/includes/editor-modules.php:1218\nmsgid \"Image\"\nmsgstr \"\"\n\n#: public/includes/components.php:27\n#: public/includes/editor-modules--gallery.php:74\n#: public/includes/editor-modules.php:355\nmsgid \"Parallax\"\nmsgstr \"\"\n\n#: public/includes/components.php:31 public/includes/editor-modules.php:356\nmsgid \"Audio\"\nmsgstr \"\"\n\n#: public/includes/components.php:35 public/includes/editor-modules.php:353\n#: public/includes/editor-modules.php:1080\nmsgid \"Content\"\nmsgstr \"\"\n\n#: public/includes/components.php:39 public/includes/editor-modules.php:351\nmsgid \"Character\"\nmsgstr \"\"\n\n#: public/includes/components.php:43 public/includes/editor-modules.php:361\nmsgid \"Collection\"\nmsgstr \"\"\n\n#: public/includes/components.php:47 public/includes/editor-modules.php:360\nmsgid \"Document\"\nmsgstr \"\"\n\n#: public/includes/components.php:51 public/includes/editor-modules.php:362\nmsgid \"Gallery\"\nmsgstr \"\"\n\n#: public/includes/components.php:55 public/includes/editor-modules.php:354\nmsgid \"Chapter\"\nmsgstr \"\"\n\n#: public/includes/components.php:59 public/includes/editor-modules.php:358\nmsgid \"Map\"\nmsgstr \"\"\n\n#: public/includes/components.php:63 public/includes/editor-modules.php:359\nmsgid \"Timeline\"\nmsgstr \"\"\n\n#: public/includes/components.php:67 public/includes/editor-modules.php:357\nmsgid \"Video\"\nmsgstr \"\"\n\n#: public/includes/components.php:71 public/includes/components.php:91\n#: public/includes/editor-modules.php:371 public/includes/editor-modules.php:373\nmsgid \"WordPress Image\"\nmsgstr \"\"\n\n#: public/includes/components.php:75\nmsgid \"WordPress Image Block\"\nmsgstr \"\"\n\n#: public/includes/components.php:79 public/includes/editor-modules.php:375\nmsgid \"WordPress Quote\"\nmsgstr \"\"\n\n#: public/includes/components.php:83 public/includes/editor-modules.php:364\nmsgid \"Gallery Pop\"\nmsgstr \"\"\n\n#: public/includes/components.php:87\nmsgid \"Events\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:19\nmsgid \"Create gallery\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:27\nmsgid \"Manage Images\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:31\nmsgid \"Rearrange or edit the images in this gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:47\nmsgid \"Create a Gallery\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:51\nmsgid \"Select images to create a gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:52\nmsgid \"Select Images\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:56\nmsgid \"Create Gallery\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:67\nmsgid \"Gallery Type\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:68\nmsgid \"Select the type of gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:70\nmsgid \"Grid\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:71\nmsgid \"Thumbnail\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:73\nmsgid \"Photoset\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:84\nmsgid \"Grid Item Width\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:85\nmsgid \"\"\n\"Adjust the width of the individual grid items, only if using Grid gallery \"\n\"style. Default is 400.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:95\nmsgid \"Gallery Transition\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:96\nmsgid \"Adjust the transition effect for the Thumbnail gallery. Default is slide.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:98\nmsgid \"Fade\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:99\nmsgid \"Slide\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:100\nmsgid \"Dissolve\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:105\nmsgid \"Gallery Transition Speed\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:106\nmsgid \"Activate slideshow by setting a speed for the transition.5000 = 5 seconds.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:112\nmsgid \"Hide Gallery Thumbnails\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:121\nmsgid \"Gallery Layout\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:122\nmsgid \"\"\n\"Let's say you have 4 images in this gallery. If you enter 121 you will have one \"\n\"image on the top row, two images on the second row, and one image on the third \"\n\"row.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:137\nmsgid \"Main Gallery Height\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:138\n#, php-format\nmsgid \"\"\n\"Adjust the overall height of the gallery. Acceptable values include 500px or \"\n\"50% etc.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:148\nmsgid \"Main Gallery Width\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:149\n#, php-format\nmsgid \"\"\n\"Adjust the overall width of the gallery. Acceptable values include 500px or \"\n\"50% etc.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:153\nmsgid \"Gallery Caption\"\nmsgstr \"\"\n\n#: public/includes/editor-modules--gallery.php:154\nmsgid \"Add an optional caption for the gallery.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:60 public/includes/editor-modules.php:437\nmsgid \"Table\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:137\n#: public/includes/underscore-templates.php:23\n#: public/includes/underscore-templates.php:41\nmsgid \"Edit Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:140 public/includes/editor-modules.php:164\n#: public/includes/editor-modules.php:457\nmsgid \"Post Settings\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:145\nmsgid \"All Posts\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:148 public/includes/editor-modules.php:1323\nmsgid \"Revisions\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:152\nmsgid \"Add Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:163 public/includes/editor-modules.php:456\n#: public/includes/underscore-templates.php:25\n#: public/includes/underscore-templates.php:43\nmsgid \"Delete Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:167 public/includes/editor-modules.php:459\nmsgid \"Save Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:170 public/includes/editor-modules.php:462\nmsgid \"Publish Post\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:170\nmsgid \"Submit For Review\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:249 public/includes/editor-modules.php:342\nmsgid \"Bold\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:250 public/includes/editor-modules.php:343\nmsgid \"Underline\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:251 public/includes/editor-modules.php:344\nmsgid \"Italicize\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:252 public/includes/editor-modules.php:345\nmsgid \"Strikethrough\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:255 public/includes/editor-modules.php:384\n#: public/includes/editor-modules.php:431\nmsgid \"H2 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:256 public/includes/editor-modules.php:385\n#: public/includes/editor-modules.php:432\nmsgid \"H3 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:262 public/includes/editor-modules.php:391\nmsgid \"H4 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:263 public/includes/editor-modules.php:392\nmsgid \"H5 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:264 public/includes/editor-modules.php:393\nmsgid \"H6 Heading\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:268 public/includes/editor-modules.php:397\nmsgid \"Set Color for Selected Text\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:269 public/includes/editor-modules.php:398\nmsgid \"Choose Color\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:273 public/includes/editor-modules.php:402\n#: public/includes/editor-modules.php:434\nmsgid \"Ordered List\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:274 public/includes/editor-modules.php:403\n#: public/includes/editor-modules.php:435\nmsgid \"Unordered List\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:278 public/includes/editor-modules.php:407\nmsgid \"Anchor Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:280 public/includes/editor-modules.php:409\nmsgid \"http://url.com\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:281 public/includes/editor-modules.php:410\nmsgid \"Create Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:283 public/includes/editor-modules.php:412\nmsgid \"Open in a New Tab\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:347\nmsgid \"Insert Component\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:367\nmsgid \"Event\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:376\nmsgid \"WordPress Video\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:419 public/includes/editor-modules.php:440\nmsgid \"Insert HTML or Code\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:421 public/includes/editor-modules.php:424\nmsgid \"Enter HTML to insert\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:425\nmsgid \"You can also use Shortcodes\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:426\nmsgid \"\"\n\"You can also enter a URL to embed, such as Youtube, Vimeo and Twitter URLs.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:440\nmsgid \"Insert\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:446\nmsgid \"Text Left Align\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:447\nmsgid \"Text Center Align\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:448\nmsgid \"Text Right Align\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:492 public/includes/editor-modules.php:890\n#: public/includes/editor-modules.php:908 public/includes/editor-modules.php:927\nmsgid \"Move\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:494 public/includes/editor-modules.php:896\n#: public/includes/editor-modules.php:910 public/includes/editor-modules.php:929\nmsgid \"Clone\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:495 public/includes/editor-modules.php:897\n#: public/includes/editor-modules.php:911 public/includes/editor-modules.php:930\nmsgid \"Delete\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:517\nmsgid \"Replace Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:518\nmsgid \"Delete Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:519\nmsgid \"save\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:593\nmsgid \"Featured Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:593\nmsgid \"Change the featured image for this post.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:597\nmsgid \"Change Featured Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:598\nmsgid \"Delete Featured Image\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:614\nmsgid \"Change the status of the post to draft or publish.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:616\nmsgid \"Draft\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:618\nmsgid \"Pending\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:620\nmsgid \"Publish\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:630\nmsgid \"Post URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:630\nmsgid \"Change the URL (slug) of this post.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:640\nmsgid \"Categories\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:640\nmsgid \"Type a category name and press enter.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:645\nmsgid \"Tags\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:645\nmsgid \"Type a tag name and press enter.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:653\nmsgid \"Custom Taxonomy\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:653\nmsgid \"Choose custom taxonomy.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:670\nmsgid \"Excerpt\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:670\nmsgid \"Edit excerpt\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:679\nmsgid \"Post Date\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:681\nmsgid \"Set to Now\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:762\nmsgid \"New <span>post</span> title\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:762\nmsgid \"Specify title for new post, then save to edit.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:763\nmsgid \"Type Your Title Here\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:800\nmsgid \"Create\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:839\nmsgid \"results found\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:952\nmsgid \"Save Locations\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:970\nmsgid \"Save this post and refesh the page to see these changes.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1109 public/includes/editor-modules.php:1224\n#: public/includes/editor-modules.php:1289\nmsgid \"Image URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1110 public/includes/editor-modules.php:1225\n#: public/includes/editor-modules.php:1290\nmsgid \"\"\n\"URL for the image. Click <em>Select Media</em> to open the WordPress Media \"\n\"Library.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1117 public/includes/editor-modules.php:1232\nmsgid \"Center\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1121 public/includes/editor-modules.php:1236\nmsgid \"Left\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1125 public/includes/editor-modules.php:1240\nmsgid \"Right\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1129 public/includes/editor-modules.php:1244\nmsgid \"Alignment\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1136\nmsgid \"Image Width\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1137\nmsgid \"\"\n\"Width of the image. You can enter the size in pixels or percentage such as \"\n\"<code>40%</code> or <code>500px</code>.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1142\nmsgid \"Image Height\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1143\nmsgid \"\"\n\"Used only for the Panorama mode. Can be set using pixel values such as \"\n\"<code>500px</code>. If unspecified, the original height would be used. \"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1150\nmsgid \"None\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1158\nmsgid \"URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1162\nmsgid \"Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1163\nmsgid \"Click leads to:\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1169\nmsgid \"URL Link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1170\nmsgid \"URL link\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1175 public/includes/editor-modules.php:1250\nmsgid \"Image ALT\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1176 public/includes/editor-modules.php:1251\nmsgid \"ALT tag used for the image. Primarily used for SEO purposes.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1182 public/includes/editor-modules.php:1256\nmsgid \"Caption\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1183 public/includes/editor-modules.php:1257\nmsgid \"Optional caption for the image.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1188\nmsgid \"An image.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1262\nmsgid \"Link URL\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1263\nmsgid \"Optional URL to link.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1268\nmsgid \"A WP Image Block.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1283\nmsgid \"Cover\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1294\nmsgid \"A WP Cover Block.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1323\nmsgid \"Use the slider to view the revision live on the page.\"\nmsgstr \"\"\n\n#: public/includes/editor-modules.php:1330\nmsgid \"Select\"\nmsgstr \"\"\n\n#: public/includes/helpers.php:449\nmsgid \"No posts to show\"\nmsgstr \"\"\n\n#: public/includes/helpers.php:455\nmsgid \"No revisions found\"\nmsgstr \"\"\n\n#: public/includes/lasso.php:292\nmsgid \"Post being edited by \"\nmsgstr \"\"\n\n#: public/includes/tour.php:67\nmsgid \"Don't show this again\"\nmsgstr \"\"\n\n#: public/includes/tour.php:71\nmsgid \"Okay, got it!\"\nmsgstr \"\"\n\n#: public/includes/tour.php:96\nmsgid \"\"\n\"Access posts by clicking the list icon. Create a new post by clicking the new \"\n\"post icon.\"\nmsgstr \"\"\n\n#: public/includes/tour.php:99\nmsgid \"\"\n\"While on a single post, edit by clicking the Pen icon. Access post settings \"\n\"with the settings icon. Press escape to exit any modal.\"\nmsgstr \"\"\n\n#: public/includes/tour.php:102\nmsgid \"\"\n\"Highlight a piece of text, and click on a formatting option to style it. Click \"\n\"the Disk icon or CMD-S to save. Click the orange \\\"X\\\" button to exit the \"\n\"editor.\"\nmsgstr \"\"\n\n#: public/includes/tour.php:105\nmsgid \"\"\n\"Story components can be added by clicking the plus icon, and dragging any \"\n\"component from the component tray into the story.\"\nmsgstr \"\"\n"
  },
  {
    "path": "lasso.php",
    "content": "<?php\n/**\n *\n *\n * @package   Editus\n * @author    Hyun Supul <hyun@aesopinteractive.com>, Nick Haskins <nick@aesopinteractive.com>\n * @link      http://edituswp.com\n * @copyright 2015-2021 Aesopinteractive \n *\n * Plugin Name:       Editus\n * Plugin URI:        http://edituswp.com\n * Description:       Front-end editor and story builder.\n * Version:           1.7.0\n * Author:            Aesopinteractive \n * Author URI:        http://aesopinteractive.com\n * Text Domain:       lasso\n * Domain Path:       /languages\n */\n\n// If this file is called directly, abort.\nif ( ! defined( 'WPINC' ) ) {\n\tdie;\n}\n\n// Set some constants\ndefine( 'LASSO_VERSION', '1.7.0' );\ndefine( 'LASSO_DIR', plugin_dir_path( __FILE__ ) );\ndefine( 'LASSO_URL', plugins_url( '', __FILE__ ) );\ndefine( 'LASSO_FILE', __FILE__ );\n\n/**\n * Load plugin if PHP version is 5.4 or later.\n */\nif ( version_compare( PHP_VERSION, '5.4.0', '>=' ) ) {\n\n\tinclude_once( LASSO_DIR . '/bootstrap.php' );\n\n} else {\n\n\tadd_action('admin_head', 'lasso_fail_notice');\n\tfunction lasso_fail_notice(){\n\n\t\tprintf('<div class=\"error\"><p>Editus requires PHP 5.4 or higher.</p></div>');\n\n\t}\n}\n\nadd_filter('register_post_type_args', 'lasso_show_in_rest', 10, 2);\nfunction lasso_show_in_rest($args, $post_type){\n \n    $allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', array( ) );\n\t$allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types );\n\tif (in_array( $post_type,$allowed_post_types)) {\n\t\t$args['show_in_rest'] = true;\n\t\tif ($post_type != 'post' && $post_type != 'page') {\n\t\t\t$args['rest_base'] = $post_type;\n\t\t}\n\t}\n \n    return $args;\n}\n\n\nfunction lasso_editor_get_option( $option, $section, $default = '' ) {\n\n\tif ( empty( $option ) )\n\t\treturn;\n\n\tif ( function_exists( 'is_multisite' ) && is_multisite() ) {\n\n\t\t$options = get_site_option( $section );\n\n\t} else {\n\n\t\t$options = get_option( $section );\n\t}\n\n\tif ( isset( $options[$option] ) ) {\n\t\treturn $options[$option];\n\t}\n\n\treturn $default;\n}\n\nregister_meta('user', 'lasso_hide_tour', array(\n  \"type\" => \"string\",\n  \"show_in_rest\" => true // this is the key part\n));\n\n// Gutenberg\nif( function_exists( 'is_gutenberg_page' ) ) {\n\tfunction add_raw_to_post( $response, $post, $request ) {\n\t\t$response_data = $response->get_data();\n\t\tif ( is_array( $response_data['content'] )) {\n\t\t\t$response_data['content']['raw'] =  $post->post_content ;\n\t\t\t$response->set_data( $response_data );\n\t\t}\n\n\t\treturn $response;\n\t}\n\tadd_filter( \"rest_prepare_post\", 'add_raw_to_post', 10, 3 );\n}\n\n\n\n//table codes to be added\nclass editus_table {\n    \n    public function __construct(){\n        $add_table = lasso_editor_get_option('add_table', 'lasso_editor', false);\n        if ($add_table) {\n            add_action('wp_enqueue_scripts', array($this,'scripts'));\n            \n        }\n\t}\n    \n    function scripts()\n    {\n        add_action('lasso_editor_controls_after_outside', array($this,'editus_table_edit_menu'));\n            add_filter('lasso_components',array($this,'editus_components_add_table'),10,1);\n            add_action( 'lasso_toolbar_components', array($this,'editus_toolbar_components_add_table'), 10 );\n            wp_enqueue_style( 'editus-table-style', LASSO_URL.  '/public/assets/css/editus-table-edit-public.css', LASSO_VERSION, true );\n            wp_enqueue_script( 'editus_table',  LASSO_URL. '/public/assets/js/editus-table-edit-public.js', array( 'jquery' ), LASSO_VERSION, true );\n    }\n    \n    function editus_table_edit_menu()\n    { ?>\n\n        <ul class='editus-table-menu'>\n          <li data-action=\"insertcol\"><?php echo __('Insert Column','lasso')?></li>\n          <li data-action=\"insertrow\"><?php echo __('Insert Row','lasso')?></li>\n          <li data-action=\"delcol\"><?php echo __('Delete Column','lasso')?></li>\n          <li data-action=\"delrow\"><?php echo __('Delete Row','lasso')?></li>\n          <li data-action=\"deltable\"><?php echo __('Delete Table','lasso')?></li\n        </ul>\n    <?php\n    }\n    \n    \n    function editus_html_table()\n    {   \n        return '<figure class=\"wp-block-table\"><table><tr><th>Cell 1</th><th>Cell 2</th></tr><tr><td>Cell 3</td><td>Cell 4</td></tr></table></figure><p><br></p>';\n    }\n\n\n    function editus_components_add_table( $array ){\n        $custom = array(\n               'htmltable' => array(\n                         'name'    => __('HTML Table','lasso'),\n                          'content' => self::editus_html_table(),\n                )\n        );\n        return array_merge( $array, $custom );\n    }\n\n\n    function editus_toolbar_components_add_table( ) {\n          ?>\n          <li data-type=\"htmltable\" title=\"<?php esc_attr_e( 'HTML Table', 'lasso' );?>\" class=\"quote lasso-toolbar--component__htmltable dashicons dashicons-grid-view\"></li>\n          <?php\n    }\n}\n\n\nnew editus_table();\n\n\n\n//table codes to be added\nclass editus_paragraph {\n    \n    public function __construct(){\n        $add_paragraph = lasso_editor_get_option('add_paragraph', 'lasso_editor', false);\n        if ($add_paragraph) {\n            add_action('wp_enqueue_scripts', array($this,'scripts'));\n            \n        }\n\t}\n    \n    function scripts()\n    {\n            add_action('lasso_editor_controls_after_outside', array($this,'editus_paragraph_style'));\n            add_filter('lasso_components',array($this,'editus_components_add_paragraph'),10,1);\n            add_action( 'lasso_toolbar_components', array($this,'editus_toolbar_components_add_paragraph'), 10 );\n            //wp_enqueue_style( 'editus-table-style', LASSO_URL.  '/public/assets/css/editus-table-edit-public.css', LASSO_VERSION, true );\n            //wp_enqueue_script( 'editus_table',  LASSO_URL. '/public/assets/js/editus-table-edit-public.js', array( 'jquery' ), LASSO_VERSION, true );\n    }\n   \n    function editus_components_add_paragraph( $array ){\n        $custom = array(\n               'htmlparagraph' => array(\n                         'name'    => __('HTML Paragraph','lasso'),\n                          'content' => self::editus_html_paragraph(),\n                )\n        );\n        return array_merge( $array, $custom );\n    }\n    \n    \n    function editus_html_paragraph()\n    {   \n        return '<p contenteditable=\"true\"><br></p>';\n    }\n\n    function editus_paragraph_style()\n    { ?>\n        <style>\n        #lasso-toolbar--components__list .lasso-toolbar--component__htmlparagraph:before\n        { \n            content: \"\\f476\";\n            font-family: 'dashicons' !important; \n        }\n        </style>\n    <?php\n    }\n    \n\n    function editus_toolbar_components_add_paragraph( ) {\n          ?>\n          <li data-type=\"htmlparagraph\" title=\"<?php esc_attr_e( 'HTML Paragraph', 'lasso' );?>\" class=\"quote lasso-toolbar--component__htmlparagraph dashicons dashicons-editor-paragraph\"></li>\n          <?php\n    }\n}\n\nnew editus_paragraph();\n\n\n\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"lasso\",\n  \"version\": \"0.9.4\",\n  \"dependencies\": {\n    \"load-grunt-tasks\": \"~0.2.1\"\n  },\n  \"devDependencies\": {\n    \"grunt\": \"~0.4.2\",\n    \"grunt-contrib-concat\": \"*\",\n    \"grunt-contrib-less\": \"~0.9.0\",\n    \"grunt-contrib-jshint\": \"~0.8.0\",\n    \"grunt-contrib-uglify\": \"~0.2.7\",\n    \"grunt-contrib-watch\": \"~0.5.3\",\n    \"grunt-phplint\": \"~0.0.5\",\n    \"grunt-cssjanus\": \"~0.2.2\",\n    \"grunt-wp-i18n\": \"~0.4.9\",\n    \"grunt-potomo\": \"~2.1.0\"\n  }\n}\n"
  },
  {
    "path": "public/assets/css/editus-table-edit-public.css",
    "content": "ul.lasso-editor-controls .lasso-toolbar--component__htmltable:before,\n#lasso-toolbar--components__list .lasso-toolbar--component__htmltable:before\n{ \n    content: \"\\f509\";\n    font-family: 'dashicons' !important; \n}\n                       \n.editus-table-menu {\n    display: none;\n    z-index: 1000;\n    position: absolute;\n    overflow: hidden;\n    border: 1px solid #CCC;\n    white-space: nowrap;\n    font-family: sans-serif;\n    background: #FFF;\n    color: #333;\n    border-radius: 5px;\n    padding: 0;\n}\n\n/* Each of the items in the menu list */\n.editus-table-menu li {\n    padding: 8px 12px;\n    cursor: pointer;\n    list-style-type: none;\n    transition: all .3s ease;\n    user-select: none;\n}\n\n.editus-table-menu li:hover {\n    background-color: #DEF;\n}"
  },
  {
    "path": "public/assets/css/lasso.css",
    "content": ".lasso--animate__spin{-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.not-visible{opacity:0;filter:alpha(opacity=0);display:none;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease}@font-face{font-family:icomoon-editus;src:url(../../../public/assets/fonts/icomoon.eot?ua4grz);src:url(../../../public/assets/fonts/icomoon.eot?#iefixua4grz) format('embedded-opentype'),url(../../../public/assets/fonts/icomoon.woff?ua4grz) format('woff'),url(../../../public/assets/fonts/icomoon.ttf?ua4grz) format('truetype'),url(../../../public/assets/fonts/icomoon.svg?ua4grz#icomoon) format('svg');font-weight:400;font-style:normal}[class^=lasso-icon-],[class*=\" lasso-icon-\"]{font-family:icomoon-editus;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso-icon-move:before{content:\"\\e600\"}.lasso-icon-pen:before{content:\"\\e908\"}.lasso-icon-image:before{content:\"\\e90d\"}.lasso-icon-images:before{content:\"\\e90e\"}.lasso-icon-camera:before{content:\"\\e90f\"}.lasso-icon-headphones:before{content:\"\\e910\"}.lasso-icon-film:before{content:\"\\e913\"}.lasso-icon-book:before{content:\"\\e91f\"}.lasso-icon-books:before{content:\"\\e920\"}.lasso-icon-file-text2:before{content:\"\\e926\"}.lasso-icon-location:before{content:\"\\e947\"}.lasso-icon-clock:before{content:\"\\e94e\"}.lasso-icon-user:before{content:\"\\e971\"}.lasso-icon-quotes-left:before{content:\"\\e977\"}.lasso-icon-plus:before{content:\"\\ea0a\"}.lasso-icon-bold:before{content:\"\\ea62\"}.lasso-icon-underline:before{content:\"\\ea63\"}.lasso-icon-italic:before{content:\"\\ea64\"}.lasso-icon-strikethrough:before{content:\"\\ea65\"}.lasso-icon-pagebreak:before{content:\"\\ea6e\"}.lasso-icon-paragraph-center:before{content:\"\\ea78\"}.lasso-icon-spinner6:before{content:\"\\e97f\"}.lasso-icon-upload2:before{content:\"\\e9c6\"}.lasso-icon-cross:before{content:\"\\ea0f\"}.lasso-icon-bin2:before{content:\"\\e9ad\"}.lasso-icon-copy:before{content:\"\\e92c\"}.lasso-icon-disk:before{content:\"\\e601\"}.lasso-icon-embed:before{content:\"\\ea7f\"}.lasso-icon-blog:before{content:\"\\e909\"}.lasso-icon-pencil:before{content:\"\\e905\"}.lasso-icon-gear:before{content:'\\e994'}.lasso-icon-link:before{content:'\\e9cb'}.lasso-icon-help:before{content:\"\\e602\"}.lasso-icon-tools:before{content:\"\\f031\"}.lasso-icon-layout:before{content:\"\\e603\"}.lasso-icon-list:before{content:\"\\e9ba\"}.lasso-icon-file-add:before{content:\"\\e603\"}.lasso-icon-check:before{content:'\\ea10'}.lasso-icon-history:before{content:\"\\e94d\"}.lasso-editing .aesop-content-comp-wrap,.lasso-editing .aesop-video-container,.lasso-editing .aesop-image-component-image{-webkit-transition:all .25s linear;-moz-transition:all .25s linear;transition:all .25s linear}.lassoShowAnimate{-webkit-animation:lassoShowAnimate .2s;-moz-animation:lassoShowAnimate .2s;animation:lassoShowAnimate .2s}.lassoHideAnimate{-webkit-animation:lassoHideAnimate .2s;-moz-animation:lassoHideAnimate .2s;animation:lassoHideAnimate .2s}@-webkit-keyframes lassoShowAnimate{0%{transform:scale(0.7);-webkit-transform:scale(0.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-moz-keyframes lassoShowAnimate{0%{transform:scale(0.7);-webkit-transform:scale(0.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes lassoShowAnimate{0%{transform:scale(0.7);-webkit-transform:scale(0.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-webkit-keyframes lassoHideAnimate{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(0.5);-webkit-transform:scale(0.5)}}@-moz-keyframes lassoHideAnimate{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(0.5);-webkit-transform:scale(0.5)}}@keyframes lassoHideAnimate{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(0.5);-webkit-transform:scale(0.5)}}.aesop-component{position:relative}.screen-reader-text,.screen-reader-text span,.ui-helper-hidden-accessible{position:absolute;margin:-1px;padding:0;height:1px;width:1px;overflow:hidden;clip:rect(0 0 0 0);border:0}[contenteditable=true]:focus{outline:0}.lasso-title-saved{-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease;background:rgba(255,255,255,.1)}.lasso-drop-zone{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;height:75px;background:rgba(0,0,0,.03);border:1px dashed rgba(0,0,0,.2);list-style-type:none;width:700px;margin:0 auto 25px;border-radius:3px}.lasso-drop-zone:hover{background:rgba(0,0,0,.03)}.lasso-drag-holder{height:75px!important;background:#d7d7d7;text-align:center;width:60px;font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso-drag-holder.lasso-toolbar--component__wpimg:before,.lasso-drag-holder.lasso-toolbar--component__image:before{content:\"\\e90f\"}.lasso-drag-holder.lasso-toolbar--component__character:before{content:\"\\e971\"}.lasso-drag-holder.lasso-toolbar--component__wpquote:before,.lasso-drag-holder.lasso-toolbar--component__quote:before{content:\"\\e977\"}.lasso-drag-holder.lasso-toolbar--component__content:before{content:\"\\ea78\"}.lasso-drag-holder.lasso-toolbar--component__chapter:before{content:\"\\e91f\"}.lasso-drag-holder.lasso-toolbar--component__parallax:before{content:\"\\ea6e\"}.lasso-drag-holder.lasso-toolbar--component__audio:before{content:\"\\e910\"}.lasso-drag-holder.lasso-toolbar--component__wpvideo:before,.lasso-drag-holder.lasso-toolbar--component__video:before{content:\"\\e913\"}.lasso-drag-holder.lasso-toolbar--component__map:before{content:\"\\e947\"}.lasso-drag-holder.lasso-toolbar--component__timeline:before{content:\"\\e94e\"}.lasso-drag-holder.lasso-toolbar--component__document:before{content:\"\\e926\"}.lasso-drag-holder.lasso-toolbar--component__collection:before{content:\"\\e920\"}.lasso-drag-holder.lasso-toolbar--component__gallery:before{content:\"\\e90e\"}.lasso-drag-holder.lasso-toolbar--component__gallerypop:before{content:\"\\f211\";font-family:Dashicons}.lasso-drag-holder.lasso-toolbar--component__event:before{content:\"\\f145\";font-family:Dashicons}.lasso-drag-holder:before{position:relative;top:25px;font-size:22px}.lasso-editor:focus{outline:0;border:0;box-shadow:none}.lasso-editor p:empty{display:block}.lasso-editor .ui-draggable-dragging{list-style-type:none;height:50px;padding:10px;width:60px!important;background:rgba(35,40,45,.5);text-align:center;font-size:22px;border-radius:4px;font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__wpimg:before,.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__image:before{content:\"\\e90f\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__character:before{content:\"\\e971\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__wpquote:before,.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__quote:before{content:\"\\e977\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__content:before{content:\"\\ea78\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__chapter:before{content:\"\\e91f\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__parallax:before{content:\"\\ea6e\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__audio:before{content:\"\\e910\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__wpvideo:before,.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__video:before{content:\"\\e913\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__map:before{content:\"\\e947\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__timeline:before{content:\"\\e94e\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__document:before{content:\"\\e926\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__collection:before{content:\"\\e920\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__gallery:before{content:\"\\e90e\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__gallerypop:before{content:\"\\f211\";font-family:Dashicons}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__event:before{content:\"\\f145\";font-family:Dashicons}.lasso-editor .ui-draggable-dragging:before{color:#fff;position:relative;top:4px}.lasso-editor-clear{background:transparent!important;background-color:transparent!important;border-color:transparent!important}.lasso-editor-paste-hook{position:absolute;opacity:0}.lasso-editor-placeholder{position:absolute}.lasso-editor-placeholder div{opacity:.5;filter:alpha(opacity=50);position:absolute}.lasso-editor-placeholder-rich div{font-style:italic}.lasso-editor-inline,.lasso-editor-placeholder-inline div,.lasso-editor-inlineRich,.lasso-editor-placeholder-inlineRich div{overflow:hidden;white-space:nowrap}.lasso-editor-drag{position:absolute;cursor:move;margin-left:-5px;margin-top:-20px}.lasso-editor-toolbar-hide{overflow:hidden;max-height:0;padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;transition-property:opacity;-moz-transition-duration:.3s;-webkit-transition-duration:.3s;-o-transition-duration:.3s;transition-duration:.3s;-moz-transition-timing-function:cubic-bezier(0,1,.5,1);-webkit-transition-timing-function:cubic-bezier(0,1,.5,1);-o-transition-timing-function:cubic-bezier(0,1,.5,1);transition-timing-function:cubic-bezier(0,1,.5,1);opacity:0}.lasso-editor-toolbar-show{transition-property:opacity;-moz-transition-duration:.3s;-webkit-transition-duration:.3s;-o-transition-duration:.3s;transition-duration:.3s;-moz-transition-timing-function:ease-in;-webkit-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;max-height:1000px;opacity:1;width:auto!important}.lasso-editor-toolbar-fixed{position:fixed}.lasso-editor-focused{transition:all 500ms ease-in-out 0s;-moz-box-shadow:0 0 3px 4px rgba(0,0,0,.2);-webkit-box-shadow:0 0 3px 4px rgba(0,0,0,.2);box-shadow:0 0 3px 4px rgba(0,0,0,.2)}#lasso--pagerefresh{padding:15px;background:#4da34d;color:#fff;font-size:14px;line-height:18.2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#aesop-generator-settings .aesop-chapter-title{left:0}.lasso--toolbar_wrap{width:auto;left:50%;-webkit-transform:translate(-50%,0);-ms-transform:translate(-50%,0);transform:translate(-50%,0)}.lasso-editor-controls--wrap{color:#e2e2e2;border:1px solid #181b1f;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);height:39px;font-size:16px;border-radius:4px;position:fixed;text-align:center;bottom:20px;z-index:9999}.lasso-editor-controls--wrap *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.lasso-editor-controls{margin:0;padding:0;letter-spacing:0;list-style:none;height:39px;line-height:1}ul.lasso-editor-controls:before,ul.lasso-editor-controls:after{content:\" \";display:table}ul.lasso-editor-controls:after{clear:both}ul.lasso-editor-controls li{height:37px;position:relative;float:left;padding:0 8px;border-right:1px solid #23282d;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4);line-height:1;margin:0}ul.lasso-editor-controls li:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease;position:relative;top:10px}ul.lasso-editor-controls li:first-child:hover{border-top-left-radius:4px;border-bottom-left-radius:4px}ul.lasso-editor-controls li:last-child{border-right:0}ul.lasso-editor-controls li:last-child:hover{border-top-right-radius:4px;border-bottom-right-radius:4px}ul.lasso-editor-controls li:hover{cursor:pointer;background:#39424a}ul.lasso-editor-controls li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4)}#lasso-toolbar--bold:before{content:'\\ea62'}#lasso-toolbar--italic:before{content:'\\ea64'}#lasso-toolbar--underline:before{content:'\\ea63'}#lasso-toolbar--strike:before{content:'\\ea65'}#lasso-toolbar--link:before{content:'\\e9cb'}#lasso-toolbar--ol:before{content:\"\\e9b9\";top:9px;font-size:18px;letter-spacing:.05em}#lasso-toolbar--ul:before{content:\"\\e9bc\";top:9px;font-size:18px;letter-spacing:.05em}#lasso-toolbar--h2:before{content:'H2';top:9px;font-size:18px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--h3:before{content:'H3';top:9px;font-size:18px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--h4:before{content:'H4';top:9px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--h5:before{content:'H5';top:9px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--h6:before{content:'H6';top:9px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--html:before{content:'\\ea7f'}#lasso-toolbar--components:before{content:'\\ea0a'}#lasso-toolbar--color-set:before{content:'A';font-weight:700;letter-spacing:.05em}#lasso-toolbar--color-pick:before{content:'\\f100';font-family:Dashicons}#lasso-toolbar--left-align:before{content:'\\f206';font-family:Dashicons}#lasso-toolbar--center-align:before{content:'\\f207';font-family:Dashicons}#lasso-toolbar--right-align:before{content:'\\f208';font-family:Dashicons}#lasso-toolbar--html #lasso-toolbar--html__wrap{position:absolute;left:-10000px;opacity:0;filter:alpha(opacity=0)}#lasso-toolbar--html.html--drop-down,#lasso-toolbar--html.html--drop-up{box-shadow:none;background:#39424a}#lasso-toolbar--html.html--drop-down *,#lasso-toolbar--html.html--drop-up *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap{margin:0;padding:4px;opacity:1;filter:alpha(opacity=100);list-style-type:none;width:340px;height:228px;bottom:45px;border-radius:4px;left:-154px;background:#353c44}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap:after{content:'';position:absolute;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #39424a;left:0;right:0;bottom:-6px;text-align:center;margin:0 auto}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:hover,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap:hover{cursor:default}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner{background:#23282d;color:#e2e2e2;height:130px;overflow:scroll;text-align:left;line-height:1.25;padding:8px;border-radius:2px;font-family:monospace;white-space:pre;font-size:14px;-webkit-box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25);box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner:empty:before,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner:empty:before{content:attr(placeholder);color:rgba(226,226,226,.5)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner:hover,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner:hover{cursor:text}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner:focus,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner:focus{outline:0}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer{text-align:right;font-family:Arial;padding:7px 2px 2px;height:90px}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer a,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer a{font-size:14px;font-weight:700;padding:5px 7px 4px;line-height:1;border-radius:2px;display:inline-block;text-decoration:none;color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.4)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__insert,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__insert{background:#007aab}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__insert:hover,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__insert:hover{background:#006187}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__insert:active,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__insert:active{background:#004764;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer .lasso-toolbar--html__cancel,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer .lasso-toolbar--html__cancel{color:#d9534f}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__footer_desc,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__footer_desc{text-align:left;color:#fff;font-size:14px}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips{font-size:12px;line-height:0;float:left;margin:0;padding-left:0;list-style:none}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips:before,#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips:after{content:\" \";display:table}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips:after{clear:both}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips li{line-height:0;height:25px;margin-right:4px;border:0;border:1px solid #1f2327;border-radius:4px;-webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,.05);box-shadow:inset 1px 1px 0 rgba(255,255,255,.05)}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips li:before{top:5px}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips li:last-child{border-right:1px solid #1f2327}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips #lasso-html--h2:before{content:'H2'}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips #lasso-html--h3:before{content:'H3'}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips #lasso-html--ul:before{content:'UL'}#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips #lasso-html--ol:before{content:'OL'}#lasso-side-comp-button ul,#lasso-toolbar--components ul{position:absolute;left:-10000px;opacity:0;filter:alpha(opacity=0)}#lasso-side-comp-button.toolbar--drop-down,#lasso-toolbar--components.toolbar--drop-down,#lasso-side-comp-button.toolbar--drop-up,#lasso-toolbar--components.toolbar--drop-up,#lasso-side-comp-button.toolbar--side,#lasso-toolbar--components.toolbar--side{box-shadow:none}#lasso-side-comp-button.toolbar--drop-down *,#lasso-toolbar--components.toolbar--drop-down *,#lasso-side-comp-button.toolbar--drop-up *,#lasso-toolbar--components.toolbar--drop-up *,#lasso-side-comp-button.toolbar--side *,#lasso-toolbar--components.toolbar--side *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso-side-comp-button.toolbar--drop-down ul,#lasso-toolbar--components.toolbar--drop-down ul,#lasso-side-comp-button.toolbar--drop-up ul,#lasso-toolbar--components.toolbar--drop-up ul,#lasso-side-comp-button.toolbar--side ul,#lasso-toolbar--components.toolbar--side ul{margin:0;padding:4px;opacity:1;filter:alpha(opacity=100);list-style-type:none;width:304px;height:auto;top:-92px;border-radius:4px;left:-136px;line-height:0;column-gap:0}#lasso-side-comp-button.toolbar--drop-down ul:after,#lasso-toolbar--components.toolbar--drop-down ul:after,#lasso-side-comp-button.toolbar--drop-up ul:after,#lasso-toolbar--components.toolbar--drop-up ul:after,#lasso-side-comp-button.toolbar--side ul:after,#lasso-toolbar--components.toolbar--side ul:after{content:'';position:absolute;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #39424a;left:0;right:0;bottom:-6px;text-align:center;margin:0 auto}#lasso-side-comp-button.toolbar--drop-down ul li,#lasso-toolbar--components.toolbar--drop-down ul li,#lasso-side-comp-button.toolbar--drop-up ul li,#lasso-toolbar--components.toolbar--drop-up ul li,#lasso-side-comp-button.toolbar--side ul li,#lasso-toolbar--components.toolbar--side ul li{line-height:0;text-align:center;position:relative;font-size:20px;text-shadow:0 1px 1px rgba(0,0,0,.4);border-right:0;margin:1px;padding:2px;height:36px;width:40px;background:0 0;border-left:1px solid rgba(255,255,255,.1);border-top:1px solid rgba(255,255,255,.1);-webkit-box-shadow:1px 1px 0 rgba(0,0,0,.3);box-shadow:1px 1px 0 rgba(0,0,0,.3)}#lasso-side-comp-button.toolbar--drop-down ul li:before,#lasso-toolbar--components.toolbar--drop-down ul li:before,#lasso-side-comp-button.toolbar--drop-up ul li:before,#lasso-toolbar--components.toolbar--drop-up ul li:before,#lasso-side-comp-button.toolbar--side ul li:before,#lasso-toolbar--components.toolbar--side ul li:before{top:6px}#lasso-side-comp-button.toolbar--drop-down ul li:hover,#lasso-toolbar--components.toolbar--drop-down ul li:hover,#lasso-side-comp-button.toolbar--drop-up ul li:hover,#lasso-toolbar--components.toolbar--drop-up ul li:hover,#lasso-side-comp-button.toolbar--side ul li:hover,#lasso-toolbar--components.toolbar--side ul li:hover{cursor:move;background:#23282d;border-radius:0}#lasso-side-comp-button.toolbar--drop-down ul li.active,#lasso-toolbar--components.toolbar--drop-down ul li.active,#lasso-side-comp-button.toolbar--drop-up ul li.active,#lasso-toolbar--components.toolbar--drop-up ul li.active,#lasso-side-comp-button.toolbar--side ul li.active,#lasso-toolbar--components.toolbar--side ul li.active,#lasso-side-comp-button.toolbar--drop-down ul li:active,#lasso-toolbar--components.toolbar--drop-down ul li:active,#lasso-side-comp-button.toolbar--drop-up ul li:active,#lasso-toolbar--components.toolbar--drop-up ul li:active,#lasso-side-comp-button.toolbar--side ul li:active,#lasso-toolbar--components.toolbar--side ul li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4);background:#1a1e22}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__wpimg:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__wpimg:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__wpimg:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__wpimg:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__wpimg:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__wpimg:before,#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__image:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__image:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__image:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__image:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__image:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__image:before{content:\"\\e90f\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__character:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__character:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__character:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__character:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__character:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__character:before{content:\"\\e971\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__wpquote:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__wpquote:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__wpquote:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__wpquote:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__wpquote:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__wpquote:before,#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__quote:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__quote:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__quote:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__quote:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__quote:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__quote:before{content:\"\\e977\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__content:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__content:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__content:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__content:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__content:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__content:before{content:\"\\ea78\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__chapter:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__chapter:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__chapter:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__chapter:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__chapter:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__chapter:before{content:\"\\e91f\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__parallax:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__parallax:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__parallax:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__parallax:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__parallax:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__parallax:before{content:\"\\ea6e\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__audio:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__audio:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__audio:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__audio:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__audio:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__audio:before{content:\"\\e910\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__wpvideo:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__wpvideo:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__wpvideo:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__wpvideo:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__wpvideo:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__wpvideo:before,#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__video:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__video:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__video:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__video:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__video:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__video:before{content:\"\\e913\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__map:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__map:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__map:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__map:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__map:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__map:before{content:\"\\e947\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__timeline:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__timeline:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__timeline:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__timeline:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__timeline:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__timeline:before{content:\"\\e94e\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__document:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__document:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__document:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__document:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__document:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__document:before{content:\"\\e926\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__collection:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__collection:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__collection:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__collection:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__collection:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__collection:before{content:\"\\e920\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__gallery:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__gallery:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__gallery:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__gallery:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__gallery:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__gallery:before{content:\"\\e90e\"}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__gallerypop:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__gallerypop:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__gallerypop:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__gallerypop:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__gallerypop:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__gallerypop:before{content:\"\\f211\";font-family:Dashicons}#lasso-side-comp-button.toolbar--drop-down ul li.lasso-toolbar--component__event:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__event:before,#lasso-side-comp-button.toolbar--drop-up ul li.lasso-toolbar--component__event:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__event:before,#lasso-side-comp-button.toolbar--side ul li.lasso-toolbar--component__event:before,#lasso-toolbar--components.toolbar--side ul li.lasso-toolbar--component__event:before{content:\"\\f145\";font-family:Dashicons}#lasso-toolbar--link *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso-toolbar--link #lasso-toolbar--link__wrap{position:absolute;left:-10000px;opacity:0;filter:alpha(opacity=0)}#lasso-toolbar--link.link--drop-down,#lasso-toolbar--link.link--drop-up{box-shadow:none;background:#39424a}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap{margin:0;padding:4px;opacity:1;filter:alpha(opacity=100);list-style-type:none;width:300px;height:70px;bottom:45px;border-radius:4px;left:-134px;background:#353c44}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap:after{content:'';position:absolute;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #39424a;left:0;right:0;bottom:-6px;text-align:center;margin:0 auto}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:hover,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap:hover{cursor:default}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner{background:#23282d;color:#e2e2e2;height:32px;white-space:nowrap;overflow:hidden;text-align:left;line-height:1.25;padding:8px;border-radius:2px;font-family:monospace;font-size:14px;-webkit-box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25);box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25)}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:empty:before,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:empty:before{content:attr(placeholder);color:rgba(226,226,226,.5)}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:after,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:after{content:'';height:20px;width:20px;position:absolute;background:#23282d;border-top-right-radius:2px;border-bottom-right-radius:2px;right:4px;top:4px;height:32px;width:36px}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:hover,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:hover{cursor:text}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:focus,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:focus{outline:0}#lasso-toolbar--link .lasso-toolbar--link__control{position:absolute;top:9px;right:5px;width:25px;font-family:Arial;font-size:12px;font-weight:700;padding:5px 7px 4px;line-height:1;border-radius:2px;display:inline-block;text-decoration:none;color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.4);background:#007aab}#lasso-toolbar--link .lasso-toolbar--link__control:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\ea10'}#lasso-toolbar--link .styled-checkbox{position:absolute;top:45px;left:8px}#lasso-toolbar--link label{position:absolute;top:45px;left:41px;font-family:Arial;color:#fff;font-size:12px}.ase-not-active #lasso-toolbar--components #lasso-toolbar--components__list{width:94px;left:calc(50% - 94px / 2);height:48px;top:-55px!important}#lasso-toolbar--components__list,#lasso-toolbar--link__wrap,#lasso-toolbar--html__wrap,.iris-picker{z-index:10000}#lasso-side-comp-button.toolbar--side{background:0 0}#lasso-side-comp-button:before{content:\"\\f502\";font-family:dashicons;display:inline-block;font-weight:400;font-size:30px}#lasso-side-comp-button li{float:left}#lasso-side-comp-button ul:after{content:none!important}#lasso-side-comp-button li:before{font-family:icomoon-editus;display:inline-block;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease;position:relative;top:10px}@media print{#lasso--controls{display:none}}#lasso--controls .lasso--controls__center{display:block}.lasso--controls__center{width:auto;left:50%;-webkit-transform:translate(-50%,0);-ms-transform:translate(-50%,0);transform:translate(-50%,0)}.lasso--controls__center li{list-style-type:none;line-height:0}.lasso--controls__right{position:fixed;right:-10000px;bottom:20px;z-index:9999;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;transition:opacity .3s ease;text-align:right}.lasso--controls__right a{display:inline-block;vertical-align:bottom;color:#e2e2e2;font-family:Arial;font-style:normal;font-size:20px;padding:0 8px;border-radius:3px;height:39px;width:43px;line-height:38px;text-align:center;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--controls__right a:hover,.lasso--controls__right a:active,.lasso--controls__right a:focus,.lasso--controls__right a:focus:before,.lasso--controls__right a:active:before{color:#e2e2e2;text-decoration:none}.lasso--controls__right a:before{color:#fff;font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso--controls__right a:focus{outline:0}#lasso--edit{border-top-left-radius:3px;border-bottom-left-radius:3px}#lasso--edit:before{content:'\\e908'}#lasso--post-settings:before{content:'\\f031'}#lasso--post-new:before{content:'\\e603'}#lasso--post-revisions:before{content:'\\e94d'}#lasso--post-all:before{content:'\\e9ba';font-size:15px;top:11px}#lasso--post-settings2,#lasso--post-delete{background:#007aab;font-size:22px}#lasso--post-settings2:before,#lasso--post-delete:before{position:relative;top:3px;left:0;width:28px;height:28px}#lasso--post-settings2:hover,#lasso--post-delete:hover{background:#005678}#lasso--post-settings2:active,#lasso--post-delete:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--post-settings2:before{content:'\\f031'}#lasso--post-delete:before{content:'\\E9AD'}#lasso--save{background:#007aab;font-size:22px}#lasso--save:before{position:relative;top:5px;left:0;width:28px;height:28px;content:'\\e601'}#lasso--save:hover{background:#005678}#lasso--save:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--save.being-saved:before{content:'\\e97f';top:4px;width:22px;height:22px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#lasso--save.lasso--saved{background:#4da34d}#lasso--save.lasso--saved:before{top:2px;content:'\\ea10'}#lasso--save.lasso--error{background:#d9534f}#lasso--save.lasso--error:before{content:'\\ea05'}#lasso--exit{background:#f0ad4e;float:left}#lasso--exit:before{position:relative;top:3px;content:'\\ea0f'}#lasso--publish{background:#4da34d}#lasso--publish:before{content:'\\e909';position:relative;top:2px}.lasso-editing #lasso--controls .lasso-editor-controls,.lasso-editing #lasso--post-settings,.lasso-editing #lasso--edit{opacity:0;filter:alpha(opacity=0);position:absolute;left:-10000px}.lasso-editing .lasso--controls__right{opacity:1;filter:alpha(opacity=100);right:20px;left:20px}.lasso-editing .wp-audio-shortcode{visibility:visible!important}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.lasso--btn-primary{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:0;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none}.lasso--btn-primary:active,.lasso--btn-primary:focus{outline:0}.lasso--btn-primary:hover{text-decoration:none;color:#fff;background:#005678}.lasso--btn-primary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-secondary{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;font-size:17px;line-height:1.8;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--btn-secondary:active,.lasso--btn-secondary:visited{color:#e2e2e2}.lasso--btn-secondary:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}.lasso--btn-secondary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-secondary.lasso--btn-loading:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.lasso--btn-secondary:active,.lasso--btn-secondary:visited{color:#e2e2e2}.lasso--btn-secondary:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}.lasso--btn-secondary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-secondary.lasso--btn-loading:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.lasso--post-form label{font-size:14px;line-height:1;margin-bottom:8px;display:block;font-family:Arial}.lasso--post-form label .lasso-icon-help{margin-left:5px;position:relative;top:2px}.lasso--post-form input[type=text]{background-color:#f8f8f8!important;padding:2px 8px;background:#f8f8f8;border:1px solid #181b1f;color:#444;font-size:14px;z-index:0;position:relative;padding-left:6px;height:36px;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4)}.lasso--post-form input[type=text]:focus{outline:0;border:1px solid #007aab;border-radius:2px}.lasso--post-form .checkbox_label{display:inline-block}.lasso--post-form .checkbox-control{position:relative;display:inline-block;padding-left:28px;cursor:pointer;top:2px}.lasso--post-form .checkbox-control input{position:absolute;opacity:0;z-index:-1}.lasso--post-form .checkbox-control input:checked~.control-indicator{color:#f8f8f8;background-color:#007aab}.lasso--post-form .checkbox-control input:active~.control-indicator{color:#f8f8f8;background-color:#007aab}.lasso--post-form .control-indicator{position:absolute;top:-1px;left:0;display:block;width:18px;height:18px;line-height:1rem;font-size:65%;color:#f8f8f8;text-align:center;background-color:#f8f8f8;background-size:50% 50%;background-position:center center;background-repeat:no-repeat;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.lasso--post-form .checkbox .control-indicator{border-radius:.25rem}.lasso--post-form .checkbox input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTYuNCwxTDUuNywxLjdMMi45LDQuNUwyLjEsMy43TDEuNCwzTDAsNC40bDAuNywwLjdsMS41LDEuNWwwLjcsMC43bDAuNy0wLjdsMy41LTMuNWwwLjctMC43TDYuNCwxTDYuNCwxeiINCgkvPg0KPC9zdmc+DQo=)}.lasso--post-form .radio .control-indicator{border-radius:50%}.lasso--post-form .radio input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQsMUMyLjMsMSwxLDIuMywxLDRzMS4zLDMsMywzczMtMS4zLDMtM1M1LjcsMSw0LDF6Ii8+DQo8L3N2Zz4NCg==)}.lasso--post-form .control-x input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0xLjQsMEwwLDEuNGwwLjcsMC43bDEuOCwxLjhMMC43LDUuN0wwLDYuNGwxLjQsMS40bDAuNy0wLjdsMS44LTEuOGwxLjgsMS44bDAuNywwLjdsMS40LTEuNEw3LjEsNS43DQoJTDUuMywzLjlsMS44LTEuOGwwLjctMC43TDYuNCwwTDUuNywwLjdMMy45LDIuNUwyLjEsMC43QzIuMSwwLjcsMS40LDAsMS40LDB6Ii8+DQo8L3N2Zz4NCg==)}.lasso--post-form .control-dash input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0wLDN2Mmg4VjNIMHoiLz4NCjwvc3ZnPg0K)}.lasso--post-form #lasso--postsettings-setnow,.lasso--post-form .lasso--postsettings-cancel{background:0 0;color:#d9534f;position:relative;top:3px}.lasso--post-form #lasso--postsettings-setnow:hover,.lasso--post-form .lasso--postsettings-cancel:hover{color:#d43f3a;text-decoration:none}.lasso--post-form #lasso--postsettings-setnow{font-size:16px}.lasso--post-form input[type=submit]{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:0;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none;float:right}.lasso--post-form input[type=submit]:active,.lasso--post-form input[type=submit]:focus{outline:0}.lasso--post-form input[type=submit]:hover{text-decoration:none;color:#fff;background:#005678}.lasso--post-form input[type=submit]:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-group{text-align:center}.lasso--btn-group a{margin:0;display:inline-block}.lasso--btn-group.lasso--btn-group-small a{font-size:14px}.lasso--notice{text-align:center;max-width:500px;padding:10px;color:#fff;font-family:Arial;font-size:14px;margin:10px auto}.lasso--notice.lasso--notice-warning{background:#f0ad4e}.lasso--notice.lasso--notice-info{background:#007aab}.lasso--notice.lasso--notice-error{background:#d9534f}.lasso--notice.lasso--notice-success{background:#4da34d}#lasso--slider{position:relative;text-align:left;background:#32373c;top:5px;height:10px;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.2);box-shadow:inset 1px 1px 1px rgba(0,0,0,.2)}#lasso--slider .ui-slider-handle{position:absolute;z-index:2;width:22px;height:22px;cursor:default;-ms-touch-action:none;touch-action:none;background:#007aab;top:-6px;margin-left:-11px;border-radius:100%;-webkit-box-shadow:0 0 7px -1px rgba(0,0,0,.75);box-shadow:0 0 7px -1px rgba(0,0,0,.75)}#lasso--slider .ui-slider-handle:focus,#lasso--slider .ui-slider-handle:active{outline:0}#lasso--slider .ui-slider-handle:hover,#lasso--slider .ui-slider-handle:active{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.5);box-shadow:inset 0 0 6px rgba(0,0,0,.5)}#lasso--slider .ui-slider-handle:hover{border:4px solid #007aab}#lasso--slider .ui-slider-handle:active{border:4px solid #006f9c}#lasso--slider .ui-slider-handle:hover,#lasso--slider .ui-slider-handle:focus,#lasso--slider .ui-slider-handle:active{cursor:move}.lasso--select-wrap{position:relative;display:inline-block;color:#444}.lasso--select-wrap select{display:inline-block;width:100%;margin:0;line-height:30px;color:#e2e2e2;background-color:#32373c;border:0;padding:2px 25px 2px 12px;border-radius:4px;cursor:pointer;outline:0;font-size:15px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.lasso--select-wrap select:focus:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.lasso--select-wrap:after{position:absolute;top:50%;right:12px;display:inline-block;content:\"\";width:0;height:0;margin-top:-.15rem;pointer-events:none;border-top:4px solid #e2e2e2;border-right:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid transparent}.lasso--select-wrap select:active{color:#444;background-color:#32373c}.lasso--select-wrap select::-ms-expand{display:none}@-moz-document url-prefix(){select{text-indent:.01px;text-overflow:'';padding-right:1rem}option{background-color:#fff}}.lasso-modal-open{overflow:hidden}#lasso--modal__overlay{z-index:9999;position:fixed;left:0;top:0;right:0;bottom:0;background:rgba(255,255,255,.85)}.lasso--modal{z-index:100001;position:fixed;display:table;top:33vh;left:0;right:0;bottom:0;width:100%;max-width:381px;margin:0 auto;font-family:Arial}.lasso--modal *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso--modal__inner{display:table-cell;vertical-align:middle;background:#23282d;border-radius:4px;border:1px solid #0d0e10;padding:18px;-webkit-box-shadow:0 0 10px 1px rgba(0,0,0,.5);box-shadow:0 0 10px 1px rgba(0,0,0,.5);color:#e2e2e2;position:relative}.lasso--modal__inner:before,.lasso--modal__inner:after{content:\" \";display:table}.lasso--modal__inner:after{clear:both}.lasso--modal__inner label{color:#fff}#lasso--modal__close{position:absolute;right:20px;top:10px}#lasso--modal__close:hover{cursor:pointer}.lasso--slider_wrap{padding:0 10px;height:18px}.lasso--postsettings__option{padding-bottom:20px;margin-bottom:20px;position:relative;line-height:1;border-bottom:1px solid #0d0e10;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.05);box-shadow:0 1px 1px rgba(255,255,255,.05)}.lasso--postsettings__option.lasso--last-option{border-bottom:0;margin-bottom:0;padding-bottom:0}.lasso--postsettings__option .story-status{margin:12px 0 8px;padding:0 10px;line-height:1;display:table;width:100%}.lasso--postsettings__option .story-status:before,.lasso--postsettings__option .story-status:after{content:\" \";display:table}.lasso--postsettings__option .story-status:after{clear:both}.lasso--postsettings__option .story-status li{font-size:14px;list-style-type:none;display:table-cell}.lasso--postsettings__option .story-status.story-status-publish #lasso--status-draft{opacity:.3;filter:alpha(opacity=30)}.lasso--postsettings__option .story-status.story-status-draft #lasso--status-publish{opacity:.3;filter:alpha(opacity=30)}.lasso--postsettings__option .story-status #lasso--status-pending{text-align:center}.lasso--postsettings__option .story-status #lasso--status-publish{float:right;text-align:right}.lasso--postsettings__option.story-slug-option .lasso--select-wrap{position:absolute;top:24px;left:1px}.lasso--postsettings__option.story-slug-option .lasso--select-wrap select{font-size:13px;border-radius:1px 0 0 1px}.lasso--postsettings__option.story-slug-option+.lasso--postsettings__footer{margin-top:inherit;padding-top:inherit;padding-to:20px;margin-top:20px}.lasso--postsettings__option+.lasso--postsettings__footer{border-top:0;box-shadow:none;margin-top:0;padding-top:0}.lasso--postsettings__footer{text-align:right;font-size:16px;padding-top:20px;margin-top:22px;border-top:1px solid #0d0e10;-webkit-box-shadow:0 -1px 1px rgba(255,255,255,.05);box-shadow:0 -1px 1px rgba(255,255,255,.05)}.lasso--postsettings__footer a,.lasso--postsettings__footer input{display:inline-block}#lasso--postnew__form .story-slug-option{margin-bottom:0}#lasso--postnew__form .story-slug-option #lasso--select-type{height:35px}#lasso--postnew__form .lasso--modal__trigger-footer{left:90px;width:260px}.lasso--modal__tabs{position:absolute;right:0;top:-36px;padding:0;margin:0;height:36px;list-style:none}.lasso--modal__tabs li{display:inline-block;background:#32373c;font-size:15px;border-top-left-radius:4px;border-top-right-radius:4px;padding:0 10px;margin:0 1px;height:36px;line-height:36px;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}.lasso--modal__tabs li.active-tab,.lasso--modal__tabs li:hover{cursor:pointer;background:#23282d}.lasso--modal__tabs li:last-child{margin-right:-1px}.lasso--modal__content #poststuff{min-width:1px}#lasso--post-settings__modal{max-width:600px}.lasso--postsettings__2col:before,.lasso--postsettings__2col:after{content:\" \";display:table}.lasso--postsettings__2col:after{clear:both}.lasso--postsettings__2col .lasso--postsettings__left,.lasso--postsettings__2col .lasso--postsettings__right{float:left}.lasso--postsettings__2col .lasso--postsettings__left{width:35%}.lasso--postsettings__2col .lasso--postsettings__left label{font-size:14px;line-height:1;display:block;margin-bottom:15px}.lasso--postsettings__2col .lasso--postsettings__left .lasso-util--help{left:6px;top:2px}.lasso--postsettings__2col .lasso--postsettings__right{width:62%;margin-left:3%}.story-tags-option,.story-slug-option{border-bottom:0;box-shadow:none;padding-bottom:0}.lasso--postsettings__middle{clear:left;padding-top:20px;border-top:1px solid #0d0e10;-webkit-box-shadow:inset 0 1px 1px rgba(255,255,255,.05);box-shadow:inset 0 1px 1px rgba(255,255,255,.05)}.lasso--post-thumb{position:relative}.lasso--post-thumb .lasso--post-thumb__controls{position:absolute;top:10px;left:10px;right:10px;z-index:1}.lasso--post-thumb .lasso--post-thumb__controls i{text-shadow:0 1px 1px rgba(0,0,0,.5);opacity:.6;filter:alpha(opacity=60);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease}.lasso--post-thumb .lasso--post-thumb__controls i:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100);-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.lasso--post-thumb .lasso--post-thumb__controls i:active{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);box-shadow:none}.lasso--post-thumb .lasso--post-thumb__controls #lasso--post-thumb__add{font-size:16px;top:2px;margin-right:-4px;position:relative}.lasso--post-thumb .lasso--post-thumb__controls #lasso--save-status{float:right;font-size:16px;position:relative;top:3px;right:3px;color:#4da34d}.lasso--post-thumb img{border:5px solid rgba(50,55,60,.75);border-radius:4px;width:196px;height:136px}#lasso--postsettings__form.no-thumbnail #lasso--post-thumb__delete{opacity:0;filter:alpha(opacity=0);display:none;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease}#lasso--custom-taxo-select{padding-top:1px;padding-bottom:1px;font-size:15px}.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-ms-filter:\"alpha(Opacity=0)\";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;bottom:3px;height:8px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#32373c;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;bottom:0;height:8px}.ps-container>.ps-scrollbar-x-rail.in-scrolling{background-color:transparent;opacity:.9;-ms-filter:\"alpha(Opacity=90)\";filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-ms-filter:\"alpha(Opacity=0)\";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;right:3px;width:8px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#32373c;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;right:0;width:8px}.ps-container>.ps-scrollbar-y-rail.in-scrolling{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6;filter:alpha(opacity=60)}.ps-container:hover>.ps-scrollbar-x-rail.in-scrolling,.ps-container:hover>.ps-scrollbar-y-rail.in-scrolling{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}.lasso-sidebar-open{overflow:hidden}.lasso-sidebar-open .lasso-buttoninsert-wrap,.lasso-sidebar-open #lasso--sidebar{right:0}#lasso--sidebar{z-index:9999;position:fixed;right:-285px;top:0;bottom:0;width:285px;-webkit-transition:right .25s ease;-moz-transition:right .25s ease;transition:right .25s ease}#lasso--sidebar *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso--sidebar label,#lasso--sidebar p{color:#e2e2e2;background:#23282d}#lasso--sidebar code{color:#e2e2e2;background:#23282d}.admin-bar #lasso--sidebar{top:32px}.admin-bar #lasso--component__settings form{padding-bottom:102px}.lasso--sidebar__inner{height:100%;font-family:Arial;font-size:14px;background:#23282d;border-left:4px solid #353c44;color:#e2e2e2;text-shadow:0 1px 1px rgba(0,0,0,.4);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-box-shadow:inset 9px 0 9px -9px #000;box-shadow:inset 9px 0 9px -9px #000}.lasso--sidebar__inner #lasso--sidebar__close{color:#007aab}.lasso--sidebar__inner #lasso--component__settings{overflow:hidden;position:relative}#lasso--sidebar__drag{height:100px;width:50px;background:red;top:50%;bottom:0;position:absolute}ul.lasso-component--controls{color:#e2e2e2;border:1px solid #181b1f;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);position:absolute;margin:0;padding:0;line-height:1;height:26px;width:121px;top:4px;text-align:center;margin:0 auto;border-radius:2px;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .4s ease;-moz-transition:opacity .4s ease;transition:opacity .4s ease;z-index:105;padding-left:0}ul.lasso-component--controls *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.lasso-component--controls:before,ul.lasso-component--controls:after{content:\" \";display:table}ul.lasso-component--controls:after{clear:both}ul.lasso-component--controls.editus-center{left:0;right:0}ul.lasso-component--controls.editus-right{right:0}ul.lasso-component--controls li{float:left;list-style-type:none;line-height:1;margin:0;width:29.51219512px;height:24px;border-right:1px solid #23282d;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4)}ul.lasso-component--controls li:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:relative;top:1px;font-size:15px}ul.lasso-component--controls li:first-child:hover{border-bottom-left-radius:2px;border-top-left-radius:2px}ul.lasso-component--controls li:hover{cursor:pointer;background:#39424a}ul.lasso-component--controls li:active{-webkit-box-shadow:inset 0 0 6px -2px rgba(0,0,0,.66);box-shadow:inset 0 0 6px -2px rgba(0,0,0,.66)}ul.lasso-component--controls li:last-child{border-right:0}ul.lasso-component--controls li:last-child:hover{border-top-right-radius:2px;border-bottom-right-radius:2px}ul.lasso-component--controls li.lasso-drag{cursor:move}ul.lasso-component--controls li.lasso-drag:hover{cursor:move}ul.lasso-component--controls li.lasso-drag:before{content:'\\e600'}ul.lasso-component--controls li.lasso-settings:before{content:'\\e994'}ul.lasso-component--controls li.lasso-clone:before{content:'\\e92c'}ul.lasso-component--controls li.lasso-delete:before{content:'\\e9ad'}.lasso-editing .aesop-component:hover .lasso-component--controls,.lasso-editing .wp-block-cover:hover .lasso-component--controls{left:4px;opacity:1;filter:alpha(opacity=100)}.aesop-timeline-stop .lasso-component--controls li{line-height:16px}.aesop-image-component[data-align=right]:hover .lasso-component--controls,.aesop-image-component[data-align=left]:hover .lasso-component--controls{margin:13px 0 0 4px}.aesop-image-component[data-align=right]:hover .lasso-component--controls{left:auto}.lasso-component{position:relative}.editus_shortcode_p{position:relative}.editus_shortcode{color:#e2e2e2;border:1px solid #181b1f;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-transition:opacity .4s ease;-moz-transition:opacity .4s ease;transition:opacity .4s ease;margin:auto;text-align:center;width:200px;z-index:105;position:absolute;left:0;right:0;top:0;opacity:.5;border-radius:4px}.editus_shortcode_p:hover .editus_shortcode{opacity:1}@media (max-width:768){.editus_shortcode_p .editus_shortcode{opacity:1}}#lasso--component__settings form{margin:0;position:relative;padding-bottom:70px}#lasso--component__settings label,#lasso--component__settings .lasso-option-desc{display:block;line-height:1.3}#lasso--component__settings h3,#lasso--component__settings label{font-weight:700;margin-bottom:3px;font-size:14px}#lasso--component__settings .lasso-option-desc{margin-bottom:5px;font-size:11.25px}#lasso--component__settings input[type=text],#lasso--component__settings input[type=text_small],#lasso--component__settings input[type=media_upload],#lasso--component__settings textarea,#lasso--component__settings select{background:#f8f8f8;width:100%;height:30px;border:1px solid #181b1f;border-radius:4px;line-height:1.8;padding:0 6px;color:#444;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);font-size:14px}#lasso--component__settings input[type=text]:focus,#lasso--component__settings input[type=text_small]:focus,#lasso--component__settings input[type=media_upload]:focus,#lasso--component__settings textarea:focus,#lasso--component__settings select:focus{box-shadow:none;outline:0;border:1px solid #007aab}#lasso--component__settings input[type=color]{border-radius:3px;border:1px solid #181b1f;padding:0 2px;height:30px;display:block}#lasso--component__settings input[type=color]:active,#lasso--component__settings input[type=color]:focus{box-shadow:none;outline:0;border:1px solid #007aab}#lasso--component__settings select{height:30px;box-shadow:none}#lasso--component__settings textarea{overflow:auto;margin:0;line-height:1.15;padding:6px;height:auto}#lasso--component__settings input[type=media_upload]{height:30px}#lasso--component__settings input[type=submit],#lasso--component__settings .lasso-generator-cancel{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:0;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none;font-size:15px}#lasso--component__settings input[type=submit]:active,#lasso--component__settings .lasso-generator-cancel:active,#lasso--component__settings input[type=submit]:focus,#lasso--component__settings .lasso-generator-cancel:focus{outline:0}#lasso--component__settings input[type=submit]:hover,#lasso--component__settings .lasso-generator-cancel:hover{text-decoration:none;color:#fff;background:#005678}#lasso--component__settings input[type=submit]:active,#lasso--component__settings .lasso-generator-cancel:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--component__settings .lasso-option-button{position:absolute;bottom:21px;right:21px;background-color:#4b5661;border-color:#2c3238;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.25);box-shadow:0 1px 1px rgba(0,0,0,.25)}#lasso--component__settings .lasso-option-button:hover{text-decoration:none;background:#3e474f}#lasso--component__settings .lasso-option-button:active,#lasso--component__settings .lasso-option-button:focus{outline:0;text-decoration:none;border-color:#21252a;background:#353c44;transition:none;-webkit-box-shadow:inset 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px rgba(0,0,0,.4)}#lasso--component__settings #lasso-upload-img{height:28px;padding:8px;border-top-right-radius:3px;border-bottom-right-radius:3px;font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#lasso--component__settings #lasso-upload-img:before{content:'\\e9c6';position:relative;color:#f8f8f8}#lasso--component__settings .lasso-generator-cancel{background:0 0;color:#d9534f;position:relative;top:-1px}#lasso--component__settings .lasso-generator-cancel:hover{color:#db5b57;background:0 0;text-decoration:none}#lasso--component__settings .lasso-generator-cancel:active{color:#d74b47;box-shadow:none}.lasso-option{position:relative;border-bottom:1px solid #181b1f;margin:0;padding:15px 20px 20px;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.05);box-shadow:0 1px 1px rgba(255,255,255,.05);-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}.lasso-option:before,.lasso-option:after{content:\" \";display:table}.lasso-option:after{clear:both}.lasso-option:hover{background:rgba(53,60,68,.5)}.lasso-buttoninsert-wrap{display:none;margin:0 auto;position:fixed;text-align:right;padding:20px;bottom:0;width:281px;height:70px;background:#353c44;right:-289px;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:right .25s ease;-moz-transition:right .25s ease;transition:right .25s ease;-webkit-box-shadow:0 -10px 10px -10px #000;box-shadow:0 -10px 10px -10px #000}.lasso-buttoninsert-wrap:before,.lasso-buttoninsert-wrap:after{content:\" \";display:table}.lasso-buttoninsert-wrap:after{clear:both}#lasso-generator-insert{text-align:center;float:right;display:block;margin:0 15px;padding:6px 10px;border-radius:2px;background:#007aab;border:1px solid #006892;color:#fff}#lasso-generator-insert:hover{text-decoration:none;background:#005678}#lasso-generator-insert:active,#lasso-generator-insert:focus{text-decoration:none;outline:0}#lasso-generator-insert:active{background:#00435e;-webkit-box-shadow:inset 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px rgba(0,0,0,.4)}#lasso-generator-insert.saved{background:#4da34d}.lasso-c-comp-text{position:absolute;right:-10000px;opacity:0;filter:alpha(opacity=0);height:0}#lasso--gallery__images{min-height:65px;position:relative}#lasso--gallery__images .lasso-icon-spinner6{position:relative;left:135px;top:18px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;font-size:16px}.editor-btn-secondary{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;font-size:17px;line-height:1.8;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.editor-btn-secondary:active,.editor-btn-secondary:visited{color:#e2e2e2}.editor-btn-secondary:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}.editor-btn-secondary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.editor-btn-secondary.lasso--btn-loading:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#ase-gallery-images{margin:0 -7px;border-radius:4px;padding:2px;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}#ase-gallery-images:before,#ase-gallery-images:after{content:\" \";display:table}#ase-gallery-images:after{clear:both}#ase-gallery-images .ui-state-highlight{height:1.5em;line-height:1.2em}.ase-gallery-image{position:relative;float:left;margin:4px;-webkit-transition:transform .1s ease;-moz-transition:transform .1s ease;transition:transform .1s ease;list-style:none}.ase-gallery-image i{top:3px;position:absolute;z-index:1;color:#fff;font-size:16px;text-shadow:0 1px 1px rgba(0,0,0,.5);opacity:.6;filter:alpha(opacity=60);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease}.ase-gallery-image i:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100);-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.ase-gallery-image i:active{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);box-shadow:none}.ase-gallery-image .dashicons-edit{left:3px}.ase-gallery-image .dashicons-no-alt{right:2px}.ase-gallery-image img{max-width:54px;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.ase-gallery-image.ui-sortable-helper{-ms-transform:rotate(7deg);-webkit-transform:rotate(7deg);transform:rotate(7deg)}.ase-gallery-image:hover{cursor:move}.ase-gallery-image:hover img{opacity:.66;filter:alpha(opacity=66)}.ase-gallery-opts--edit-gallery:hover #ase-gallery-images{background:#181b1f;-webkit-box-shadow:inset 0 -1px 1px rgba(255,255,255,.1);box-shadow:inset 0 -1px 1px rgba(255,255,255,.1)}.lasso-editor-tiny-btn{font-size:10px;background:#181b1f;color:rgba(226,226,226,.8);border-radius:100%;font-weight:400;height:18px;width:18px;line-height:20px;text-align:center;text-shadow:1px 1px rgba(0,0,0,.1)}.lasso-editor-tiny-btn:focus,.lasso-editor-tiny-btn:active,.lasso-editor-tiny-btn:hover{outline:0;color:rgba(226,226,226,.8);text-decoration:none}.lasso-editor-tiny-btn:hover{color:rgba(226,226,226,.8);background:rgba(0,122,171,.8)}.lasso-editor-tiny-btn:active{color:rgba(226,226,226,.8);background:#007aab}#ase-gallery-add-image{position:absolute;right:12px;font-size:9px}.ase-gallery-drop-zone{border:1px solid #23282d;background:#353c44;color:#363636;width:54px;height:54px;float:left;margin:4px;border-radius:2px}#lasso--component__settings .ase-gallery-layout-label{font-size:12px}.ase-gallery-opts--type{position:relative}.ase-gallery-opts--type h3{margin:0}.ase-gallery-opts--type input[type=radio]{position:absolute;opacity:0;z-index:-1}.ase-gallery-opts--type .ase-gallery-layout-label{position:relative;float:left;height:68px;width:78px;overflow:hidden;text-align:center;background:#353c44;padding:5px;box-sizing:border-box;border:1px solid #181b1f;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;opacity:.3;filter:alpha(opacity=30);margin-right:2px;font-weight:400}.ase-gallery-opts--type .ase-gallery-layout-label:last-of-type{margin-right:0!important}.ase-gallery-opts--type .ase-gallery-layout-label:after{content:'';background-image:url(../img/layout-sprite.png);background-size:84%;position:absolute;height:42px;display:block;left:0;right:0;bottom:0}.ase-gallery-opts--type .ase-gallery-layout-label:hover{opacity:1;filter:alpha(opacity=100);cursor:pointer}.ase-gallery-opts--type .ase-gallery-layout-label:active{background:#2c3238;-webkit-box-shadow:inset 0 0 6px -1px rgba(0,0,0,.5);box-shadow:inset 0 0 6px -1px rgba(0,0,0,.5)}.ase-gallery-opts--type .selected{-webkit-box-shadow:inset 0 0 12px -2px rgba(0,0,0,.5);box-shadow:inset 0 0 12px -2px rgba(0,0,0,.5);opacity:1;filter:alpha(opacity=100)}.ase-gallery-opts--type label:first-of-type:after{background-position:5px -9px}.ase-gallery-opts--type label:nth-of-type(2):after{background-position:5px -52px}.ase-gallery-opts--type label:nth-of-type(3):after{background-position:5px -99px}.ase-gallery-opts--type label:nth-of-type(4):after{background-position:5px -145px}.ase-gallery-opts--type label:nth-of-type(5):after{background-position:5px -191px}.ase-gallery-opts--type label:last-of-type:after{background-position:5px -235px}.ase-gallery-opts{-webkit-transition:opacity .25s ease;-moz-transition:opacity .25s ease;transition:opacity .25s ease}.lasso--empty-component{height:0;opacity:0;filter:alpha(opacity=0);text-align:center;color:#444;font-family:Arial;font-size:20px;-webkit-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear}.lasso--empty-component span{position:relative;top:2px}.lasso-editing .lasso--empty-component+.aesop-map-component .lasso-component--controls,.lasso-editing .aesop-gallery-component.empty-gallery .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}.lasso-editing .lasso--empty-component{height:150px;padding-top:75px;opacity:1;filter:alpha(opacity=100)}#lasso--component__settings.gallery-no-images .ase-gallery-opts:not(.ase-gallery-opts--create-gallery){display:none}#lasso--component-settings-form.creating-gallery .lasso-option.lasso-gallery-id{display:none}#lasso--component-settings-form.has-galleries .ase-gallery-opts--create-gallery{display:none}#lasso--component-settings-form.hide-all-fields .ase-gallery-opts{opacity:0;filter:alpha(opacity=0)}#lasso--map-form{position:relative}#lasso--map-form .lasso--map-form__submit{position:absolute;top:10px;right:10px;z-index:1000;background:#007aab;border:1px solid #0073a1;padding:8px 12px;font-size:14px;line-height:1.2;font-family:Arial;text-shadow:1px 1px rgba(0,0,0,.1);-webkit-box-shadow:0 0 5px -1px rgba(0,0,0,.4);box-shadow:0 0 5px -1px rgba(0,0,0,.4)}#lasso--map-form .lasso--map-form__submit:active,#lasso--map-form .lasso--map-form__submit:focus{outline:0}#lasso--map-form .lasso--map-form__submit:hover{background:#005678;border:1px solid #004e6e}#lasso--map-form .lasso--map-form__submit:active{box-shadow:none}#lasso--map-form{margin-top:10px}#lasso--map-form .leaflet-popup-content-wrapper,#lasso--map-form .leaflet-popup-tip{border-radius:4px}#lasso--map-form .leaflet-popup-content-wrapper input,#lasso--map-form .leaflet-popup-tip input{font-size:14px;border-radius:0;padding:3px 5px;width:200px;display:inline-block;line-height:1}#lasso--map-form .leaflet-popup-content{margin:10px}#lasso--map-form .leaflet-popup-close-button{position:absolute;left:-10000px;height:0}#lasso--map-form .marker-update-button,#lasso--map-form .marker-delete-button{border-radius:0;color:#fff;box-shadow:none;border:0;border-radius:3px;display:inline-block;height:25px;width:25px;vertical-align:top;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;text-align:center}#lasso--map-form .marker-update-button:hover,#lasso--map-form .marker-delete-button:hover{cursor:pointer}#lasso--map-form .marker-update-button:active,#lasso--map-form .marker-delete-button:active{outline:0;focus:none;box-shadow:none}#lasso--map-form .marker-update-button:before,#lasso--map-form .marker-delete-button:before{position:relative;text-align:center}#lasso--map-form .marker-update-button{background:#007aab}#lasso--map-form .marker-update-button:hover{background:#00648c}#lasso--map-form .marker-update-button:active{background:#005678}#lasso--map-form .marker-update-button:before{top:1px;left:-1px;font-size:24px}#lasso--map-form .marker-delete-button{background:#d9534f}#lasso--map-form .marker-delete-button:hover{background:#d43a36}#lasso--map-form .marker-delete-button:active{background:#c9302c}#lasso--map-form .marker-delete-button:before{font-size:17px;top:1px;left:1px}.aesop-map-component .lasso-component--controls{width:91px;z-index:9999}.aesop-map-component .lasso-component--controls .lasso-clone{display:none}.aesop-sticky-map #lasso--map-form .lasso-component--controls{position:fixed;z-index:9999;width:61px}.aesop-sticky-map #lasso--map-form .lasso-component--controls .lasso-drag{display:none}.aesop-sticky-map.aesop-sticky-map-left #lasso--map-form .lasso-component--controls{left:183px;right:auto}.aesop-sticky-map.aesop-sticky-map-right #lasso--map-form .lasso-component--controls{right:183px;left:auto}#lasso--featImgControls{position:relative;z-index:1;left:0;right:0;text-align:center;top:5px;width:30px;height:26px;padding:0;margin:0 auto;font-size:15px;border-radius:2px;line-height:0;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--featImgControls.lasso--featImg--has-thumb{width:60px;padding:0}#lasso--featImgControls.lasso--featImg--has-thumb #lasso--featImgDelete{opacity:1;filter:alpha(opacity=100)}#lasso--featImgControls li{float:left;list-style-type:none;line-height:0;margin-left:0;width:30px;height:26px;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4)}#lasso--featImgControls li i{font-style:normal;position:relative;top:5px}#lasso--featImgControls li:before{position:relative;top:3px;font-size:15px}#lasso--featImgControls li:hover{cursor:pointer;background:#39424a}#lasso--featImgControls li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4)}#lasso--featImgControls .lasso--featImg--controlHidden{position:absolute;left:-1000px;height:0;opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls #lasso--featImgSave{position:absolute;left:-1000px;height:0;opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls #lasso--featImgDelete{opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls a{color:#fff;display:block}#lasso--featImgControls a:hover{text-decoration:none}.lasso--wpquote,.lasso--wpimg__wrap{position:relative}.lasso--wpquote:hover{opacity:1;filter:alpha(opacity=100);left:0}.lasso--wpimg__wrap:hover .lasso-component--controls,.lasso-component:hover .lasso-component--controls,.wp-block-image:hover .lasso-component--controls{opacity:1;filter:alpha(opacity=100)}.wp-block-image:hover .lasso-component--controls{position:relative}.lasso--wpquote .lasso-component--controls #lasso-component--settings__trigger{position:absolute;left:-10000px;height:0;opacity:0;filter:alpha(opacity=0);display:none}.sweet-overlay{background-color:rgba(0,0,0,.4);position:fixed;left:0;right:0;top:0;bottom:0;display:none;z-index:1000}.sweet-alert{background-color:#1f2327;font-family:Arial;width:478px;padding:17px;border-radius:5px;text-align:center;position:fixed;left:50%;top:50%;margin-left:-256px;margin-top:-200px;overflow:hidden;display:none;z-index:100002;-webkit-box-shadow:0 0 10px 1px rgba(0,0,0,.5);box-shadow:0 0 10px 1px rgba(0,0,0,.5)}@media all and (max-width:540px){.sweet-alert{width:auto;margin-left:0;margin-right:0;left:15px;right:15px}}.sweet-alert h2{color:#e2e2e2;font-size:30px;text-align:center;font-weight:600;text-transform:none;position:relative;margin:25px 0;padding:0;line-height:40px;display:block;font-family:inherit}.sweet-alert p{color:#e2e2e2;font-size:16px;text-align:center;font-weight:300;position:relative;text-align:inherit;float:none;margin:0;padding:0;line-height:normal}.sweet-alert p~button{margin-bottom:20px}.sweet-alert button{background-color:#007aab;color:#fff;border:0;box-shadow:none;font-size:17px;font-family:Arial;font-weight:500;border-radius:5px;padding:10px 32px;margin:26px 5px 0;cursor:pointer}.sweet-alert button:focus{outline:0;box-shadow:0 0 2px rgba(128,179,235,.5),inset 0 0 0 1px rgba(0,0,0,.05)}.sweet-alert button:hover{background-color:#a1d9f2}.sweet-alert button:active{background-color:#81ccee}.sweet-alert button.cancel{background:0 0;color:#d9534f}.sweet-alert button.cancel:hover{background:0 0}.sweet-alert button.cancel:active{background:0 0}.sweet-alert button.cancel:focus{box-shadow:rgba(197,205,211,.8) 0 0 2px,rgba(0,0,0,.0470588) 0 0 0 1px inset!important}.sweet-alert button::-moz-focus-inner{border:0}.sweet-alert .icon{width:80px;height:80px;border:4px solid gray;border-radius:50%;margin:20px auto;padding:0;position:relative;box-sizing:content-box}.sweet-alert .icon.error{border-color:#d9534f}.sweet-alert .icon.error .x-mark{position:relative;display:block}.sweet-alert .icon.error .line{position:absolute;height:5px;width:47px;background-color:#d9534f;display:block;top:37px;border-radius:2px}.sweet-alert .icon.error .line.left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.sweet-alert .icon.error .line.right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}.sweet-alert .icon.warning{border-color:#d9534f}.sweet-alert .icon.warning .body{position:absolute;width:5px;height:47px;left:50%;top:10px;border-radius:2px;margin-left:-2px;background-color:#d9534f}.sweet-alert .icon.warning .dot{position:absolute;width:7px;height:7px;border-radius:50%;margin-left:-3px;left:50%;bottom:10px;background-color:#d9534f}.sweet-alert .icon.info{border-color:#007aab}.sweet-alert .icon.info::before{content:\"\";position:absolute;width:5px;height:29px;left:50%;bottom:17px;border-radius:2px;margin-left:-2px;background-color:#007aab}.sweet-alert .icon.info::after{content:\"\";position:absolute;width:7px;height:7px;border-radius:50%;margin-left:-3px;top:19px;background-color:#007aab}.sweet-alert .icon.success{border-color:#A5DC86}.sweet-alert .icon.success::before,.sweet-alert .icon.success::after{content:'';border-radius:50%;position:absolute;width:60px;height:120px;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .icon.success::before{border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.sweet-alert .icon.success::after{border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px}.sweet-alert .icon.success .placeholder{width:80px;height:80px;border:4px solid rgba(165,220,134,.2);border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.sweet-alert .icon.success .fix{width:5px;height:90px;background-color:#fff;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .icon.success .line{height:5px;background-color:#A5DC86;display:block;border-radius:2px;position:absolute;z-index:2}.sweet-alert .icon.success .line.tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .icon.success .line.long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .icon.custom{background-size:contain;border-radius:0;border:0;background-position:center center;background-repeat:no-repeat}.sweet-alert #shortcode_edit{width:100%;height:200px;color:#000;font-size:small;font-family:\"Lucida Console\",\"Courier New\",monospace}.sweet-alert[data-has-cancel-button=false] button{box-shadow:none!important}@-webkit-keyframes showSweetAlert{0%{transform:scale(0.7);-webkit-transform:scale(0.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-moz-keyframes showSweetAlert{0%{transform:scale(0.7);-webkit-transform:scale(0.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes showSweetAlert{0%{transform:scale(0.7);-webkit-transform:scale(0.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-webkit-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(0.5);-webkit-transform:scale(0.5)}}@-moz-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(0.5);-webkit-transform:scale(0.5)}}@keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(0.5);-webkit-transform:scale(0.5)}}.showSweetAlert{-webkit-animation:showSweetAlert .2s;-moz-animation:showSweetAlert .2s;animation:showSweetAlert .2s}.hideSweetAlert{-webkit-animation:hideSweetAlert .2s;-moz-animation:hideSweetAlert .2s;animation:hideSweetAlert .2s}.animateSuccessTip{-webkit-animation:animateSuccessTip .75s;-moz-animation:animateSuccessTip .75s;animation:animateSuccessTip .75s}.animateSuccessLong{-webkit-animation:animateSuccessLong .75s;-moz-animation:animateSuccessLong .75s;animation:animateSuccessLong .75s}.icon.success.animate::after{-webkit-animation:rotatePlaceholder 4.25s ease-in;-moz-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}.lasso-util--help{position:relative;cursor:pointer;color:#007aab;display:inline-block;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;opacity:.75;filter:alpha(opacity=75)}.lasso-util--help:hover{text-decoration:none;opacity:1;filter:alpha(opacity=100)}.lasso-util--help:before,.lasso-util--help:after{position:absolute;visibility:hidden;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-webkit-transform .2s cubic-bezier(0.71,1.7,.77,1.24);-moz-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-moz-transform .2s cubic-bezier(0.71,1.7,.77,1.24);transition:opacity .2s ease-in-out,visibility .2s ease-in-out,transform .2s cubic-bezier(0.71,1.7,.77,1.24);-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translate3d(0,0,0);pointer-events:none}.lasso-util--help:hover:before,.lasso-util--help:hover:after,.lasso-util--help:focus:before,.lasso-util--help:focus:after{visibility:visible;opacity:1;filter:alpha(opacity=100)}.lasso-util--help:before{z-index:10001;border:6px solid transparent;background:0 0;content:\"\"}.lasso-util--help:after{z-index:1000;padding:8px;width:160px;background-color:rgba(0,122,171,.95);color:#e2e2e2;font-family:Arial;content:attr(data-tooltip);font-size:12px;line-height:1.2;border-radius:2px}.lasso-util--help:before,.lasso-util--help:after,.lasso-util--help-top:before,.lasso-util--help-top:after{bottom:100%;left:50%}.lasso-util--help:before,.lasso-util--help-top:before{margin-left:-6px;margin-bottom:-12px;border-top-color:rgba(0,122,171,.95)}.lasso-util--help:after,.lasso-util--help-top:after{margin-left:-80px}.lasso-util--help:hover:before,.lasso-util--help:hover:after,.lasso-util--help:focus:before,.lasso-util--help:focus:after,.lasso-util--help-top:hover:before,.lasso-util--help-top:hover:after,.lasso-util--help-top:focus:before,.lasso-util--help-top:focus:after{-webkit-transform:translateY(-12px);-moz-transform:translateY(-12px);transform:translateY(-12px)}.lasso-util--help-left:before,.lasso-util--help-left:after{right:100%;bottom:50%;left:auto}.lasso-util--help-left:before{margin-left:0;margin-right:-12px;margin-bottom:0;border-top-color:transparent;border-left-color:rgba(0,122,171,.95)}.lasso-util--help-left:hover:before,.lasso-util--help-left:hover:after,.lasso-util--help-left:focus:before,.lasso-util--help-left:focus:after{-webkit-transform:translateX(-12px);-moz-transform:translateX(-12px);transform:translateX(-12px)}.lasso-util--help-bottom:before,.lasso-util--help-bottom:after{top:100%;bottom:auto;left:50%}.lasso-util--help-bottom:before{margin-top:-12px;margin-bottom:0;border-top-color:transparent;border-bottom-color:rgba(0,122,171,.95)}.lasso-util--help-bottom:hover:before,.lasso-util--help-bottom:hover:after,.lasso-util--help-bottom:focus:before,.lasso-util--help-bottom:focus:after{-webkit-transform:translateY(12px);-moz-transform:translateY(12px);transform:translateY(12px)}.lasso-util--help-right:before,.lasso-util--help-right:after{bottom:50%;left:100%}.lasso-util--help-right:before{margin-bottom:0;margin-left:-12px;border-top-color:transparent;border-right-color:rgba(0,122,171,.95)}.lasso-util--help-right:hover:before,.lasso-util--help-right:hover:after,.lasso-util--help-right:focus:before,.lasso-util--help-right:focus:after{-webkit-transform:translateX(12px);-moz-transform:translateX(12px);transform:translateX(12px)}.lasso-util--help-left:before,.lasso-util--help-right:before{top:3px}.lasso-util--help-left:after,.lasso-util--help-right:after{margin-left:0;margin-bottom:-16px}.story-tags-option .tagit,.story-categories-option .tagit,.story-custom-taxonomy-option .tagit{padding:4px 0 0;overflow:auto;margin-left:inherit;margin-right:inherit;border-radius:3px;list-style:none}.story-tags-option .tagit li,.story-categories-option .tagit li,.story-custom-taxonomy-option .tagit li{float:left}.story-tags-option .tagit li.tagit-choice,.story-categories-option .tagit li.tagit-choice,.story-custom-taxonomy-option .tagit li.tagit-choice{position:relative;margin:2px;display:inline;padding:4px 8px 4px 18px;font-family:Arial;font-size:12px;line-height:16px;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:2px;background:rgba(50,55,60,.75)}.story-tags-option .tagit li .tagit-close,.story-categories-option .tagit li .tagit-close,.story-custom-taxonomy-option .tagit li .tagit-close{cursor:pointer;position:absolute;left:7px;color:#fff;top:5px}.story-tags-option .tagit li .tagit-close:hover,.story-categories-option .tagit li .tagit-close:hover,.story-custom-taxonomy-option .tagit li .tagit-close:hover{text-decoration:none;color:#fff}.story-tags-option .tagit li.tagit-new,.story-categories-option .tagit li.tagit-new,.story-custom-taxonomy-option .tagit li.tagit-new{position:relative;top:-6px}.story-tags-option .tagit li input[type=text],.story-categories-option .tagit li input[type=text],.story-custom-taxonomy-option .tagit li input[type=text]{box-shadow:none;border:0;border-radius:0;margin:0;padding:0 0 0 4px;width:inherit;background-color:#fff!important;color:#000!important;outline:0;font-size:12px;line-height:24px;display:inline-block;margin:2px 5px 2px 0;color:rgba(255,255,255,.5)}.story-tags-option input.tagit-hidden-field,.story-categories-option input.tagit-hidden-field,.story-custom-taxonomy-option input.tagit-hidden-field{display:none}.story-tags-option ul.tagit li.tagit-choice a.tagit-label,.story-categories-option ul.tagit li.tagit-choice a.tagit-label,.story-custom-taxonomy-option ul.tagit li.tagit-choice a.tagit-label{cursor:pointer;text-decoration:none}.story-categories-option{border-bottom:0;box-shadow:none;margin-bottom:0}.story-tags-option .tagit li.tagit-choice{position:relative;margin:2px 2px 2px 15px;padding:4px 8px 4px 12px;border-top-left-radius:0;border-bottom-left-radius:0}.story-tags-option .tagit li.tagit-choice:before{content:'';position:absolute;width:0;height:0;border-top:12px solid transparent;border-bottom:12px solid transparent;border-right:14px solid #32373c;left:-14px;top:0}.story-tags-option .tagit li.tagit-choice .tagit-close{left:0}.lasso-modal-open .ui-autocomplete{position:absolute;top:100%;left:0;z-index:100002;float:left;display:none;min-width:160px;padding:4px;margin:2px 0 0;list-style:none;color:#fff;background-color:#32373c;border-radius:3px;box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.lasso-modal-open .ui-autocomplete .ui-menu-item{display:block;padding:1px 2px;clear:both;font-weight:400;line-height:18px;white-space:nowrap;font-family:Arial;font-size:14px;background-color:#23282d}.lasso-modal-open .ui-autocomplete .ui-menu-item a{background-color:#23282d;color:#fff}.lasso-modal-open .ui-autocomplete .ui-menu-item:hover,.lasso-modal-open .ui-autocomplete .ui-menu-item.ui-state-active{cursor:pointer}.lasso-modal-open .ui-autocomplete.tagit-autocomplete{overflow-y:scroll;max-height:310px}.lasso--tour__modal .lasso--postsettings__footer:before,.lasso--tour__modal .lasso--postsettings__footer:after{content:\" \";display:table}.lasso--tour__modal .lasso--postsettings__footer:after{clear:both}.lasso--tour__modal .lasso--modal__inner{position:relative}.lasso--tour__modal .lasso--postsettings__option{border-bottom:0;box-shadow:none;padding-bottom:0;margin-bottom:0;float:left;top:4px;position:relative;opacity:.85;filter:alpha(opacity=85)}.lasso--tour__modal .lasso--postsettings__option label{padding-left:23px;font-size:14px;font-weight:400;color:#fff}.lasso--tour__modal .lasso--postsettings__option .control-indicator{width:14px;height:14px;top:0}.lasso--tour__modal #lasso--tour__slides{position:relative;overflow:auto;display:none}.lasso--tour__modal ul{margin:0;padding:0;list-style:none}.lasso--tour__modal ul:before,.lasso--tour__modal ul:after{content:\" \";display:table}.lasso--tour__modal ul:after{clear:both}.lasso--tour__modal ul li{float:left}.lasso--tour__modal li img{background:#0d0e10;padding:6px;border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.1);box-shadow:0 1px 1px rgba(255,255,255,.1)}.lasso--tour__modal li p{font-family:Arial;font-size:16px;line-height:1.25;margin:15px auto 28px;padding-right:4px;padding-left:4px}.lasso--tour__modal .dots{position:absolute;left:0;right:0;bottom:-10px;text-align:center;width:100%;margin:0;height:30px}.lasso--tour__modal .dots li{display:inline-block;width:14px;height:14px;line-height:16px;margin:0 3px;text-indent:-999em;border:1px solid #0d0e10;background:rgba(0,122,171,.75);border-radius:100%;cursor:pointer;opacity:.4;filter:alpha(opacity=40);-webkit-transition:background .5s,opacity .5s;-moz-transition:background .5s,opacity .5s;transition:background .5s,opacity .5s;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.1);box-shadow:0 1px 1px rgba(255,255,255,.1)}.lasso--tour__modal .dots li.active{background:#fff;opacity:1}.lasso--tour__modal input[type=submit]{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:0;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none}.lasso--tour__modal input[type=submit]:active,.lasso--tour__modal input[type=submit]:focus{outline:0}.lasso--tour__modal input[type=submit]:hover{text-decoration:none;color:#fff;background:#005678}.lasso--tour__modal input[type=submit]:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--loading{height:auto;left:0;top:0;right:0;width:100%}.lasso--loader{height:40px;width:40px;margin:10px auto;top:48%;position:relative;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:3px solid rgba(96,106,116,.2);border-right:3px solid rgba(96,106,116,.2);border-bottom:3px solid rgba(96,106,116,.2);border-top:3px solid #606a74;border-radius:100%}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{from{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{from{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.lasso--modal{top:10vh}.lasso--modal.lasso--modal__full{width:100%;max-width:800px}.lasso--modal.lasso--modal__full .lasso--modal__inner{display:block;padding:36px}.lasso--modal.lasso--modal__full .lasso--modal__inner:before,.lasso--modal.lasso--modal__full .lasso--modal__inner:after{content:\" \";display:table}.lasso--modal.lasso--modal__full .lasso--modal__inner:after{clear:both}#lasso--all-posts__modal #lasso--loading{position:absolute;height:90%}ul.lasso--post-object-list,ul.lasso--post-list{text-align:left;list-style:none;margin:0;padding:0}ul.lasso--post-object-list li,ul.lasso--post-list li{display:block;position:relative;width:100%;list-style-type:none;margin-bottom:7px;font-size:14px;font-family:Arial;font-weight:700}ul.lasso--post-object-list{width:100px;float:left;height:100%}ul.lasso--post-object-list li{line-height:25px;margin-bottom:0;font-family:Arial;font-weight:400;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}ul.lasso--post-object-list li:not(.active){opacity:.45;filter:alpha(opacity=45)}ul.lasso--post-object-list li:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100)}.lasso--post-filtering{padding:0 18px;width:calc(100% - 100px);height:42px;float:right}.lasso--post-filtering:before,.lasso--post-filtering:after{content:\" \";display:table}.lasso--post-filtering:after{clear:both}.lasso--post-filtering .lasso--search__results,.lasso--post-filtering .lasso--search{float:left}.lasso--post-filtering .lasso--search__results{opacity:0;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease;width:60%;font-size:15px}.lasso--post-filtering .lasso--search__results span{font-weight:700;margin-right:4px}.lasso--post-filtering .lasso--search{width:40%;overflow:hidden;position:relative}.lasso--post-filtering .lasso--search #lasso--search__toggle,.lasso--post-filtering .lasso--search input{-webkit-transition:right .15s linear;-moz-transition:right .15s linear;transition:right .15s linear}.lasso--post-filtering .lasso--search #lasso--search__toggle{position:relative;top:7.5px;right:-209px}.lasso--post-filtering .lasso--search #lasso--search__toggle:before{opacity:.5;filter:alpha(opacity=50);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--post-filtering .lasso--search #lasso--search__toggle:hover{cursor:pointer}.lasso--post-filtering .lasso--search #lasso--search__toggle:hover:before{opacity:.9;filter:alpha(opacity=90)}.lasso--post-filtering .lasso--search input{float:right;width:194px;right:-194px;background-color:#f8f8f8!important;padding:2px 8px;background:#f8f8f8;border:1px solid #181b1f;color:#444;font-size:14px;z-index:0;position:relative;padding-left:6px;height:36px;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);height:32px}.lasso--post-filtering .lasso--search input:focus{outline:0;border:1px solid #007aab;border-radius:2px}.lasso--post-filtering .lasso--search input:focus{box-shadow:none}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle{right:-15px}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle:before{opacity:.9;filter:alpha(opacity=90)}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle:hover:before{opacity:.5;filter:alpha(opacity=50)}.lasso--post-filtering .lasso--search.lasso--search__visible input{right:0}#lasso--helper{position:absolute;right:4px;top:4px;font-size:12px;padding:2px 6px;background:#32373c;color:#fff;border-radius:2px;font-family:Arial}#lasso--clear-search{position:absolute;right:7px;top:7px;color:#c9c9c9;z-index:1}#lasso--clear-search:hover{color:#bcbcbc;cursor:pointer}.lasso--empty-state{max-width:200px;text-align:center;color:#737679;margin:0 auto;top:40%;position:relative}.lasso--empty-state .lasso--empty-state-icon{font-size:50px}.lasso--empty-state p{margin-bottom:0;font-family:Arial;font-size:90%;font-weight:700}.lasso--empty-state p+a{margin-top:10px}ul.lasso--post-list{float:left;padding:0 18px;width:calc(100% - 100px);overflow:hidden;position:relative;height:520px;border-left:1px solid #181b1f;-webkit-box-shadow:inset 1px 0 1px -1px rgba(255,255,255,.15);box-shadow:inset 1px 0 1px -1px rgba(255,255,255,.15)}ul.lasso--post-list li{overflow:hidden;line-height:50px}ul.lasso--post-list .lasso--post-list__item{color:#c9c9c9;display:block;padding:0 15px;background:rgba(50,55,60,.75);text-decoration:none;border-radius:4px;-webkit-transition:all .15s ease;-moz-transition:all .15s ease;transition:all .15s ease;font-family:Arial;font-weight:400;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ul.lasso--post-list .lasso--post-list__item:before{content:'';height:8px;width:8px;border-radius:100%;margin-right:8px;display:inline-block}ul.lasso--post-list .lasso--post-list__item.draft:before{background:#f0ad4e}ul.lasso--post-list .lasso--post-list__item.publish:before{background:#4da34d}ul.lasso--post-list .lasso--post-list__item.pending:before{background:#007aab}ul.lasso--post-list .lasso--post-list__item:hover{background:#32373c;text-decoration:none;width:calc(100% - 115px)}ul.lasso--post-list .lasso--post-list__item:hover .lasso--post-list__controls{right:0}ul.lasso--post-list .lasso--post-list__item:active{outline:0;background:#32373c;text-decoration:none;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.5);box-shadow:inset 1px 1px 2px rgba(0,0,0,.5)}ul.lasso--post-list .lasso--post-list__item:focus{outline:0}ul.lasso--post-list .lasso--post-list__item.no-delete:hover{width:calc(100% - 57.5px)}.lasso--post-list__controls{position:absolute;right:0;top:0;width:115px;text-align:right;right:-115px;height:50px;-webkit-transition:right .15s ease;-moz-transition:right .15s ease;transition:right .15s ease}.lasso--post-list__controls span{color:#626262;display:inline-block;width:50px;height:50px;background:#32373c;border-radius:4px;position:relative}.lasso--post-list__controls span:after{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;font-size:18px;position:absolute;z-index:2;top:16px;left:16px}.lasso--post-list__controls span:hover{color:#626262;background:rgba(50,55,60,.5)}.lasso--post-list__controls span:active{background:#32373c;text-decoration:none;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.5);box-shadow:inset 1px 1px 2px rgba(0,0,0,.5)}.lasso--post-list__controls #lasso--post__edit{margin-right:3px}.lasso--post-list__controls #lasso--post__edit:hover{color:#e2e2e2;background:#007aab}.lasso--post-list__controls #lasso--post__edit:after{content:'\\e908'}.lasso--post-list__controls #lasso--post__delete:hover{color:#e2e2e2;background:#d9534f}.lasso--post-list__controls #lasso--post__delete:after{content:'\\e9ad'}#lasso--load-more,#lasso--close-modal-posts{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;font-size:17px;line-height:1.8;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;font-size:15px;text-transform:uppercase;line-height:2;margin-top:10px;opacity:.66;filter:alpha(opacity=66)}#lasso--load-more:active,#lasso--close-modal-posts:active,#lasso--load-more:visited,#lasso--close-modal-posts:visited{color:#e2e2e2}#lasso--load-more:hover,#lasso--close-modal-posts:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}#lasso--load-more:active,#lasso--close-modal-posts:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--load-more.lasso--btn-loading:before,#lasso--close-modal-posts.lasso--btn-loading:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#lasso--load-more:active,#lasso--close-modal-posts:active,#lasso--load-more:visited,#lasso--close-modal-posts:visited{color:#e2e2e2}#lasso--load-more:hover,#lasso--close-modal-posts:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}#lasso--load-more:active,#lasso--close-modal-posts:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--load-more.lasso--btn-loading:before,#lasso--close-modal-posts.lasso--btn-loading:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.editus-firstp:empty:before{content:attr(placeholder);color:grey;font-style:italic}#lasso--revision__modal{-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--revision__modal .lasso--slider_wrap{padding:0 16px;margin-top:18px}#lasso--revision__modal .lasso--btn-group .lasso--btn-secondary{opacity:.7;filter:alpha(opacity=70);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--revision__modal .lasso--btn-group .lasso--btn-secondary:hover{opacity:1;filter:alpha(opacity=100)}#lasso--revision__modal .lasso-icon-move{position:absolute;top:15px;right:15px;color:#747474;font-size:14px}#lasso--revision__modal .lasso-icon-move:hover{cursor:move}#lasso--revision-list{margin:0;padding:0;list-style:none;text-align:center;margin-bottom:10px;width:110%;left:-5%;position:relative;top:-3px}#lasso--revision-list:before,#lasso--revision-list:after{content:\" \";display:table}#lasso--revision-list:after{clear:both}#lasso--revision-list li{padding:12px 0 0;display:inline-block;font-family:Arial;font-size:11px;color:#c9c9c9;text-transform:uppercase;line-height:13px;margin:0 auto;position:relative}#lasso--revision-list li span{color:#c9c9c9}#lasso--revision-list li:first-child{margin-left:0}#lasso--revision-list li:last-child{margin-right:0}#lasso--revision-list li:before{content:'';height:5px;border-right:1px solid #747474;width:1px;position:absolute;top:0;left:0;right:0;text-align:center;margin:0 auto}#lasso--revision-list[data-count=\"6\"] li{width:16.666666%}#lasso--revision-list[data-count=\"6\"] li[data-revision=\"0\"]{left:2px}#lasso--revision-list[data-count=\"6\"] li[data-revision=\"1\"]{left:2px}#lasso--revision-list[data-count=\"6\"] li[data-revision=\"5\"]{right:-1px}#lasso--revision-list[data-count=\"6\"] li[data-revision=\"6\"]{right:6px}#lasso--revision-list[data-count=\"5\"] li{width:20%}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"0\"]{left:-4px}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"1\"]{left:-2px}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"2\"]{left:0}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"3\"]{right:-2px}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"4\"]{right:-4px}#lasso--revision-list[data-count=\"4\"] li{width:25%}#lasso--revision-list[data-count=\"4\"] li[data-revision=\"0\"]{left:-15px}#lasso--revision-list[data-count=\"4\"] li[data-revision=\"1\"]{left:-4px}#lasso--revision-list[data-count=\"4\"] li[data-revision=\"2\"]{right:-4px}#lasso--revision-list[data-count=\"4\"] li[data-revision=\"3\"]{right:-15px}#lasso--revision-list[data-count=\"3\"] li{width:33.333%}#lasso--revision-list[data-count=\"3\"] li[data-revision=\"0\"]{left:-29px}#lasso--revision-list[data-count=\"3\"] li[data-revision=\"1\"]{left:0}#lasso--revision-list[data-count=\"3\"] li[data-revision=\"2\"]{right:-29px}#lasso--revision-list[data-count=\"2\"] li{width:50%}#lasso--revision-list[data-count=\"2\"] li[data-revision=\"0\"]{left:-60px}#lasso--revision-list[data-count=\"2\"] li[data-revision=\"1\"]{right:-60px}.os-ios .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}@media (max-width:600px){.lasso-editing .lasso--toolbar_wrap.ase-not-active,.lasso-editing .lasso--toolbar_wrap.toolbar-extended,.lasso-editing .lasso--toolbar_wrap.ase-not-active.toolbar-extended,.lasso-editing .lasso--toolbar_wrap{border-radius:0;width:100%;left:0;right:0;-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0);height:auto;bottom:auto}.lasso-editing .lasso--controls__right{z-index:1000;top:auto;right:0}.lasso-editing .lasso--controls__right a{background:0 0}.lasso-editing .lasso--controls__right #lasso--save:before{top:3px}.lasso-editing #lasso-toolbar--link.link--drop-down,.lasso-editing #lasso-toolbar--html.html--drop-down{position:static}.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--link__wrap,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--html__wrap,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap{left:0;right:0;top:auto;bottom:50px;width:90%}.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--link__wrap:after,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--html__wrap:after,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{margin:0;top:-6px;border-top:0;border-bottom:6px solid #39424a}.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{left:142px}.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{left:175px}.lasso-editing #lasso-toolbar--components.toolbar--drop-down{position:static}.lasso-editing #lasso-toolbar--components.toolbar--drop-down ul{top:44px;left:0;right:0;width:100%}.lasso-editing #lasso-toolbar--components.toolbar--drop-down ul:after{left:206px;margin:0;top:-6px;border-top:0;border-bottom:6px solid #39424a}.lasso-editing .toolbar-extended #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{left:222px}.lasso-editing .toolbar-extended #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{left:255px}.lasso-editing .toolbar-extended #lasso-toolbar--components.toolbar--drop-down ul:after{left:288px}#lasso--all-posts__modal ul.lasso--post-list,#lasso--all-posts__modal ul.lasso--post-object-list{float:none;width:100%;display:block}#lasso--all-posts__modal ul.lasso--post-object-list{margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid #181b1f;-webkit-box-shadow:0 1px 1px -1px rgba(255,255,255,.15);box-shadow:0 1px 1px -1px rgba(255,255,255,.15)}#lasso--all-posts__modal ul.lasso--post-object-list li{display:inline-block;width:auto;margin-right:20px;font-size:90%}#lasso--all-posts__modal ul.lasso--post-list{padding-left:0;border:0;box-shadow:none}.lasso--modal .lasso--modal__inner,.lasso--modal.lasso--modal__full .lasso--modal__inner{border-radius:0;padding:10px}}.lasso-mobile #lasso--exit{float:none}@media (min-width:601px){.lasso-mobile .toolbar--drop-up ul:after{margin:0;top:-9px;border-top:0;border-bottom:6px solid #39424a}.lasso-mobile #lasso-toolbar--html__wrap:after,.lasso-mobile #lasso-toolbar--link__wrap:after{margin:0;top:-9px;border-top:0;border-bottom:6px solid #39424a}.lasso-mobile.lasso--toolbar_wrap{width:100%}}"
  },
  {
    "path": "public/assets/css/style.css",
    "content": ".lasso--animate__spin{-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.not-visible{opacity:0;filter:alpha(opacity=0);display:none;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease}@font-face{font-family:icomoon;src:url(../../../public/assets/fonts/icomoon.eot?ua4grz);src:url(../../../public/assets/fonts/icomoon.eot?#iefixua4grz) format('embedded-opentype'),url(../../../public/assets/fonts/icomoon.woff?ua4grz) format('woff'),url(../../../public/assets/fonts/icomoon.ttf?ua4grz) format('truetype'),url(../../../public/assets/fonts/icomoon.svg?ua4grz#icomoon) format('svg');font-weight:400;font-style:normal}[class*=\" lasso-icon-\"],[class^=lasso-icon-]{font-family:icomoon;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso-icon-move:before{content:\"\\e600\"}.lasso-icon-pen:before{content:\"\\e908\"}.lasso-icon-image:before{content:\"\\e90d\"}.lasso-icon-images:before{content:\"\\e90e\"}.lasso-icon-camera:before{content:\"\\e90f\"}.lasso-icon-headphones:before{content:\"\\e910\"}.lasso-icon-film:before{content:\"\\e913\"}.lasso-icon-book:before{content:\"\\e91f\"}.lasso-icon-books:before{content:\"\\e920\"}.lasso-icon-file-text2:before{content:\"\\e926\"}.lasso-icon-location:before{content:\"\\e947\"}.lasso-icon-clock:before{content:\"\\e94e\"}.lasso-icon-user:before{content:\"\\e971\"}.lasso-icon-quotes-left:before{content:\"\\e977\"}.lasso-icon-plus:before{content:\"\\ea0a\"}.lasso-icon-bold:before{content:\"\\ea62\"}.lasso-icon-underline:before{content:\"\\ea63\"}.lasso-icon-italic:before{content:\"\\ea64\"}.lasso-icon-strikethrough:before{content:\"\\ea65\"}.lasso-icon-pagebreak:before{content:\"\\ea6e\"}.lasso-icon-paragraph-center:before{content:\"\\ea78\"}.lasso-icon-spinner6:before{content:\"\\e97f\"}.lasso-icon-upload2:before{content:\"\\e9c6\"}.lasso-icon-cross:before{content:\"\\ea0f\"}.lasso-icon-bin2:before{content:\"\\e9ad\"}.lasso-icon-copy:before{content:\"\\e92c\"}.lasso-icon-disk:before{content:\"\\e601\"}.lasso-icon-embed:before{content:\"\\ea7f\"}.lasso-icon-blog:before{content:\"\\e909\"}.lasso-icon-pencil:before{content:\"\\e905\"}.lasso-icon-gear:before{content:'\\e994'}.lasso-icon-link:before{content:'\\e9cb'}.lasso-icon-help:before{content:\"\\e602\"}.lasso-icon-tools:before{content:\"\\f031\"}.lasso-icon-layout:before{content:\"\\e603\"}.lasso-icon-list:before{content:\"\\e9ba\"}.lasso-icon-file-add:before{content:\"\\e603\"}.lasso-icon-check:before{content:'\\ea10'}.lasso-icon-history:before{content:\"\\e94d\"}.lasso-editing .aesop-content-comp-wrap,.lasso-editing .aesop-image-component-image,.lasso-editing .aesop-video-container{-webkit-transition:all .25s linear;-moz-transition:all .25s linear;transition:all .25s linear}.lassoShowAnimate{-webkit-animation:lassoShowAnimate .2s;-moz-animation:lassoShowAnimate .2s;animation:lassoShowAnimate .2s}.lassoHideAnimate{-webkit-animation:lassoHideAnimate .2s;-moz-animation:lassoHideAnimate .2s;animation:lassoHideAnimate .2s}@-webkit-keyframes lassoShowAnimate{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-moz-keyframes lassoShowAnimate{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes lassoShowAnimate{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-webkit-keyframes lassoHideAnimate{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@-moz-keyframes lassoHideAnimate{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@keyframes lassoHideAnimate{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}.aesop-component{position:relative}.screen-reader-text,.screen-reader-text span,.ui-helper-hidden-accessible{position:absolute;margin:-1px;padding:0;height:1px;width:1px;overflow:hidden;clip:rect(0 0 0 0);border:0}[contenteditable=true]:focus{outline:0}.lasso-title-saved{-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease;background:rgba(255,255,255,.1)}.lasso-drop-zone{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;height:75px;background:rgba(0,0,0,.03);border:1px dashed rgba(0,0,0,.2);list-style-type:none;width:700px;margin:0 auto 25px;border-radius:3px}.lasso-drop-zone:hover{background:rgba(0,0,0,.03)}.lasso-drag-holder{height:75px!important;background:#d7d7d7;text-align:center;width:60px;font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso-drag-holder.lasso-toolbar--component__image:before,.lasso-drag-holder.lasso-toolbar--component__wpimg:before{content:\"\\e90f\"}.lasso-drag-holder.lasso-toolbar--component__character:before{content:\"\\e971\"}.lasso-drag-holder.lasso-toolbar--component__quote:before,.lasso-drag-holder.lasso-toolbar--component__wpquote:before{content:\"\\e977\"}.lasso-drag-holder.lasso-toolbar--component__content:before{content:\"\\ea78\"}.lasso-drag-holder.lasso-toolbar--component__chapter:before{content:\"\\e91f\"}.lasso-drag-holder.lasso-toolbar--component__parallax:before{content:\"\\ea6e\"}.lasso-drag-holder.lasso-toolbar--component__audio:before{content:\"\\e910\"}.lasso-drag-holder.lasso-toolbar--component__video:before,.lasso-drag-holder.lasso-toolbar--component__wpvideo:before{content:\"\\e913\"}.lasso-drag-holder.lasso-toolbar--component__map:before{content:\"\\e947\"}.lasso-drag-holder.lasso-toolbar--component__timeline:before{content:\"\\e94e\"}.lasso-drag-holder.lasso-toolbar--component__document:before{content:\"\\e926\"}.lasso-drag-holder.lasso-toolbar--component__collection:before{content:\"\\e920\"}.lasso-drag-holder.lasso-toolbar--component__gallery:before{content:\"\\e90e\"}.lasso-drag-holder.lasso-toolbar--component__gallerypop:before{content:\"\\f211\";font-family:Dashicons}.lasso-drag-holder:before{position:relative;top:25px;font-size:22px}.lasso-editor{position:relative;min-height:10px}.lasso-editor:focus{outline:0;border:none;box-shadow:none}.lasso-editor p:empty{display:block;height:1em}.lasso-editor .ui-draggable-dragging{list-style-type:none;height:50px;padding:10px;width:60px!important;background:rgba(35,40,45,.5);text-align:center;font-size:22px;border-radius:4px;font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__image:before,.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__wpimg:before{content:\"\\e90f\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__character:before{content:\"\\e971\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__quote:before,.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__wpquote:before{content:\"\\e977\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__content:before{content:\"\\ea78\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__chapter:before{content:\"\\e91f\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__parallax:before{content:\"\\ea6e\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__audio:before{content:\"\\e910\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__video:before,.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__wpvideo:before{content:\"\\e913\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__map:before{content:\"\\e947\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__timeline:before{content:\"\\e94e\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__document:before{content:\"\\e926\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__collection:before{content:\"\\e920\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__gallery:before{content:\"\\e90e\"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__gallerypop:before{content:\"\\f211\";font-family:Dashicons}.lasso-editor .ui-draggable-dragging:before{color:#fff;position:relative;top:4px}.lasso-editor-clear{background:0 0!important;border-color:transparent!important}.lasso-editor-paste-hook{position:absolute;opacity:0}.lasso-editor-placeholder{position:absolute}.lasso-editor-placeholder div{opacity:.5;filter:alpha(opacity=50);position:absolute}.lasso-editor-placeholder-rich div{font-style:italic}.lasso-editor-inline,.lasso-editor-inlineRich,.lasso-editor-placeholder-inline div,.lasso-editor-placeholder-inlineRich div{overflow:hidden;white-space:nowrap}.lasso-editor-drag{position:absolute;cursor:move;margin-left:-5px;margin-top:-20px}.lasso-editor-toolbar-hide{overflow:hidden;max-height:0;padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;transition-property:opacity;-moz-transition-duration:.3s;-webkit-transition-duration:.3s;-o-transition-duration:.3s;transition-duration:.3s;-moz-transition-timing-function:cubic-bezier(0,1,.5,1);-webkit-transition-timing-function:cubic-bezier(0,1,.5,1);-o-transition-timing-function:cubic-bezier(0,1,.5,1);transition-timing-function:cubic-bezier(0,1,.5,1);opacity:0}.lasso-editor-toolbar-show{transition-property:opacity;-moz-transition-duration:.3s;-webkit-transition-duration:.3s;-o-transition-duration:.3s;transition-duration:.3s;-moz-transition-timing-function:ease-in;-webkit-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;max-height:1000px;opacity:1;width:auto!important}.lasso-editor-toolbar-fixed{position:fixed}.lasso-editor-focused{transition:all 500ms ease-in-out 0s;-moz-box-shadow:0 0 3px 4px rgba(0,0,0,.2);-webkit-box-shadow:0 0 3px 4px rgba(0,0,0,.2);box-shadow:0 0 3px 4px rgba(0,0,0,.2)}#lasso--pagerefresh{padding:15px;background:#4da34d;color:#fff;font-size:14px;line-height:18.2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--toolbar_wrap{width:auto;left:50%;-webkit-transform:translate(-50%,0);-ms-transform:translate(-50%,0);transform:translate(-50%,0)}.lasso-editor-controls--wrap{color:#e2e2e2;border:1px solid #181b1f;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);height:39px;font-size:16px;border-radius:4px;position:fixed;text-align:center;bottom:20px;z-index:999}.lasso-editor-controls--wrap *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.lasso-editor-controls{margin:0;padding:0;letter-spacing:0;list-style:none;height:39px;line-height:1}ul.lasso-editor-controls:after,ul.lasso-editor-controls:before{content:\" \";display:table}ul.lasso-editor-controls:after{clear:both}ul.lasso-editor-controls li{height:37px;position:relative;float:left;padding:0 8px;border-right:1px solid #23282d;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4);line-height:1}ul.lasso-editor-controls li:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease;position:relative;top:10px}ul.lasso-editor-controls li:first-child:hover{border-top-left-radius:4px;border-bottom-left-radius:4px}ul.lasso-editor-controls li:last-child{border-right:0}ul.lasso-editor-controls li:last-child:hover{border-top-right-radius:4px;border-bottom-right-radius:4px}ul.lasso-editor-controls li:hover{cursor:pointer;background:#39424a}ul.lasso-editor-controls li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4)}#lasso-toolbar--bold:before{content:'\\ea62'}#lasso-toolbar--italic:before{content:'\\ea64'}#lasso-toolbar--underline:before{content:'\\ea63'}#lasso-toolbar--strike:before{content:'\\ea65'}#lasso-toolbar--link:before{content:'\\e9cb'}#lasso-toolbar--h2:before{content:'H2';top:9px;font-size:17px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--h3:before{content:'H3';top:9px;font-size:17px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--html:before{content:'\\ea7f'}#lasso-toolbar--components:before{content:'\\ea0a'}#lasso-toolbar--color-set:before{content:'A';top:5px;font-size:21px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--color-pick:before{content:'\\f100';font-family:Dashicons}#lasso-toolbar--left-align:before{content:'\\f206';font-family:Dashicons}#lasso-toolbar--center-align:before{content:'\\f207';font-family:Dashicons}#lasso-toolbar--right-align:before{content:'\\f208';font-family:Dashicons}#lasso-toolbar--html #lasso-toolbar--html__wrap{position:absolute;left:-10000px;opacity:0;filter:alpha(opacity=0)}#lasso-toolbar--html.html--drop-down,#lasso-toolbar--html.html--drop-up{box-shadow:none;background:#39424a}#lasso-toolbar--html.html--drop-down *,#lasso-toolbar--html.html--drop-up *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap{margin:0;padding:4px;opacity:1;filter:alpha(opacity=100);list-style-type:none;width:340px;height:173px;bottom:45px;border-radius:4px;left:-154px;background:#353c44}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap:after{content:'';position:absolute;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #39424a;left:0;right:0;bottom:-6px;text-align:center;margin:0 auto}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:hover,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap:hover{cursor:default}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner{background:#23282d;color:#e2e2e2;height:130px;overflow:scroll;text-align:left;line-height:1.25;padding:8px;border-radius:2px;font-family:monospace;white-space:pre;font-size:14px;-webkit-box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25);box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner:empty:before,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner:empty:before{content:attr(placeholder);color:rgba(226,226,226,.5)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner:hover,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner:hover{cursor:text}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner:focus,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner:focus{outline:0}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer{text-align:right;font-family:Arial;padding:7px 2px 2px;height:35px}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer a,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer a{font-size:14px;font-weight:700;padding:5px 7px 4px;line-height:1;border-radius:2px;display:inline-block;text-decoration:none;color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.4)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__insert,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__insert{background:#007aab}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__insert:hover,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__insert:hover{background:#006187}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__insert:active,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__insert:active{background:#004764;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer .lasso-toolbar--html__cancel,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer .lasso-toolbar--html__cancel{color:#d9534f}ul.lasso-toolbar--html-snips{font-size:12px;line-height:0;float:left;margin:0;list-style:none}ul.lasso-toolbar--html-snips:after,ul.lasso-toolbar--html-snips:before{content:\" \";display:table}ul.lasso-toolbar--html-snips:after{clear:both}ul.lasso-toolbar--html-snips li{line-height:0;height:25px;margin-right:4px;background:#23282d;border:1px solid #1f2327;border-radius:4px;-webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,.05);box-shadow:inset 1px 1px 0 rgba(255,255,255,.05)}ul.lasso-toolbar--html-snips li:before{top:5px}ul.lasso-toolbar--html-snips li:last-child{border-right:1px solid #1f2327}ul.lasso-toolbar--html-snips #lasso-html--h2:before{content:'H2'}ul.lasso-toolbar--html-snips #lasso-html--h3:before{content:'H3'}ul.lasso-toolbar--html-snips #lasso-html--ul:before{content:'UL'}ul.lasso-toolbar--html-snips #lasso-html--ol:before{content:'OL'}#lasso-toolbar--components ul{position:absolute;left:-10000px;opacity:0;filter:alpha(opacity=0)}#lasso-toolbar--components.toolbar--drop-down,#lasso-toolbar--components.toolbar--drop-up{box-shadow:none;background:#39424a}#lasso-toolbar--components.toolbar--drop-down *,#lasso-toolbar--components.toolbar--drop-up *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso-toolbar--components.toolbar--drop-down ul,#lasso-toolbar--components.toolbar--drop-up ul{margin:0;padding:4px;opacity:1;filter:alpha(opacity=100);list-style-type:none;width:304px;height:86px;top:-92px;border-radius:4px;left:-136px;background:#353c44;line-height:0}#lasso-toolbar--components.toolbar--drop-down ul:after,#lasso-toolbar--components.toolbar--drop-up ul:after{content:'';position:absolute;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #39424a;left:0;right:0;bottom:-6px;text-align:center;margin:0 auto}#lasso-toolbar--components.toolbar--drop-down ul li,#lasso-toolbar--components.toolbar--drop-up ul li{line-height:0;text-align:center;position:relative;font-size:20px;text-shadow:0 1px 1px rgba(0,0,0,.4);border-right:none;margin:1px;padding:2px;height:36px;width:40px;background:#2a3036;border-left:1px solid rgba(255,255,255,.1);border-top:1px solid rgba(255,255,255,.1);-webkit-box-shadow:1px 1px 0 rgba(0,0,0,.3);box-shadow:1px 1px 0 rgba(0,0,0,.3)}#lasso-toolbar--components.toolbar--drop-down ul li:before,#lasso-toolbar--components.toolbar--drop-up ul li:before{top:6px}#lasso-toolbar--components.toolbar--drop-down ul li:hover,#lasso-toolbar--components.toolbar--drop-up ul li:hover{cursor:move;background:#23282d;border-radius:0}#lasso-toolbar--components.toolbar--drop-down ul li.active,#lasso-toolbar--components.toolbar--drop-down ul li:active,#lasso-toolbar--components.toolbar--drop-up ul li.active,#lasso-toolbar--components.toolbar--drop-up ul li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4);background:#1a1e22}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__image:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__wpimg:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__image:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__wpimg:before{content:\"\\e90f\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__character:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__character:before{content:\"\\e971\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__quote:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__wpquote:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__quote:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__wpquote:before{content:\"\\e977\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__content:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__content:before{content:\"\\ea78\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__chapter:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__chapter:before{content:\"\\e91f\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__parallax:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__parallax:before{content:\"\\ea6e\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__audio:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__audio:before{content:\"\\e910\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__video:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__wpvideo:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__video:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__wpvideo:before{content:\"\\e913\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__map:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__map:before{content:\"\\e947\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__timeline:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__timeline:before{content:\"\\e94e\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__document:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__document:before{content:\"\\e926\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__collection:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__collection:before{content:\"\\e920\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__gallery:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__gallery:before{content:\"\\e90e\"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__gallerypop:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__gallerypop:before{content:\"\\f211\";font-family:Dashicons}#lasso-toolbar--link *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso-toolbar--link #lasso-toolbar--link__wrap{position:absolute;left:-10000px;opacity:0;filter:alpha(opacity=0)}#lasso-toolbar--link.link--drop-down,#lasso-toolbar--link.link--drop-up{box-shadow:none;background:#39424a}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap{margin:0;padding:4px;opacity:1;filter:alpha(opacity=100);list-style-type:none;width:300px;height:70px;bottom:45px;border-radius:4px;left:-134px;background:#353c44}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap:after{content:'';position:absolute;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #39424a;left:0;right:0;bottom:-6px;text-align:center;margin:0 auto}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:hover,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap:hover{cursor:default}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner{background:#23282d;color:#e2e2e2;height:32px;white-space:nowrap;overflow:hidden;text-align:left;line-height:1.25;padding:8px;border-radius:2px;font-family:monospace;font-size:14px;-webkit-box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25);box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25)}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:empty:before,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:empty:before{content:attr(placeholder);color:rgba(226,226,226,.5)}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:after,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:after{content:'';position:absolute;background:#23282d;border-top-right-radius:2px;border-bottom-right-radius:2px;right:4px;top:4px;height:32px;width:36px}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:hover,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:hover{cursor:text}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:focus,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:focus{outline:0}#lasso-toolbar--link .lasso-toolbar--link__control{position:absolute;top:9px;right:5px;width:25px;font-family:Arial;font-size:12px;font-weight:700;padding:5px 7px 4px;line-height:1;border-radius:2px;display:inline-block;text-decoration:none;color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.4);background:#007aab}#lasso-toolbar--link .lasso-toolbar--link__control:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\ea10'}#lasso-toolbar--link .styled-checkbox{position:absolute;top:45px;left:8px}#lasso-toolbar--link label{position:absolute;top:45px;left:41px;font-family:Arial;color:#fff;font-size:12px}.ase-not-active #lasso-toolbar--components #lasso-toolbar--components__list{width:94px;left:calc(50% - 94px / 2);height:48px;top:-55px}.lasso--controls__center{width:auto;left:50%;-webkit-transform:translate(-50%,0);-ms-transform:translate(-50%,0);transform:translate(-50%,0)}.lasso--controls__center li{list-style-type:none;line-height:0}.lasso--controls__right{position:fixed;right:-10000px;bottom:20px;z-index:999;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;transition:opacity .3s ease;text-align:right}.lasso--controls__right a{display:inline-block;vertical-align:bottom;color:#e2e2e2;font-family:Arial;font-style:normal;font-size:20px;padding:0 8px;border-radius:3px;height:39px;width:43px;line-height:38px;text-align:center;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--controls__right a:active,.lasso--controls__right a:active:before,.lasso--controls__right a:focus,.lasso--controls__right a:focus:before,.lasso--controls__right a:hover{color:#e2e2e2;text-decoration:none}.lasso--controls__right a:before{color:#fff;font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso--controls__right a:focus{outline:0}#lasso--edit{background:#353c44;border-top-left-radius:3px;border-bottom-left-radius:3px}#lasso--edit:before{content:'\\e908'}#lasso--edit:hover{background:#2e353b}#lasso--post-settings:before{content:'\\f031'}#lasso--post-new:before{content:'\\e603'}#lasso--post-revisions:before{content:'\\e94d'}#lasso--post-all:before{content:'\\e9ba';font-size:15px;top:11px}#lasso--save{background:#007aab;font-size:22px}#lasso--save:before{position:relative;top:4px;left:0;height:auto;content:'\\e601'}#lasso--save:hover{background:#005678}#lasso--save:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--save.being-saved:before{content:'\\e97f';-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#lasso--save.lasso--saved{background:#4da34d}#lasso--save.lasso--saved:before{top:2px;content:'\\ea10'}#lasso--save.lasso--error{background:#d9534f}#lasso--save.lasso--error:before{content:'\\ea05'}#lasso--exit{background:#f0ad4e;float:left}#lasso--exit:before{position:relative;top:3px;content:'\\ea0f'}#lasso--publish{background:#4da34d}#lasso--publish:before{content:'\\e909';position:relative;top:2px}.lasso-editing #lasso--controls .lasso-editor-controls,.lasso-editing #lasso--edit,.lasso-editing #lasso--post-settings{opacity:0;filter:alpha(opacity=0);position:absolute;left:-10000px}.lasso-editing .lasso--controls__right{opacity:1;filter:alpha(opacity=100);right:20px;left:20px}.lasso-editing .wp-audio-shortcode{visibility:visible!important}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.lasso--btn-primary{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:none;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none}.lasso--btn-primary:active,.lasso--btn-primary:focus{outline:0}.lasso--btn-primary:hover{text-decoration:none;color:#fff;background:#005678}.lasso--btn-primary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-secondary{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;font-size:17px;line-height:1.8;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--btn-secondary:active,.lasso--btn-secondary:visited{color:#e2e2e2}.lasso--btn-secondary:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}.lasso--btn-secondary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-secondary.lasso--btn-loading:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.lasso--post-form label{font-size:14px;line-height:1;margin-bottom:8px;display:block;font-family:Arial}.lasso--post-form label .lasso-icon-help{margin-left:5px;position:relative;top:2px}.lasso--post-form input[type=text]{background-color:#f8f8f8!important;padding:2px 8px 2px 6px;background:0 0;border:1px solid #181b1f;color:#444;font-size:14px;z-index:0;position:relative;height:36px;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4)}.lasso--post-form input[type=text]:focus{outline:0;border:1px solid #007aab;border-radius:2px}.lasso--post-form .checkbox_label{display:inline-block}.lasso--post-form .checkbox-control{position:relative;display:inline-block;padding-left:28px;cursor:pointer;top:2px}.lasso--post-form .checkbox-control input{position:absolute;opacity:0;z-index:-1}.lasso--post-form .checkbox-control input:checked~.control-indicator{color:#f8f8f8;background-color:#007aab}.lasso--post-form .checkbox-control input:active~.control-indicator{color:#f8f8f8;background-color:#007aab}.lasso--post-form .control-indicator{position:absolute;top:-1px;left:0;display:block;width:18px;height:18px;line-height:1rem;font-size:65%;color:#f8f8f8;text-align:center;background-color:#f8f8f8;background-size:50% 50%;background-position:center center;background-repeat:no-repeat;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.lasso--post-form .checkbox .control-indicator{border-radius:.25rem}.lasso--post-form .checkbox input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTYuNCwxTDUuNywxLjdMMi45LDQuNUwyLjEsMy43TDEuNCwzTDAsNC40bDAuNywwLjdsMS41LDEuNWwwLjcsMC43bDAuNy0wLjdsMy41LTMuNWwwLjctMC43TDYuNCwxTDYuNCwxeiINCgkvPg0KPC9zdmc+DQo=)}.lasso--post-form .radio .control-indicator{border-radius:50%}.lasso--post-form .radio input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQsMUMyLjMsMSwxLDIuMywxLDRzMS4zLDMsMywzczMtMS4zLDMtM1M1LjcsMSw0LDF6Ii8+DQo8L3N2Zz4NCg==)}.lasso--post-form .control-x input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0xLjQsMEwwLDEuNGwwLjcsMC43bDEuOCwxLjhMMC43LDUuN0wwLDYuNGwxLjQsMS40bDAuNy0wLjdsMS44LTEuOGwxLjgsMS44bDAuNywwLjdsMS40LTEuNEw3LjEsNS43DQoJTDUuMywzLjlsMS44LTEuOGwwLjctMC43TDYuNCwwTDUuNywwLjdMMy45LDIuNUwyLjEsMC43QzIuMSwwLjcsMS40LDAsMS40LDB6Ii8+DQo8L3N2Zz4NCg==)}.lasso--post-form .control-dash input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0wLDN2Mmg4VjNIMHoiLz4NCjwvc3ZnPg0K)}.lasso--post-form .lasso--postsettings-cancel{background:0 0;color:#d9534f;position:relative;top:3px}.lasso--post-form .lasso--postsettings-cancel:hover{color:#d43f3a;text-decoration:none}.lasso--post-form input[type=submit]{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:none;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none;float:right}.lasso--post-form input[type=submit]:active,.lasso--post-form input[type=submit]:focus{outline:0}.lasso--post-form input[type=submit]:hover{text-decoration:none;color:#fff;background:#005678}.lasso--post-form input[type=submit]:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-group{text-align:center}.lasso--btn-group a{margin:0;display:inline-block}.lasso--btn-group.lasso--btn-group-small a{font-size:14px}.lasso--notice{text-align:center;max-width:500px;padding:10px;color:#fff;font-family:Arial;font-size:14px;margin:10px auto}.lasso--notice.lasso--notice-warning{background:#f0ad4e}.lasso--notice.lasso--notice-info{background:#007aab}.lasso--notice.lasso--notice-error{background:#d9534f}.lasso--notice.lasso--notice-success{background:#4da34d}#lasso--slider{position:relative;text-align:left;background:#32373c;top:5px;height:10px;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.2);box-shadow:inset 1px 1px 1px rgba(0,0,0,.2)}#lasso--slider .ui-slider-handle{position:absolute;z-index:2;width:22px;height:22px;cursor:default;-ms-touch-action:none;touch-action:none;background:#007aab;top:-6px;margin-left:-11px;border-radius:100%;-webkit-box-shadow:0 0 7px -1px rgba(0,0,0,.75);box-shadow:0 0 7px -1px rgba(0,0,0,.75)}#lasso--slider .ui-slider-handle:active,#lasso--slider .ui-slider-handle:focus{outline:0}#lasso--slider .ui-slider-handle:active,#lasso--slider .ui-slider-handle:hover{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.5);box-shadow:inset 0 0 6px rgba(0,0,0,.5)}#lasso--slider .ui-slider-handle:hover{border:4px solid #007aab}#lasso--slider .ui-slider-handle:active{border:4px solid #006f9c}#lasso--slider .ui-slider-handle:active,#lasso--slider .ui-slider-handle:focus,#lasso--slider .ui-slider-handle:hover{cursor:move}.lasso--select-wrap{position:relative;display:inline-block;color:#444}.lasso--select-wrap select{display:inline-block;width:100%;margin:0;line-height:30px;color:#e2e2e2;background-color:#32373c;border:0;padding:2px 25px 2px 12px;border-radius:4px;cursor:pointer;outline:0;font-size:15px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.lasso--select-wrap select:focus:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.lasso--select-wrap:after{position:absolute;top:50%;right:12px;display:inline-block;content:\"\";width:0;height:0;margin-top:-.15rem;pointer-events:none;border-top:4px solid #e2e2e2;border-right:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid transparent}.lasso--select-wrap select:active{color:#444;background-color:#32373c}.lasso--select-wrap select::-ms-expand{display:none}@-moz-document url-prefix(){select{text-indent:.01px;text-overflow:'';padding-right:1rem}option{background-color:#fff}}.lasso-modal-open{overflow:hidden}#lasso--modal__overlay{z-index:999;position:fixed;left:0;top:0;right:0;bottom:0;background:rgba(255,255,255,.85)}.lasso--modal{z-index:1001;position:fixed;display:table;left:0;right:0;bottom:0;width:100%;max-width:381px;margin:0 auto;font-family:Arial}.lasso--modal *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso--modal__inner{display:table-cell;vertical-align:middle;background:#23282d;border-radius:4px;border:1px solid #0d0e10;padding:18px;-webkit-box-shadow:0 0 10px 1px rgba(0,0,0,.5);box-shadow:0 0 10px 1px rgba(0,0,0,.5);color:#e2e2e2;position:relative}.lasso--modal__inner:after,.lasso--modal__inner:before{content:\" \";display:table}.lasso--modal__inner:after{clear:both}#lasso--modal__close{position:absolute;right:20px;top:10px}#lasso--modal__close:hover{cursor:pointer}.lasso--slider_wrap{padding:0 10px;height:18px}.lasso--postsettings__option{padding-bottom:20px;margin-bottom:20px;position:relative;line-height:1;border-bottom:1px solid #0d0e10;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.05);box-shadow:0 1px 1px rgba(255,255,255,.05)}.lasso--postsettings__option.lasso--last-option{border-bottom:none;margin-bottom:0;padding-bottom:0}.lasso--postsettings__option .story-status{margin:12px 0 8px;padding:0 10px;line-height:1}.lasso--postsettings__option .story-status:after,.lasso--postsettings__option .story-status:before{content:\" \";display:table}.lasso--postsettings__option .story-status:after{clear:both}.lasso--postsettings__option .story-status li{font-size:14px;float:left;list-style-type:none}.lasso--postsettings__option .story-status.story-status-draft #lasso--status-publish,.lasso--postsettings__option .story-status.story-status-publish #lasso--status-draft{opacity:.3;filter:alpha(opacity=30)}.lasso--postsettings__option .story-status #lasso--status-publish{float:right}.lasso--postsettings__option.story-slug-option .lasso--select-wrap{position:absolute;top:24px;left:1px}.lasso--postsettings__option.story-slug-option .lasso--select-wrap select{font-size:13px;border-radius:1px 0 0 1px}.lasso--postsettings__option.story-slug-option+.lasso--postsettings__footer{padding-top:inherit;padding-to:20px;margin-top:20px}.lasso--postsettings__option+.lasso--postsettings__footer{border-top:none;box-shadow:none;margin-top:0;padding-top:0}.lasso--postsettings__footer{text-align:right;font-size:16px;padding-top:20px;margin-top:22px;border-top:1px solid #0d0e10;-webkit-box-shadow:0 -1px 1px rgba(255,255,255,.05);box-shadow:0 -1px 1px rgba(255,255,255,.05)}.lasso--postsettings__footer a,.lasso--postsettings__footer input{display:inline-block}#lasso--postnew__form .story-slug-option{margin-bottom:0}#lasso--postnew__form .story-slug-option input[type=text]{padding-left:92px}#lasso--postnew__form .story-slug-option #lasso--select-type{height:35px}.lasso--modal__tabs{position:absolute;right:0;top:-36px;padding:0;margin:0;height:36px;list-style:none}.lasso--modal__tabs li{display:inline-block;background:#32373c;font-size:15px;border-top-left-radius:4px;border-top-right-radius:4px;padding:0 10px;margin:0 1px;height:36px;line-height:36px;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}.lasso--modal__tabs li.active-tab,.lasso--modal__tabs li:hover{cursor:pointer;background:#23282d}.lasso--modal__tabs li:last-child{margin-right:-1px}.lasso--modal__content #poststuff{min-width:1px}#lasso--post-settings__modal{max-width:600px}.lasso--postsettings__2col:after,.lasso--postsettings__2col:before{content:\" \";display:table}.lasso--postsettings__2col:after{clear:both}.lasso--postsettings__2col .lasso--postsettings__left,.lasso--postsettings__2col .lasso--postsettings__right{float:left}.lasso--postsettings__2col .lasso--postsettings__left{width:35%}.lasso--postsettings__2col .lasso--postsettings__left label{font-size:14px;line-height:1;display:block;margin-bottom:15px}.lasso--postsettings__2col .lasso--postsettings__left .lasso-util--help{left:6px;top:2px}.lasso--postsettings__2col .lasso--postsettings__right{width:62%;margin-left:3%}.story-slug-option,.story-tags-option{border-bottom:none;box-shadow:none;padding-bottom:0}.lasso--postsettings__middle{clear:left;padding-top:20px;border-top:1px solid #0d0e10;-webkit-box-shadow:inset 0 1px 1px rgba(255,255,255,.05);box-shadow:inset 0 1px 1px rgba(255,255,255,.05)}.lasso--post-thumb{position:relative}.lasso--post-thumb .lasso--post-thumb__controls{position:absolute;top:10px;left:10px;right:10px;z-index:1}.lasso--post-thumb .lasso--post-thumb__controls i{text-shadow:0 1px 1px rgba(0,0,0,.5);opacity:.6;filter:alpha(opacity=60);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease}.lasso--post-thumb .lasso--post-thumb__controls i:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100);-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.lasso--post-thumb .lasso--post-thumb__controls i:active{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);box-shadow:none}.lasso--post-thumb .lasso--post-thumb__controls #lasso--post-thumb__add{font-size:16px;top:2px;margin-right:-4px;position:relative}.lasso--post-thumb .lasso--post-thumb__controls #lasso--save-status{float:right;font-size:16px;position:relative;top:3px;right:3px;color:#4da34d}.lasso--post-thumb img{border:5px solid #32373c;border-radius:4px;width:196px;height:136px}#lasso--postsettings__form.no-thumbnail #lasso--post-thumb__delete{opacity:0;filter:alpha(opacity=0);display:none;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease}.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-ms-filter:\"alpha(Opacity=0)\";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;bottom:3px;height:8px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#32373c;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;bottom:0;height:8px}.ps-container>.ps-scrollbar-x-rail.in-scrolling{background-color:transparent;opacity:.9;-ms-filter:\"alpha(Opacity=90)\";filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-ms-filter:\"alpha(Opacity=0)\";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;right:3px;width:8px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#32373c;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;right:0;width:8px}.ps-container>.ps-scrollbar-y-rail.in-scrolling{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6;filter:alpha(opacity=60)}.ps-container:hover>.ps-scrollbar-x-rail.in-scrolling,.ps-container:hover>.ps-scrollbar-x-rail:hover,.ps-container:hover>.ps-scrollbar-y-rail.in-scrolling{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}.lasso-sidebar-open{overflow:hidden}.lasso-sidebar-open #lasso--sidebar,.lasso-sidebar-open .lasso-buttoninsert-wrap{right:0}#lasso--sidebar{z-index:9999;position:fixed;right:-285px;top:0;bottom:0;width:285px;-webkit-transition:right .25s ease;-moz-transition:right .25s ease;transition:right .25s ease}#lasso--sidebar *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso--sidebar code,#lasso--sidebar p{color:#e2e2e2;background:#23282d}.admin-bar #lasso--sidebar{top:32px}.admin-bar #lasso--component__settings form{padding-bottom:102px}.lasso--sidebar__inner{height:100%;font-family:Arial;font-size:14px;background:#23282d;border-left:4px solid #353c44;color:#e2e2e2;text-shadow:0 1px 1px rgba(0,0,0,.4);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-box-shadow:inset 9px 0 9px -9px #000;box-shadow:inset 9px 0 9px -9px #000}.lasso--sidebar__inner #lasso--sidebar__close{color:#007aab}.lasso--sidebar__inner #lasso--component__settings{overflow:hidden;position:relative}#lasso--sidebar__drag{height:100px;width:50px;background:red;top:50%;bottom:0;position:absolute}ul.lasso-component--controls{color:#e2e2e2;border:1px solid #181b1f;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);position:absolute;padding:0;line-height:1;height:26px;width:121px;top:4px;right:0;left:-10000px;text-align:center;margin:0 auto;border-radius:2px;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .4s ease;-moz-transition:opacity .4s ease;transition:opacity .4s ease;z-index:105}ul.lasso-component--controls *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.lasso-component--controls:after,ul.lasso-component--controls:before{content:\" \";display:table}ul.lasso-component--controls:after{clear:both}ul.lasso-component--controls li{float:left;list-style-type:none;line-height:1;width:29.51px;height:24px;border-right:1px solid #23282d;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4)}ul.lasso-component--controls li:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:relative;top:1px;font-size:15px}ul.lasso-component--controls li:first-child:hover{border-bottom-left-radius:2px;border-top-left-radius:2px}ul.lasso-component--controls li:hover{cursor:pointer;background:#39424a}ul.lasso-component--controls li:active{-webkit-box-shadow:inset 0 0 6px -2px rgba(0,0,0,.66);box-shadow:inset 0 0 6px -2px rgba(0,0,0,.66)}ul.lasso-component--controls li:last-child{border-right:none}ul.lasso-component--controls li:last-child:hover{border-top-right-radius:2px;border-bottom-right-radius:2px}ul.lasso-component--controls li.lasso-drag,ul.lasso-component--controls li.lasso-drag:hover{cursor:move}ul.lasso-component--controls li.lasso-drag:before{content:'\\e600'}ul.lasso-component--controls li.lasso-settings:before{content:'\\e994'}ul.lasso-component--controls li.lasso-clone:before{content:'\\e92c'}ul.lasso-component--controls li.lasso-delete:before{content:'\\e9ad'}.lasso-editing .aesop-component:hover .lasso-component--controls{left:4px;opacity:1;filter:alpha(opacity=100)}.aesop-timeline-stop .lasso-component--controls li{line-height:16px}.aesop-image-component[data-align=right]:hover .lasso-component--controls,.aesop-image-component[data-align=left]:hover .lasso-component--controls{margin:13px 0 0 4px}.aesop-image-component[data-align=right]:hover .lasso-component--controls{left:auto}#lasso--component__settings form{margin:0;position:relative;padding-bottom:70px}#lasso--component__settings .lasso-option-desc,#lasso--component__settings label{display:block;line-height:1.3}#lasso--component__settings h3,#lasso--component__settings label{font-weight:700;margin-bottom:3px;font-size:14px}#lasso--component__settings .lasso-option-desc{margin-bottom:5px;font-size:11.25px}#lasso--component__settings input[type=text],#lasso--component__settings input[type=text_small],#lasso--component__settings input[type=media_upload],#lasso--component__settings select,#lasso--component__settings textarea{background:#f8f8f8;width:100%;height:30px;border:1px solid #181b1f;border-radius:4px;line-height:1.8;padding:0 6px;color:#444;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);font-size:14px}#lasso--component__settings input[type=text]:focus,#lasso--component__settings input[type=text_small]:focus,#lasso--component__settings input[type=media_upload]:focus,#lasso--component__settings select:focus,#lasso--component__settings textarea:focus{box-shadow:none;outline:0;border:1px solid #007aab}#lasso--component__settings input[type=color]{border-radius:3px;border:1px solid #181b1f;padding:0 2px;height:30px;display:block}#lasso--component__settings input[type=color]:active,#lasso--component__settings input[type=color]:focus{box-shadow:none;outline:0;border:1px solid #007aab}#lasso--component__settings select{height:30px;box-shadow:none}#lasso--component__settings textarea{overflow:auto;margin:0;line-height:1.15;padding:6px;height:auto}#lasso--component__settings input[type=media_upload]{height:30px}#lasso--component__settings .lasso-generator-cancel,#lasso--component__settings input[type=submit]{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:none;display:inline-block;font-family:Arial;color:#fff;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none;font-size:15px}#lasso--component__settings .lasso-generator-cancel:active,#lasso--component__settings .lasso-generator-cancel:focus,#lasso--component__settings input[type=submit]:active,#lasso--component__settings input[type=submit]:focus{outline:0}#lasso--component__settings .lasso-generator-cancel:hover,#lasso--component__settings input[type=submit]:hover{text-decoration:none;color:#fff;background:#005678}#lasso--component__settings .lasso-generator-cancel:active,#lasso--component__settings input[type=submit]:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--component__settings .lasso-option-button{position:absolute;bottom:21px;right:21px;background-color:#4b5661;border-color:#2c3238;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.25);box-shadow:0 1px 1px rgba(0,0,0,.25)}#lasso--component__settings .lasso-option-button:hover{text-decoration:none;background:#3e474f}#lasso--component__settings .lasso-option-button:active,#lasso--component__settings .lasso-option-button:focus{outline:0;text-decoration:none;border-color:#21252a;background:#353c44;transition:none;-webkit-box-shadow:inset 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px rgba(0,0,0,.4)}#lasso--component__settings #lasso-upload-img{height:28px;padding:8px;border-top-right-radius:3px;border-bottom-right-radius:3px;font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#lasso--component__settings #lasso-upload-img:before{content:'\\e9c6';position:relative;color:#f8f8f8}#lasso--component__settings .lasso-generator-cancel{background:0 0;color:#d9534f;position:relative;top:-1px}#lasso--component__settings .lasso-generator-cancel:hover{color:#db5b57;background:0 0;text-decoration:none}#lasso--component__settings .lasso-generator-cancel:active{color:#d74b47;box-shadow:none}.lasso-option{position:relative;border-bottom:1px solid #181b1f;margin:0;padding:15px 20px 20px;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.05);box-shadow:0 1px 1px rgba(255,255,255,.05);-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}.lasso-option:after,.lasso-option:before{content:\" \";display:table}.lasso-option:after{clear:both}.lasso-option:hover{background:rgba(53,60,68,.5)}.lasso-buttoninsert-wrap{display:none;margin:0 auto;position:fixed;text-align:right;padding:20px;bottom:0;width:281px;height:70px;background:#353c44;right:-289px;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:right .25s ease;-moz-transition:right .25s ease;transition:right .25s ease;-webkit-box-shadow:0 -10px 10px -10px #000;box-shadow:0 -10px 10px -10px #000}.lasso-buttoninsert-wrap:after,.lasso-buttoninsert-wrap:before{content:\" \";display:table}.lasso-buttoninsert-wrap:after{clear:both}#lasso-generator-insert{text-align:center;float:right;display:block;margin:0 15px;padding:6px 10px;border-radius:2px;background:#007aab;border:1px solid #006892;color:#fff}#lasso-generator-insert:hover{text-decoration:none;background:#005678}#lasso-generator-insert:active,#lasso-generator-insert:focus{text-decoration:none;outline:0}#lasso-generator-insert:active{background:#00435e;-webkit-box-shadow:inset 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px rgba(0,0,0,.4)}#lasso-generator-insert.saved{background:#4da34d}.lasso-c-comp-text{position:absolute;right:-10000px;opacity:0;filter:alpha(opacity=0);height:0}#lasso--gallery__images{min-height:65px;position:relative}#lasso--gallery__images .lasso-icon-spinner6{position:relative;left:135px;top:18px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;font-size:16px}.editor-btn-secondary{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;font-size:17px;line-height:1.8;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.editor-btn-secondary:active,.editor-btn-secondary:visited{color:#e2e2e2}.editor-btn-secondary:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}.editor-btn-secondary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.editor-btn-secondary.lasso--btn-loading:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#ase-gallery-images{margin:0 -7px;border-radius:4px;padding:2px;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}#ase-gallery-images:after,#ase-gallery-images:before{content:\" \";display:table}#ase-gallery-images:after{clear:both}#ase-gallery-images .ui-state-highlight{height:1.5em;line-height:1.2em}.ase-gallery-image{position:relative;float:left;margin:4px;-webkit-transition:transform .1s ease;-moz-transition:transform .1s ease;transition:transform .1s ease;list-style:none}.ase-gallery-image i{top:3px;position:absolute;z-index:1;color:#fff;font-size:16px;text-shadow:0 1px 1px rgba(0,0,0,.5);opacity:.6;filter:alpha(opacity=60);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease}.ase-gallery-image i:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100);-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.ase-gallery-image i:active{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);box-shadow:none}.ase-gallery-image .dashicons-edit{left:3px}.ase-gallery-image .dashicons-no-alt{right:2px}.ase-gallery-image img{max-width:54px;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.ase-gallery-image.ui-sortable-helper{-ms-transform:rotate(7deg);-webkit-transform:rotate(7deg);transform:rotate(7deg)}.ase-gallery-image:hover{cursor:move}.ase-gallery-image:hover img{opacity:.66;filter:alpha(opacity=66)}.ase-gallery-opts--edit-gallery:hover #ase-gallery-images{background:#181b1f;-webkit-box-shadow:inset 0 -1px 1px rgba(255,255,255,.1);box-shadow:inset 0 -1px 1px rgba(255,255,255,.1)}.lasso-editor-tiny-btn{font-size:10px;background:#181b1f;color:rgba(226,226,226,.8);border-radius:100%;font-weight:400;height:18px;width:18px;line-height:20px;text-align:center;text-shadow:1px 1px rgba(0,0,0,.1)}.lasso-editor-tiny-btn:active,.lasso-editor-tiny-btn:focus,.lasso-editor-tiny-btn:hover{outline:0;color:rgba(226,226,226,.8);text-decoration:none}.lasso-editor-tiny-btn:hover{color:rgba(226,226,226,.8);background:rgba(0,122,171,.8)}.lasso-editor-tiny-btn:active{color:rgba(226,226,226,.8);background:#007aab}#ase-gallery-add-image{position:absolute;right:12px;font-size:9px}.ase-gallery-drop-zone{border:1px solid #23282d;background:#353c44;color:#363636;width:54px;height:54px;float:left;margin:4px;border-radius:2px}#lasso--component__settings .ase-gallery-layout-label{font-size:12px}.ase-gallery-opts--type{position:relative}.ase-gallery-opts--type h3{margin:0}.ase-gallery-opts--type input[type=radio]{position:absolute;opacity:0;z-index:-1}.ase-gallery-opts--type .ase-gallery-layout-label{position:relative;float:left;height:68px;width:78px;overflow:hidden;text-align:center;background:#353c44;padding:5px;box-sizing:border-box;border:1px solid #181b1f;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;opacity:.3;filter:alpha(opacity=30);margin-right:2px;font-weight:400}.ase-gallery-opts--type .ase-gallery-layout-label:last-of-type{margin-right:0!important}.ase-gallery-opts--type .ase-gallery-layout-label:after{content:'';background-image:url(../img/layout-sprite.png);background-size:84%;position:absolute;height:42px;display:block;left:0;right:0;bottom:0}.ase-gallery-opts--type .ase-gallery-layout-label:hover{opacity:1;filter:alpha(opacity=100);cursor:pointer}.ase-gallery-opts--type .ase-gallery-layout-label:active{background:#2c3238;-webkit-box-shadow:inset 0 0 6px -1px rgba(0,0,0,.5);box-shadow:inset 0 0 6px -1px rgba(0,0,0,.5)}.ase-gallery-opts--type .selected{-webkit-box-shadow:inset 0 0 12px -2px rgba(0,0,0,.5);box-shadow:inset 0 0 12px -2px rgba(0,0,0,.5);opacity:1;filter:alpha(opacity=100)}.ase-gallery-opts--type label:first-of-type:after{background-position:5px -9px}.ase-gallery-opts--type label:nth-of-type(2):after{background-position:5px -52px}.ase-gallery-opts--type label:nth-of-type(3):after{background-position:5px -99px}.ase-gallery-opts--type label:nth-of-type(4):after{background-position:5px -145px}.ase-gallery-opts--type label:nth-of-type(5):after{background-position:5px -191px}.ase-gallery-opts--type label:last-of-type:after{background-position:5px -470px}.ase-gallery-opts{-webkit-transition:opacity .25s ease;-moz-transition:opacity .25s ease;transition:opacity .25s ease}.lasso--empty-component{height:0;opacity:0;filter:alpha(opacity=0);text-align:center;color:#444;font-family:Arial;font-size:20px;-webkit-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear}.lasso--empty-component span{position:relative;top:2px}.lasso-editing .aesop-gallery-component.empty-gallery .lasso-component--controls,.lasso-editing .lasso--empty-component+.aesop-map-component .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}.lasso-editing .lasso--empty-component{height:150px;padding-top:75px;opacity:1;filter:alpha(opacity=100)}#lasso--component__settings.gallery-no-images .ase-gallery-opts:not(.ase-gallery-opts--create-gallery){display:none}#lasso--component-settings-form.creating-gallery .lasso-option.lasso-gallery-id,#lasso--component-settings-form.has-galleries .ase-gallery-opts--create-gallery{display:none}#lasso--component-settings-form.hide-all-fields .ase-gallery-opts{opacity:0;filter:alpha(opacity=0)}#lasso--map-form{position:relative}#lasso--map-form .lasso--map-form__submit{position:absolute;top:10px;right:10px;z-index:100;background:#007aab;border:1px solid #0073a1;padding:8px 12px;font-size:14px;line-height:1.2;font-family:Arial;text-shadow:1px 1px rgba(0,0,0,.1);-webkit-box-shadow:0 0 5px -1px rgba(0,0,0,.4);box-shadow:0 0 5px -1px rgba(0,0,0,.4)}#lasso--map-form .lasso--map-form__submit:active,#lasso--map-form .lasso--map-form__submit:focus{outline:0}#lasso--map-form .lasso--map-form__submit:hover{background:#005678;border:1px solid #004e6e}#lasso--map-form .lasso--map-form__submit:active{box-shadow:none}#lasso--map-form{margin-top:10px}#lasso--map-form .leaflet-popup-content-wrapper,#lasso--map-form .leaflet-popup-tip{border-radius:4px}#lasso--map-form .leaflet-popup-content-wrapper input,#lasso--map-form .leaflet-popup-tip input{font-size:14px;border-radius:0;padding:3px 5px;width:200px;display:inline-block;line-height:1}#lasso--map-form .leaflet-popup-content{margin:10px}#lasso--map-form .leaflet-popup-close-button{position:absolute;left:-10000px;height:0}#lasso--map-form .marker-delete-button,#lasso--map-form .marker-update-button{color:#fff;box-shadow:none;border:none;border-radius:3px;display:inline-block;height:25px;width:25px;vertical-align:top;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;text-align:center}#lasso--map-form .marker-delete-button:hover,#lasso--map-form .marker-update-button:hover{cursor:pointer}#lasso--map-form .marker-delete-button:active,#lasso--map-form .marker-update-button:active{outline:0;focus:none;box-shadow:none}#lasso--map-form .marker-delete-button:before,#lasso--map-form .marker-update-button:before{position:relative;text-align:center}#lasso--map-form .marker-update-button{background:#007aab}#lasso--map-form .marker-update-button:hover{background:#00648c}#lasso--map-form .marker-update-button:active{background:#005678}#lasso--map-form .marker-update-button:before{top:1px;left:-1px;font-size:24px}#lasso--map-form .marker-delete-button{background:#d9534f}#lasso--map-form .marker-delete-button:hover{background:#d43a36}#lasso--map-form .marker-delete-button:active{background:#c9302c}#lasso--map-form .marker-delete-button:before{font-size:17px;top:1px;left:1px}.aesop-map-component .lasso-component--controls{width:91px}.aesop-map-component .lasso-component--controls .lasso-clone{display:none}.aesop-sticky-map #lasso--map-form .lasso-component--controls{position:fixed;z-index:999;width:61px}.aesop-sticky-map #lasso--map-form .lasso-component--controls .lasso-drag{display:none}.aesop-sticky-map.aesop-sticky-map-left #lasso--map-form .lasso-component--controls{left:183px;right:auto}.aesop-sticky-map.aesop-sticky-map-right #lasso--map-form .lasso-component--controls{right:183px;left:auto}#lasso--featImgControls{position:relative;z-index:1;left:0;right:0;text-align:center;top:5px;width:30px;height:26px;padding:0;margin:0 auto;font-size:15px;border-radius:2px;line-height:0;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--featImgControls.lasso--featImg--has-thumb{width:60px}#lasso--featImgControls.lasso--featImg--has-thumb #lasso--featImgDelete{opacity:1;filter:alpha(opacity=100)}#lasso--featImgControls li{float:left;list-style-type:none;line-height:0;width:30px;height:26px;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4)}#lasso--featImgControls li i{font-style:normal;position:relative;top:5px}#lasso--featImgControls li:before{position:relative;top:3px;font-size:15px}#lasso--featImgControls li:hover{cursor:pointer;background:#39424a}#lasso--featImgControls li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4)}#lasso--featImgControls #lasso--featImgSave,#lasso--featImgControls .lasso--featImg--controlHidden{position:absolute;left:-1000px;height:0;opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls #lasso--featImgDelete{opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls a{color:#fff;display:block}#lasso--featImgControls a:hover{text-decoration:none}.lasso--wpimg__wrap,.lasso--wpquote{position:relative}.lasso--wpimg__wrap:hover .lasso-component--controls,.lasso--wpquote:hover .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}.lasso--wpquote .lasso-component--controls{width:91px}.lasso--wpquote .lasso-component--controls #lasso-component--settings__trigger{position:absolute;left:-10000px;height:0;opacity:0;filter:alpha(opacity=0);display:none}.sweet-overlay{background-color:rgba(0,0,0,.4);position:fixed;left:0;right:0;top:0;bottom:0;display:none;z-index:1000}.sweet-alert{background-color:#1f2327;font-family:Arial;width:478px;padding:17px;border-radius:5px;text-align:center;position:fixed;left:50%;top:50%;margin-left:-256px;margin-top:-200px;overflow:hidden;display:none;z-index:2000;-webkit-box-shadow:0 0 10px 1px rgba(0,0,0,.5);box-shadow:0 0 10px 1px rgba(0,0,0,.5)}@media all and (max-width:540px){.sweet-alert{width:auto;margin-left:0;margin-right:0;left:15px;right:15px}}.sweet-alert h2{color:#e2e2e2;font-size:30px;text-align:center;font-weight:600;text-transform:none;position:relative;margin:25px 0;padding:0;line-height:40px;display:block;font-family:inherit}.sweet-alert p{color:#e2e2e2;font-size:16px;font-weight:300;position:relative;text-align:inherit;float:none;margin:0;padding:0;line-height:normal}.sweet-alert p~button{margin-bottom:20px}.sweet-alert button{background-color:#007aab;color:#fff;border:none;box-shadow:none;font-size:17px;font-family:Arial;font-weight:500;border-radius:5px;padding:10px 32px;margin:26px 5px 0;cursor:pointer}.sweet-alert button:focus{outline:0;box-shadow:0 0 2px rgba(128,179,235,.5),inset 0 0 0 1px rgba(0,0,0,.05)}.sweet-alert button:hover{background-color:#a1d9f2}.sweet-alert button:active{background-color:#81ccee}.sweet-alert button.cancel{background:0 0;color:#d9534f}.sweet-alert button.cancel:active,.sweet-alert button.cancel:hover{background:0 0}.sweet-alert button.cancel:focus{box-shadow:rgba(197,205,211,.8) 0 0 2px,rgba(0,0,0,.0470588) 0 0 0 1px inset!important}.sweet-alert button::-moz-focus-inner{border:0}.sweet-alert .icon{width:80px;height:80px;border:4px solid gray;border-radius:50%;margin:20px auto;padding:0;position:relative;box-sizing:content-box}.sweet-alert .icon.error{border-color:#d9534f}.sweet-alert .icon.error .x-mark{position:relative;display:block}.sweet-alert .icon.error .line{position:absolute;height:5px;width:47px;background-color:#d9534f;display:block;top:37px;border-radius:2px}.sweet-alert .icon.error .line.left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.sweet-alert .icon.error .line.right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}.sweet-alert .icon.warning{border-color:#d9534f}.sweet-alert .icon.warning .body{position:absolute;width:5px;height:47px;left:50%;top:10px;border-radius:2px;margin-left:-2px;background-color:#d9534f}.sweet-alert .icon.warning .dot{position:absolute;width:7px;height:7px;border-radius:50%;margin-left:-3px;left:50%;bottom:10px;background-color:#d9534f}.sweet-alert .icon.info{border-color:#007aab}.sweet-alert .icon.info::before{content:\"\";position:absolute;width:5px;height:29px;left:50%;bottom:17px;border-radius:2px;margin-left:-2px;background-color:#007aab}.sweet-alert .icon.info::after{content:\"\";position:absolute;width:7px;height:7px;border-radius:50%;margin-left:-3px;top:19px;background-color:#007aab}.sweet-alert .icon.success{border-color:#A5DC86}.sweet-alert .icon.success::after,.sweet-alert .icon.success::before{content:'';position:absolute;width:60px;height:120px;background:#fff;-webkit-transform:rotate(45deg)}.sweet-alert .icon.success::before{border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.sweet-alert .icon.success::after{border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px}.sweet-alert .icon.success .placeholder{width:80px;height:80px;border:4px solid rgba(165,220,134,.2);border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.sweet-alert .icon.success .fix{width:5px;height:90px;background-color:#fff;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .icon.success .line{height:5px;background-color:#A5DC86;display:block;border-radius:2px;position:absolute;z-index:2}.sweet-alert .icon.success .line.tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .icon.success .line.long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .icon.custom{background-size:contain;border-radius:0;border:none;background-position:center center;background-repeat:no-repeat}.sweet-alert[data-has-cancel-button=false] button{box-shadow:none!important}@-webkit-keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-moz-keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-webkit-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@-moz-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}.showSweetAlert{-webkit-animation:showSweetAlert .2s;-moz-animation:showSweetAlert .2s;animation:showSweetAlert .2s}.hideSweetAlert{-webkit-animation:hideSweetAlert .2s;-moz-animation:hideSweetAlert .2s;animation:hideSweetAlert .2s}.animateSuccessTip{-webkit-animation:animateSuccessTip .75s;-moz-animation:animateSuccessTip .75s;animation:animateSuccessTip .75s}.animateSuccessLong{-webkit-animation:animateSuccessLong .75s;-moz-animation:animateSuccessLong .75s;animation:animateSuccessLong .75s}.icon.success.animate::after{-webkit-animation:rotatePlaceholder 4.25s ease-in;-moz-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}.lasso-util--help{position:relative;cursor:pointer;color:#007aab;display:inline-block;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;opacity:.75;filter:alpha(opacity=75)}.lasso-util--help:hover{text-decoration:none;opacity:1;filter:alpha(opacity=100)}.lasso-util--help:after,.lasso-util--help:before{position:absolute;visibility:hidden;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-webkit-transform .2s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-moz-transform .2s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .2s ease-in-out,visibility .2s ease-in-out,transform .2s cubic-bezier(.71,1.7,.77,1.24);-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translate3d(0,0,0);pointer-events:none}.lasso-util--help:focus:after,.lasso-util--help:focus:before,.lasso-util--help:hover:after,.lasso-util--help:hover:before{visibility:visible;opacity:1;filter:alpha(opacity=100)}.lasso-util--help:before{z-index:1001;border:6px solid transparent;background:0 0;content:\"\"}.lasso-util--help:after{z-index:1000;padding:8px;width:160px;background-color:rgba(0,122,171,.95);color:#e2e2e2;font-family:Arial;content:attr(data-tooltip);font-size:12px;line-height:1.2;border-radius:2px}.lasso-util--help-top:after,.lasso-util--help-top:before,.lasso-util--help:after,.lasso-util--help:before{bottom:100%;left:50%}.lasso-util--help-top:before,.lasso-util--help:before{margin-left:-6px;margin-bottom:-12px;border-top-color:rgba(0,122,171,.95)}.lasso-util--help-top:after,.lasso-util--help:after{margin-left:-80px}.lasso-util--help-top:focus:after,.lasso-util--help-top:focus:before,.lasso-util--help-top:hover:after,.lasso-util--help-top:hover:before,.lasso-util--help:focus:after,.lasso-util--help:focus:before,.lasso-util--help:hover:after,.lasso-util--help:hover:before{-webkit-transform:translateY(-12px);-moz-transform:translateY(-12px);transform:translateY(-12px)}.lasso-util--help-left:after,.lasso-util--help-left:before{right:100%;bottom:50%;left:auto}.lasso-util--help-left:before{margin-left:0;margin-right:-12px;margin-bottom:0;border-top-color:transparent;border-left-color:rgba(0,122,171,.95)}.lasso-util--help-left:focus:after,.lasso-util--help-left:focus:before,.lasso-util--help-left:hover:after,.lasso-util--help-left:hover:before{-webkit-transform:translateX(-12px);-moz-transform:translateX(-12px);transform:translateX(-12px)}.lasso-util--help-bottom:after,.lasso-util--help-bottom:before{top:100%;bottom:auto;left:50%}.lasso-util--help-bottom:before{margin-top:-12px;margin-bottom:0;border-top-color:transparent;border-bottom-color:rgba(0,122,171,.95)}.lasso-util--help-bottom:focus:after,.lasso-util--help-bottom:focus:before,.lasso-util--help-bottom:hover:after,.lasso-util--help-bottom:hover:before{-webkit-transform:translateY(12px);-moz-transform:translateY(12px);transform:translateY(12px)}.lasso-util--help-right:after,.lasso-util--help-right:before{bottom:50%;left:100%}.lasso-util--help-right:before{margin-bottom:0;margin-left:-12px;border-top-color:transparent;border-right-color:rgba(0,122,171,.95)}.lasso-util--help-right:focus:after,.lasso-util--help-right:focus:before,.lasso-util--help-right:hover:after,.lasso-util--help-right:hover:before{-webkit-transform:translateX(12px);-moz-transform:translateX(12px);transform:translateX(12px)}.lasso-util--help-left:before,.lasso-util--help-right:before{top:3px}.lasso-util--help-left:after,.lasso-util--help-right:after{margin-left:0;margin-bottom:-16px}.story-categories-option .tagit,.story-tags-option .tagit{padding:4px 0 0;overflow:auto;margin-left:inherit;margin-right:inherit;border-radius:3px;list-style:none}.story-categories-option .tagit li,.story-tags-option .tagit li{float:left}.story-categories-option .tagit li.tagit-choice,.story-tags-option .tagit li.tagit-choice{position:relative;margin:2px;display:inline;padding:4px 8px 4px 18px;font-family:Arial;font-size:12px;line-height:16px;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:2px;background:#32373c}.story-categories-option .tagit li .tagit-close,.story-tags-option .tagit li .tagit-close{cursor:pointer;position:absolute;left:7px;color:#fff;top:5px}.story-categories-option .tagit li .tagit-close:hover,.story-tags-option .tagit li .tagit-close:hover{text-decoration:none;color:#fff}.story-categories-option .tagit li.tagit-new,.story-tags-option .tagit li.tagit-new{position:relative;top:-6px}.story-categories-option .tagit li input[type=text],.story-tags-option .tagit li input[type=text]{box-shadow:none;border:none;border-radius:0;padding:0 0 0 4px;width:inherit;background-color:inherit;outline:0;font-size:12px;line-height:24px;display:inline-block;margin:2px 5px 2px 0;color:rgba(255,255,255,.5)}.story-categories-option input.tagit-hidden-field,.story-tags-option input.tagit-hidden-field{display:none}.story-categories-option ul.tagit li.tagit-choice a.tagit-label,.story-tags-option ul.tagit li.tagit-choice a.tagit-label{cursor:pointer;text-decoration:none}.story-categories-option{border-bottom:none;box-shadow:none;margin-bottom:0}.story-tags-option .tagit li.tagit-choice{position:relative;margin:2px 2px 2px 15px;padding:4px 8px 4px 12px;border-top-left-radius:0;border-bottom-left-radius:0}.story-tags-option .tagit li.tagit-choice:before{content:'';position:absolute;width:0;height:0;border-top:12px solid transparent;border-bottom:12px solid transparent;border-right:14px solid #32373c;left:-14px;top:0}.story-tags-option .tagit li.tagit-choice .tagit-close{left:0}.lasso-modal-open .ui-autocomplete{position:absolute;top:100%;left:0;z-index:9999;float:left;display:none;min-width:160px;padding:4px;margin:2px 0 0;list-style:none;color:#fff;background-color:#32373c;border-radius:3px;box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.lasso-modal-open .ui-autocomplete .ui-menu-item{display:block;padding:1px 2px;clear:both;font-weight:400;line-height:18px;color:#fff;white-space:nowrap;font-family:Arial;font-size:14px}.lasso-modal-open .ui-autocomplete .ui-menu-item.ui-state-active,.lasso-modal-open .ui-autocomplete .ui-menu-item:hover{cursor:pointer;background:#222529}.lasso--tour__modal .lasso--postsettings__footer:after,.lasso--tour__modal .lasso--postsettings__footer:before{content:\" \";display:table}.lasso--tour__modal .lasso--postsettings__footer:after{clear:both}.lasso--tour__modal .lasso--modal__inner{position:relative}.lasso--tour__modal .lasso--postsettings__option{border-bottom:none;box-shadow:none;padding-bottom:0;margin-bottom:0;float:left;top:4px;position:relative;opacity:.85;filter:alpha(opacity=85)}.lasso--tour__modal .lasso--postsettings__option label{padding-left:23px;font-size:14px;font-weight:400}.lasso--tour__modal .lasso--postsettings__option .control-indicator{width:14px;height:14px;top:0}.lasso--tour__modal #lasso--tour__slides{position:relative;overflow:auto;display:none}.lasso--tour__modal ul{margin:0;padding:0;list-style:none}.lasso--tour__modal ul:after,.lasso--tour__modal ul:before{content:\" \";display:table}.lasso--tour__modal ul:after{clear:both}.lasso--tour__modal ul li{float:left}.lasso--tour__modal li img{background:#0d0e10;padding:6px;border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.1);box-shadow:0 1px 1px rgba(255,255,255,.1)}.lasso--tour__modal li p{font-family:Arial;font-size:16px;line-height:1.25;margin:15px auto 28px;padding-right:4px;padding-left:4px}.lasso--tour__modal .dots{position:absolute;left:0;right:0;bottom:-10px;text-align:center;width:100%;margin:0}.lasso--tour__modal .dots li{display:inline-block;width:14px;height:14px;line-height:16px;margin:0 3px;text-indent:-999em;border:1px solid #0d0e10;background:#32373c;border-radius:100%;cursor:pointer;opacity:.4;filter:alpha(opacity=40);-webkit-transition:background .5s,opacity .5s;-moz-transition:background .5s,opacity .5s;transition:background .5s,opacity .5s;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.1);box-shadow:0 1px 1px rgba(255,255,255,.1)}.lasso--tour__modal .dots li.active{background:rgba(0,122,171,.75);opacity:1}.lasso--tour__modal input[type=submit]{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:none;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none}.lasso--tour__modal input[type=submit]:active,.lasso--tour__modal input[type=submit]:focus{outline:0}.lasso--tour__modal input[type=submit]:hover{text-decoration:none;color:#fff;background:#005678}.lasso--tour__modal input[type=submit]:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--loading{height:auto;left:0;top:0;right:0;width:100%}.lasso--loader{height:40px;width:40px;margin:10px auto;top:48%;position:relative;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:3px solid rgba(96,106,116,.2);border-right:3px solid rgba(96,106,116,.2);border-bottom:3px solid rgba(96,106,116,.2);border-top:3px solid #606a74;border-radius:100%}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{from{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{from{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.lasso--modal{top:10vh}.lasso--modal.lasso--modal__full{width:100%;max-width:800px}.lasso--modal.lasso--modal__full .lasso--modal__inner{display:block;padding:36px}.lasso--modal.lasso--modal__full .lasso--modal__inner:after,.lasso--modal.lasso--modal__full .lasso--modal__inner:before{content:\" \";display:table}.lasso--modal.lasso--modal__full .lasso--modal__inner:after{clear:both}#lasso--all-posts__modal #lasso--loading{position:absolute;height:90%}ul.lasso--post-list,ul.lasso--post-object-list{text-align:left;list-style:none;margin:0;padding:0}ul.lasso--post-list li,ul.lasso--post-object-list li{display:block;position:relative;width:100%;list-style-type:none;margin-bottom:7px;font-size:14px;font-family:Arial;font-weight:700}ul.lasso--post-object-list{width:100px;float:left;height:100%}ul.lasso--post-object-list li{line-height:25px;margin-bottom:0;font-family:Arial;font-weight:400;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}ul.lasso--post-object-list li:not(.active){opacity:.45;filter:alpha(opacity=45)}ul.lasso--post-object-list li:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100)}.lasso--post-filtering{padding:0 18px;width:calc(100% - 100px);height:42px;float:right}.lasso--post-filtering:after,.lasso--post-filtering:before{content:\" \";display:table}.lasso--post-filtering:after{clear:both}.lasso--post-filtering .lasso--search,.lasso--post-filtering .lasso--search__results{float:left}.lasso--post-filtering .lasso--search__results{opacity:0;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease;width:60%;font-size:15px}.lasso--post-filtering .lasso--search__results span{font-weight:700;margin-right:4px}.lasso--post-filtering .lasso--search{width:40%;overflow:hidden;position:relative}.lasso--post-filtering .lasso--search #lasso--search__toggle,.lasso--post-filtering .lasso--search input{-webkit-transition:right .15s linear;-moz-transition:right .15s linear;transition:right .15s linear}.lasso--post-filtering .lasso--search #lasso--search__toggle{position:relative;top:7.5px;right:-209px}.lasso--post-filtering .lasso--search #lasso--search__toggle:before{opacity:.5;filter:alpha(opacity=50);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--post-filtering .lasso--search #lasso--search__toggle:hover{cursor:pointer}.lasso--post-filtering .lasso--search #lasso--search__toggle:hover:before{opacity:.9;filter:alpha(opacity=90)}.lasso--post-filtering .lasso--search input{float:right;width:194px;right:-194px;background-color:#f8f8f8!important;padding:2px 8px 2px 6px;background:0 0;border:1px solid #181b1f;color:#444;font-size:14px;z-index:0;position:relative;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);height:32px}.lasso--post-filtering .lasso--search input:focus{outline:0;border:1px solid #007aab;border-radius:2px;box-shadow:none}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle{right:-15px}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle:before{opacity:.9;filter:alpha(opacity=90)}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle:hover:before{opacity:.5;filter:alpha(opacity=50)}.lasso--post-filtering .lasso--search.lasso--search__visible input{right:0}#lasso--helper{position:absolute;right:4px;top:4px;font-size:12px;padding:2px 6px;background:#32373c;color:#fff;border-radius:2px;font-family:Arial}#lasso--clear-search{position:absolute;right:7px;top:7px;color:#c9c9c9;z-index:1}#lasso--clear-search:hover{color:#bcbcbc;cursor:pointer}.lasso--empty-state{max-width:200px;text-align:center;color:#737679;margin:0 auto;top:40%;position:relative}.lasso--empty-state .lasso--empty-state-icon{font-size:50px}.lasso--empty-state p{margin-bottom:0;font-family:Arial;font-size:90%;font-weight:700}.lasso--empty-state p+a{margin-top:10px}ul.lasso--post-list{float:left;padding:0 18px;width:calc(100% - 100px);overflow:hidden;position:relative;height:520px;border-left:1px solid #181b1f;-webkit-box-shadow:inset 1px 0 1px -1px rgba(255,255,255,.15);box-shadow:inset 1px 0 1px -1px rgba(255,255,255,.15)}ul.lasso--post-list li{overflow:hidden;line-height:50px}ul.lasso--post-list .lasso--post-list__item{color:#c9c9c9;display:block;padding:0 15px;background:rgba(50,55,60,.88);text-decoration:none;border-radius:4px;-webkit-transition:all .15s ease;-moz-transition:all .15s ease;transition:all .15s ease;font-family:Arial;font-weight:400;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ul.lasso--post-list .lasso--post-list__item:before{content:'';height:8px;width:8px;border-radius:100%;margin-right:8px;display:inline-block}ul.lasso--post-list .lasso--post-list__item.draft:before{background:#f0ad4e}ul.lasso--post-list .lasso--post-list__item.publish:before{background:#4da34d}ul.lasso--post-list .lasso--post-list__item.pending:before{background:#007aab}ul.lasso--post-list .lasso--post-list__item:hover{background:#32373c;text-decoration:none;width:calc(100% - 115px)}ul.lasso--post-list .lasso--post-list__item:hover .lasso--post-list__controls{right:0}ul.lasso--post-list .lasso--post-list__item:active{outline:0;background:#32373c;text-decoration:none;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.5);box-shadow:inset 1px 1px 2px rgba(0,0,0,.5)}ul.lasso--post-list .lasso--post-list__item:focus{outline:0}ul.lasso--post-list .lasso--post-list__item.no-delete:hover{width:calc(100% - 57.5px)}.lasso--post-list__controls{position:absolute;top:0;width:115px;text-align:right;right:-115px;height:50px;-webkit-transition:right .15s ease;-moz-transition:right .15s ease;transition:right .15s ease}.lasso--post-list__controls span{color:#626262;display:inline-block;width:50px;height:50px;background:#32373c;border-radius:4px;position:relative}.lasso--post-list__controls span:after{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;font-size:18px;position:absolute;z-index:2;top:16px;left:16px}.lasso--post-list__controls span:hover{color:#626262;background:rgba(50,55,60,.5)}.lasso--post-list__controls span:active{background:#32373c;text-decoration:none;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.5);box-shadow:inset 1px 1px 2px rgba(0,0,0,.5)}.lasso--post-list__controls #lasso--post__edit{margin-right:3px}.lasso--post-list__controls #lasso--post__edit:hover{color:#e2e2e2;background:#007aab}.lasso--post-list__controls #lasso--post__edit:after{content:'\\e908'}.lasso--post-list__controls #lasso--post__delete:hover{color:#e2e2e2;background:#d9534f}.lasso--post-list__controls #lasso--post__delete:after{content:'\\e9ad'}#lasso--load-more{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;font-size:15px;text-transform:uppercase;line-height:2;margin-top:10px;opacity:.66;filter:alpha(opacity=66)}#lasso--load-more:active,#lasso--load-more:visited{color:#e2e2e2}#lasso--load-more:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}#lasso--load-more:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--load-more.lasso--btn-loading:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#lasso--revision__modal{-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--revision__modal .lasso--slider_wrap{padding:0 16px;margin-top:18px}#lasso--revision__modal .lasso--btn-group .lasso--btn-secondary{opacity:.7;filter:alpha(opacity=70);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--revision__modal .lasso--btn-group .lasso--btn-secondary:hover{opacity:1;filter:alpha(opacity=100)}#lasso--revision__modal .lasso-icon-move{position:absolute;top:15px;right:15px;color:#747474;font-size:14px}#lasso--revision__modal .lasso-icon-move:hover{cursor:move}#lasso--revision-list{margin:0 0 10px;padding:0;list-style:none;text-align:center;width:110%;left:-5%;position:relative;top:-3px}#lasso--revision-list:after,#lasso--revision-list:before{content:\" \";display:table}#lasso--revision-list:after{clear:both}#lasso--revision-list li{padding:12px 0 0;display:inline-block;font-family:Arial;font-size:11px;color:#c9c9c9;text-transform:uppercase;line-height:13px;margin:0 auto;position:relative}#lasso--revision-list li span{color:#c9c9c9}#lasso--revision-list li:first-child{margin-left:0}#lasso--revision-list li:last-child{margin-right:0}#lasso--revision-list li:before{content:'';height:5px;border-right:1px solid #747474;width:1px;position:absolute;top:0;left:0;right:0;text-align:center;margin:0 auto}#lasso--revision-list[data-count=\"6\"] li{width:16.666666%}#lasso--revision-list[data-count=\"6\"] li[data-revision=\"0\"],#lasso--revision-list[data-count=\"6\"] li[data-revision=\"1\"]{left:2px}#lasso--revision-list[data-count=\"6\"] li[data-revision=\"5\"]{right:-1px}#lasso--revision-list[data-count=\"6\"] li[data-revision=\"6\"]{right:6px}#lasso--revision-list[data-count=\"5\"] li{width:20%}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"0\"]{left:-4px}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"1\"]{left:-2px}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"2\"]{left:0}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"3\"]{right:-2px}#lasso--revision-list[data-count=\"5\"] li[data-revision=\"4\"]{right:-4px}#lasso--revision-list[data-count=\"4\"] li{width:25%}#lasso--revision-list[data-count=\"4\"] li[data-revision=\"0\"]{left:-15px}#lasso--revision-list[data-count=\"4\"] li[data-revision=\"1\"]{left:-4px}#lasso--revision-list[data-count=\"4\"] li[data-revision=\"2\"]{right:-4px}#lasso--revision-list[data-count=\"4\"] li[data-revision=\"3\"]{right:-15px}#lasso--revision-list[data-count=\"3\"] li{width:33.333%}#lasso--revision-list[data-count=\"3\"] li[data-revision=\"0\"]{left:-29px}#lasso--revision-list[data-count=\"3\"] li[data-revision=\"1\"]{left:0}#lasso--revision-list[data-count=\"3\"] li[data-revision=\"2\"]{right:-29px}#lasso--revision-list[data-count=\"2\"] li{width:50%}#lasso--revision-list[data-count=\"2\"] li[data-revision=\"0\"]{left:-60px}#lasso--revision-list[data-count=\"2\"] li[data-revision=\"1\"]{right:-60px}.os-ios .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}@media (max-width:600px){.lasso-editing .lasso--toolbar_wrap,.lasso-editing .lasso--toolbar_wrap.ase-not-active,.lasso-editing .lasso--toolbar_wrap.ase-not-active.toolbar-extended,.lasso-editing .lasso--toolbar_wrap.toolbar-extended{border-radius:0;top:0;width:100%;left:0;right:0;-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0);height:auto;bottom:auto}.lasso-editing .lasso--controls__right{z-index:1000;top:auto;right:0}.lasso-editing .lasso--controls__right #lasso--save,.lasso-editing .lasso--controls__right a{background:0 0}.lasso-editing .lasso--controls__right #lasso--save:before{color:#007aab;top:3px}.lasso-editing #lasso-toolbar--html.html--drop-down,.lasso-editing #lasso-toolbar--link.link--drop-down{position:static}.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--link__wrap,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--html__wrap,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap{left:0;right:0;top:44px;bottom:auto;width:90%}.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--link__wrap:after,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--html__wrap:after,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{margin:0;top:-6px;border-top:none;border-bottom:6px solid #39424a}.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{left:142px}.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{left:175px}.lasso-editing #lasso-toolbar--components.toolbar--drop-down{position:static}.lasso-editing #lasso-toolbar--components.toolbar--drop-down ul{top:44px;left:0;right:0;width:100%}.lasso-editing #lasso-toolbar--components.toolbar--drop-down ul:after{left:206px;margin:0;top:-6px;border-top:none;border-bottom:6px solid #39424a}.lasso-editing .toolbar-extended #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{left:222px}.lasso-editing .toolbar-extended #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{left:255px}.lasso-editing .toolbar-extended #lasso-toolbar--components.toolbar--drop-down ul:after{left:288px}#lasso--all-posts__modal ul.lasso--post-list,#lasso--all-posts__modal ul.lasso--post-object-list{float:none;width:100%;display:block}#lasso--all-posts__modal ul.lasso--post-object-list{margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid #181b1f;-webkit-box-shadow:0 1px 1px -1px rgba(255,255,255,.15);box-shadow:0 1px 1px -1px rgba(255,255,255,.15)}#lasso--all-posts__modal ul.lasso--post-object-list li{display:inline-block;width:auto;margin-right:20px;font-size:90%}#lasso--all-posts__modal ul.lasso--post-list{padding-left:0;border:none;box-shadow:none}.lasso--modal{display:block}.lasso--modal .lasso--modal__inner,.lasso--modal.lasso--modal__full .lasso--modal__inner{border-radius:0;padding:10px}}@media (min-width:601px){.lasso-mobile #lasso-toolbar--html__wrap:after,.lasso-mobile #lasso-toolbar--link__wrap:after,.lasso-mobile .toolbar--drop-up ul:after{margin:0;top:-9px;border-top:none;border-bottom:6px solid #39424a}}"
  },
  {
    "path": "public/assets/js/editus-table-edit-public.js",
    "content": "jQuery(document).ready(function($){\n\t'use strict';\n\tif (typeof lasso_editor !== 'undefined') {\n\n\t\t// JAVASCRIPT (jQuery)\n\t\tvar enable = false;\n\t\tvar table;\n\t\tvar tableWidth;\n\t\tvar col;\n\t\tvar row;\n\t\t\n\t\tif (lasso_editor.enterEditorHookArray) {\n\t\t\tlasso_editor.enterEditorHookArray.push(whenEnterEditor);\n\t\t} else {\n\t\t\tlasso_editor.enterEditorHookArray = [whenEnterEditor];\n\t\t}\n\t  \n\t\tif (lasso_editor.exitEditorHookArray) {\n\t\t\tlasso_editor.exitEditorHookArray.push(whenExitEditor);\n\t\t} else {\n\t\t\tlasso_editor.exitEditorHookArray = [whenExitEditor];\n\t\t}\n\n\t\t// Trigger action when the contexmenu is about to be shown\n\t\t$(document).bind(\"contextmenu\", function (event) {\n\t\t\tif (enable && (event.target.nodeName ==\"TH\" || event.target.nodeName ==\"TD\" )) {\n\t\t\t\t// Avoid the real one\n\t\t\t\tevent.preventDefault();\n\t\t\t\tvar cell = event.target;\n\t\t\t\ttable = cell.parentNode.parentNode;\n\t\t\t\ttableWidth = $(table).find(\"tr:first td\").length;\n\t\t\t\tcol = $(cell).parent().children().index($(cell));\n\t\t\t\trow = $(cell).parent().parent().children().index($(cell).parent());\n\t\t\t\tif (!tableWidth) {\n\t\t\t\t\ttableWidth = $(table).find(\"tr:first th\").length;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Show contextmenu\n\t\t\t\t$(\".editus-table-menu\").finish().toggle(100).\n\t\t\t\t\n\t\t\t\t// In the right position (the mouse)\n\t\t\t\tcss({\n\t\t\t\t\ttop: event.pageY + \"px\",\n\t\t\t\t\tleft: event.pageX + \"px\"\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// If the menu element is clicked\n\t\t\t\t$(\".editus-table-menu li\").on('click',function(){\n\t\t\t\t\t// This is the triggered action name\n\t\t\t\t\tif (!table) return;\n\t\t\t\t\tswitch($(this).attr(\"data-action\")) {\n\t\t\t\t\t\t\n\t\t\t\t\t\t// A case for each action. Your actions here\n\t\t\t\t\t\tcase \"insertcol\": addColumn(col); break;\n\t\t\t\t\t\tcase \"insertrow\": addRow(row); break;\n\t\t\t\t\t\tcase \"delcol\": deleteColumn(col); break;\n\t\t\t\t\t\tcase \"delrow\": deleteRow(row); break;\n                        case \"deltable\": deleteTable(); break;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tarticleMedium.makeUndoable();\n\t\t\t\t\ttable = 0;\n\t\t\t\t  \n\t\t\t\t\t// Hide it AFTER the action was triggered\n\t\t\t\t\t$(\".custom-menu\").hide(100);\n\t\t\t\t\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\n\t\t// If the document is clicked somewhere\n\t\t$(document).bind(\"mousedown\", function (e) {\n\t\t\t\n\t\t\t// If the clicked element is not the menu\n\t\t\tif (!$(e.target).parents(\".editus-table-menu\").length > 0) {\n\t\t\t\t\n\t\t\t\t// Hide it\n\t\t\t\t$(\".editus-table-menu\").hide(100);\n\t\t\t}\n\t\t});\n\n\n\t\t\n\t\t\n\t\tfunction addColumn(n) {\n\t\t\t$(table).find('tr').each(function(){\n\t\t\t//$(\"tr\").each(function() {\n\t\t\t\t$(this).find('th').eq(n).after('<th>new cell added</th>');\n\t\t\t\t$(this).find('td').eq(n).after('<td>new cell added</td>');\n\t\t\t});\n\t\t\ttableWidth = $(table).find(\"tr:first td\").length;\n\t\t}\n\t\t\n\t\tfunction addRow(n) {\n\t\t\tvar str = '<tr>';\n\t\t\tfor (var i =0; i<tableWidth;i++) {\n\t\t\t\tstr += '<td>New Cell</td>';\n\t\t\t}\n\t\t\tstr += '</tr>';\n\t\t\t$(table).find('tr').eq(n).after(str);\n\t\t}\n\t\t\n\t\tfunction deleteColumn(n) {\n\t\t\t$(table).find('tr').each(function(){\n\t\t\t//$(\"tr\").each(function() {\n\t\t\t\t$(this).find('th').eq(n).remove();\n\t\t\t\t$(this).find('td').eq(n).remove();\n\t\t\t});\n\t\t\ttableWidth = $(table).find(\"tr:first td\").length;\n\t\t}\n\t\t\n\t\tfunction deleteRow(n) {\n\t\t\t$(table).find('tr').eq(n).remove();\n\t\t}\n        \n        function deleteTable() {\n\t\t\t$(table).remove();\n\t\t}\n\t\t\n\t\tfunction whenExitEditor(){\n\t\t  enable = false;\n\t\t}\n\t  \n\t\tfunction whenEnterEditor(){\n\t\t  enable = true;\n\t\t}\n\t}\n\n});"
  },
  {
    "path": "public/assets/js/lasso.js",
    "content": "/* ways to inject JS Codes\n\nlasso_editor.setupHookArray\nlasso_editor.enterEditorHookArray\nlasso_editor.enterEditorHookArray2\nlasso_editor.exitEditorHookArray\nlasso_editor.saveSuccessHookArray\n\n*/\n\n\n\n\n/*\n * Undo.js - A undo/redo framework for JavaScript\n * \n * http://jzaefferer.github.com/undo\n *\n * Copyright (c) 2011 Jörn Zaefferer\n * MIT licensed.\n */\n(function() {\n\n// based on Backbone.js' inherits\t\nvar ctor = function(){};\nvar inherits = function(parent, protoProps) {\n\tvar child;\n\n\tif (protoProps && protoProps.hasOwnProperty('constructor')) {\n\t\tchild = protoProps.constructor;\n\t} else {\n\t\tchild = function(){ return parent.apply(this, arguments); };\n\t}\n\n\tctor.prototype = parent.prototype;\n\tchild.prototype = new ctor();\n\t\n\tif (protoProps) extend(child.prototype, protoProps);\n\t\n\tchild.prototype.constructor = child;\n\tchild.__super__ = parent.prototype;\n\treturn child;\n};\n\nfunction extend(target, ref) {\n\tvar name, value;\n\tfor ( name in ref ) {\n\t\tvalue = ref[name];\n\t\tif (value !== undefined) {\n\t\t\ttarget[ name ] = value;\n\t\t}\n\t}\n\treturn target;\n};\n\nvar Undo;\nif (typeof exports !== 'undefined') {\n\tUndo = exports;\n} else {\n\tUndo = this.Undo = {};\n}\n\nUndo.Stack = function() {\n\tthis.commands = [];\n\tthis.stackPosition = -1;\n\tthis.savePosition = -1;\n};\n\nextend(Undo.Stack.prototype, {\n\texecute: function(command) {\n\t\tthis._clearRedo();\n\t\tcommand.execute();\n\t\tthis.commands.push(command);\n\t\tif (this.commands.length>15) {\n\t\t\tthis.commands.shift();\n\t\t} else {\n\t\t\tthis.stackPosition++;\n\t\t}\n\t\t\n\t\tthis.changed();\n\t},\n\tundo: function() {\n\t\tthis.commands[this.stackPosition].undo();\n\t\tthis.stackPosition--;\n\t\t//this.commands.pop();\n\t\tthis.changed();\n\t},\n\tcanUndo: function() {\n\t\treturn this.stackPosition >= 0;\n\t},\n\tredo: function() {\n\t\tthis.stackPosition++;\n\t\tthis.commands[this.stackPosition].redo();\n\t\tthis.changed();\n\t},\n\tcanRedo: function() {\n\t\treturn this.stackPosition < this.commands.length - 1;\n\t},\n\tsave: function() {\n\t\tthis.savePosition = this.stackPosition;\n\t\tthis.changed();\n\t},\n\tdirty: function() {\n\t\treturn (this.stackPosition != this.savePosition) || lasso_editor.dirtyByComponent;\n\t},\n\t_clearRedo: function() {\n\t\t// TODO there's probably a more efficient way for this\n\t\tthis.commands = this.commands.slice(0, this.stackPosition + 1);\n\t},\n\tchanged: function() {\n\t\t// do nothing, override\n\t}\n});\n\nUndo.Command = function(name) {\n\tthis.name = name;\n}\n\nvar up = new Error(\"override me!\");\n\nextend(Undo.Command.prototype, {\n\texecute: function() {\n\t\tthrow up;\n\t},\n\tundo: function() {\n\t\tthrow up;\n\t},\n\tredo: function() {\n\t\tthis.execute();\n\t}\n});\n\nUndo.Command.extend = function(protoProps) {\n\tvar child = inherits(this, protoProps);\n\tchild.extend = Undo.Command.extend;\n\treturn child;\n};\n\t\n}).call(this);\n/**\n * Rangy, a cross-browser JavaScript range and selection library\n * http://code.google.com/p/rangy/\n *\n * Copyright 2014, Tim Down\n * Licensed under the MIT license.\n * Version: 1.3.0-alpha.20140827\n * Build date: 27 August 2014\n */\n\n(function(factory, root) {\n    if (typeof define == \"function\" && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(factory);\n    } else if (typeof module != \"undefined\" && typeof exports == \"object\") {\n        // Node/CommonJS style\n        module.exports = factory();\n    } else {\n        // No AMD or CommonJS support so we place Rangy in (probably) the global variable\n        root.rangy = factory();\n    }\n})(function() {\n\n    var OBJECT = \"object\", FUNCTION = \"function\", UNDEFINED = \"undefined\";\n\n    // Minimal set of properties required for DOM Level 2 Range compliance. Comparison constants such as START_TO_START\n    // are omitted because ranges in KHTML do not have them but otherwise work perfectly well. See issue 113.\n    var domRangeProperties = [\"startContainer\", \"startOffset\", \"endContainer\", \"endOffset\", \"collapsed\",\n        \"commonAncestorContainer\"];\n\n    // Minimal set of methods required for DOM Level 2 Range compliance\n    var domRangeMethods = [\"setStart\", \"setStartBefore\", \"setStartAfter\", \"setEnd\", \"setEndBefore\",\n        \"setEndAfter\", \"collapse\", \"selectNode\", \"selectNodeContents\", \"compareBoundaryPoints\", \"deleteContents\",\n        \"extractContents\", \"cloneContents\", \"insertNode\", \"surroundContents\", \"cloneRange\", \"toString\", \"detach\"];\n\n    var textRangeProperties = [\"boundingHeight\", \"boundingLeft\", \"boundingTop\", \"boundingWidth\", \"htmlText\", \"text\"];\n\n    // Subset of TextRange's full set of methods that we're interested in\n    var textRangeMethods = [\"collapse\", \"compareEndPoints\", \"duplicate\", \"moveToElementText\", \"parentElement\", \"select\",\n        \"setEndPoint\", \"getBoundingClientRect\"];\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Trio of functions taken from Peter Michaux's article:\n    // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting\n    function isHostMethod(o, p) {\n        var t = typeof o[p];\n        return t == FUNCTION || (!!(t == OBJECT && o[p])) || t == \"unknown\";\n    }\n\n    function isHostObject(o, p) {\n        return !!(typeof o[p] == OBJECT && o[p]);\n    }\n\n    function isHostProperty(o, p) {\n        return typeof o[p] != UNDEFINED;\n    }\n\n    // Creates a convenience function to save verbose repeated calls to tests functions\n    function createMultiplePropertyTest(testFunc) {\n        return function(o, props) {\n            var i = props.length;\n            while (i--) {\n                if (!testFunc(o, props[i])) {\n                    return false;\n                }\n            }\n            return true;\n        };\n    }\n\n    // Next trio of functions are a convenience to save verbose repeated calls to previous two functions\n    var areHostMethods = createMultiplePropertyTest(isHostMethod);\n    var areHostObjects = createMultiplePropertyTest(isHostObject);\n    var areHostProperties = createMultiplePropertyTest(isHostProperty);\n\n    function isTextRange(range) {\n        return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties);\n    }\n\n    function getBody(doc) {\n        return isHostObject(doc, \"body\") ? doc.body : doc.getElementsByTagName(\"body\")[0];\n    }\n\n    var modules = {};\n\n    var isBrowser = (typeof window != UNDEFINED && typeof document != UNDEFINED);\n\n    var util = {\n        isHostMethod: isHostMethod,\n        isHostObject: isHostObject,\n        isHostProperty: isHostProperty,\n        areHostMethods: areHostMethods,\n        areHostObjects: areHostObjects,\n        areHostProperties: areHostProperties,\n        isTextRange: isTextRange,\n        getBody: getBody\n    };\n\n    var api = {\n        version: \"1.3.0-alpha.20140827\",\n        initialized: false,\n        isBrowser: isBrowser,\n        supported: true,\n        util: util,\n        features: {},\n        modules: modules,\n        config: {\n            alertOnFail: true,\n            alertOnWarn: false,\n            preferTextRange: false,\n            autoInitialize: (typeof rangyAutoInitialize == UNDEFINED) ? true : rangyAutoInitialize\n        }\n    };\n\n    function consoleLog(msg) {\n        if (typeof console != UNDEFINED && isHostMethod(console, \"log\")) {\n            console.log(msg);\n        }\n    }\n\n    function alertOrLog(msg, shouldAlert) {\n        if (isBrowser && shouldAlert) {\n            alert(msg);\n        } else  {\n            consoleLog(msg);\n        }\n    }\n\n    function fail(reason) {\n        api.initialized = true;\n        api.supported = false;\n        alertOrLog(\"Rangy is not supported in this environment. Reason: \" + reason, api.config.alertOnFail);\n    }\n\n    api.fail = fail;\n\n    function warn(msg) {\n        alertOrLog(\"Rangy warning: \" + msg, api.config.alertOnWarn);\n    }\n\n    api.warn = warn;\n\n    // Add utility extend() method\n    var extend;\n    if ({}.hasOwnProperty) {\n        util.extend = extend = function(obj, props, deep) {\n            var o, p;\n            for (var i in props) {\n                if (props.hasOwnProperty(i)) {\n                    o = obj[i];\n                    p = props[i];\n                    if (deep && o !== null && typeof o == \"object\" && p !== null && typeof p == \"object\") {\n                        extend(o, p, true);\n                    }\n                    obj[i] = p;\n                }\n            }\n            // Special case for toString, which does not show up in for...in loops in IE <= 8\n            if (props.hasOwnProperty(\"toString\")) {\n                obj.toString = props.toString;\n            }\n            return obj;\n        };\n\n        util.createOptions = function(optionsParam, defaults) {\n            var options = {};\n            extend(options, defaults);\n            if (optionsParam) {\n                extend(options, optionsParam, true);\n            }\n            return options;\n        };\n    } else {\n        fail(\"hasOwnProperty not supported\");\n    }\n    \n    // Test whether we're in a browser and bail out if not\n    if (!isBrowser) {\n        fail(\"Rangy can only run in a browser\");\n    }\n\n    // Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not\n    (function() {\n        var toArray;\n\n        if (isBrowser) {\n            var el = document.createElement(\"div\");\n            el.appendChild(document.createElement(\"span\"));\n            var slice = [].slice;\n            try {\n                if (slice.call(el.childNodes, 0)[0].nodeType == 1) {\n                    toArray = function(arrayLike) {\n                        return slice.call(arrayLike, 0);\n                    };\n                }\n            } catch (e) {}\n        }\n\n        if (!toArray) {\n            toArray = function(arrayLike) {\n                var arr = [];\n                for (var i = 0, len = arrayLike.length; i < len; ++i) {\n                    arr[i] = arrayLike[i];\n                }\n                return arr;\n            };\n        }\n\n        util.toArray = toArray;\n    })();\n\n    // Very simple event handler wrapper function that doesn't attempt to solve issues such as \"this\" handling or\n    // normalization of event properties\n    var addListener;\n    if (isBrowser) {\n        if (isHostMethod(document, \"addEventListener\")) {\n            addListener = function(obj, eventType, listener) {\n                obj.addEventListener(eventType, listener, false);\n            };\n        } else if (isHostMethod(document, \"attachEvent\")) {\n            addListener = function(obj, eventType, listener) {\n                obj.attachEvent(\"on\" + eventType, listener);\n            };\n        } else {\n            fail(\"Document does not have required addEventListener or attachEvent method\");\n        }\n\n        util.addListener = addListener;\n    }\n\n    var initListeners = [];\n\n    function getErrorDesc(ex) {\n        return ex.message || ex.description || String(ex);\n    }\n\n    // Initialization\n    function init() {\n        if (!isBrowser || api.initialized) {\n            return;\n        }\n        var testRange;\n        var implementsDomRange = false, implementsTextRange = false;\n\n        // First, perform basic feature tests\n\n        if (isHostMethod(document, \"createRange\")) {\n            testRange = document.createRange();\n            if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) {\n                implementsDomRange = true;\n            }\n        }\n\n        var body = getBody(document);\n        if (!body || body.nodeName.toLowerCase() != \"body\") {\n            fail(\"No body element found\");\n            return;\n        }\n\n        if (body && isHostMethod(body, \"createTextRange\")) {\n            testRange = body.createTextRange();\n            if (isTextRange(testRange)) {\n                implementsTextRange = true;\n            }\n        }\n\n        if (!implementsDomRange && !implementsTextRange) {\n            fail(\"Neither Range nor TextRange are available\");\n            return;\n        }\n\n        api.initialized = true;\n        api.features = {\n            implementsDomRange: implementsDomRange,\n            implementsTextRange: implementsTextRange\n        };\n\n        // Initialize modules\n        var module, errorMessage;\n        for (var moduleName in modules) {\n            if ( (module = modules[moduleName]) instanceof Module ) {\n                module.init(module, api);\n            }\n        }\n\n        // Call init listeners\n        for (var i = 0, len = initListeners.length; i < len; ++i) {\n            try {\n                initListeners[i](api);\n            } catch (ex) {\n                errorMessage = \"Rangy init listener threw an exception. Continuing. Detail: \" + getErrorDesc(ex);\n                consoleLog(errorMessage);\n            }\n        }\n    }\n\n    // Allow external scripts to initialize this library in case it's loaded after the document has loaded\n    api.init = init;\n\n    // Execute listener immediately if already initialized\n    api.addInitListener = function(listener) {\n        if (api.initialized) {\n            listener(api);\n        } else {\n            initListeners.push(listener);\n        }\n    };\n\n    var shimListeners = [];\n\n    api.addShimListener = function(listener) {\n        shimListeners.push(listener);\n    };\n\n    function shim(win) {\n        win = win || window;\n        init();\n\n        // Notify listeners\n        for (var i = 0, len = shimListeners.length; i < len; ++i) {\n            shimListeners[i](win);\n        }\n    }\n\n    if (isBrowser) {\n        api.shim = api.createMissingNativeApi = shim;\n    }\n\n    function Module(name, dependencies, initializer) {\n        this.name = name;\n        this.dependencies = dependencies;\n        this.initialized = false;\n        this.supported = false;\n        this.initializer = initializer;\n    }\n\n    Module.prototype = {\n        init: function() {\n            var requiredModuleNames = this.dependencies || [];\n            for (var i = 0, len = requiredModuleNames.length, requiredModule, moduleName; i < len; ++i) {\n                moduleName = requiredModuleNames[i];\n\n                requiredModule = modules[moduleName];\n                if (!requiredModule || !(requiredModule instanceof Module)) {\n                    throw new Error(\"required module '\" + moduleName + \"' not found\");\n                }\n\n                requiredModule.init();\n\n                if (!requiredModule.supported) {\n                    throw new Error(\"required module '\" + moduleName + \"' not supported\");\n                }\n            }\n            \n            // Now run initializer\n            this.initializer(this);\n        },\n        \n        fail: function(reason) {\n            this.initialized = true;\n            this.supported = false;\n            throw new Error(\"Module '\" + this.name + \"' failed to load: \" + reason);\n        },\n\n        warn: function(msg) {\n            api.warn(\"Module \" + this.name + \": \" + msg);\n        },\n\n        deprecationNotice: function(deprecated, replacement) {\n            api.warn(\"DEPRECATED: \" + deprecated + \" in module \" + this.name + \"is deprecated. Please use \" +\n                replacement + \" instead\");\n        },\n\n        createError: function(msg) {\n            return new Error(\"Error in Rangy \" + this.name + \" module: \" + msg);\n        }\n    };\n    \n    function createModule(name, dependencies, initFunc) {\n        var newModule = new Module(name, dependencies, function(module) {\n            if (!module.initialized) {\n                module.initialized = true;\n                try {\n                    initFunc(api, module);\n                    module.supported = true;\n                } catch (ex) {\n                    var errorMessage = \"Module '\" + name + \"' failed to load: \" + getErrorDesc(ex);\n                    consoleLog(errorMessage);\n                }\n            }\n        });\n        modules[name] = newModule;\n        return newModule;\n    }\n\n    api.createModule = function(name) {\n        // Allow 2 or 3 arguments (second argument is an optional array of dependencies)\n        var initFunc, dependencies;\n        if (arguments.length == 2) {\n            initFunc = arguments[1];\n            dependencies = [];\n        } else {\n            initFunc = arguments[2];\n            dependencies = arguments[1];\n        }\n\n        var module = createModule(name, dependencies, initFunc);\n\n        // Initialize the module immediately if the core is already initialized\n        if (api.initialized && api.supported) {\n            module.init();\n        }\n    };\n\n    api.createCoreModule = function(name, dependencies, initFunc) {\n        createModule(name, dependencies, initFunc);\n    };\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately\n\n    function RangePrototype() {}\n    api.RangePrototype = RangePrototype;\n    api.rangePrototype = new RangePrototype();\n\n    function SelectionPrototype() {}\n    api.selectionPrototype = new SelectionPrototype();\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // DOM utility methods used by Rangy\n    api.createCoreModule(\"DomUtil\", [], function(api, module) {\n        var UNDEF = \"undefined\";\n        var util = api.util;\n\n        // Perform feature tests\n        if (!util.areHostMethods(document, [\"createDocumentFragment\", \"createElement\", \"createTextNode\"])) {\n            module.fail(\"document missing a Node creation method\");\n        }\n\n        if (!util.isHostMethod(document, \"getElementsByTagName\")) {\n            module.fail(\"document missing getElementsByTagName method\");\n        }\n\n        var el = document.createElement(\"div\");\n        if (!util.areHostMethods(el, [\"insertBefore\", \"appendChild\", \"cloneNode\"] ||\n                !util.areHostObjects(el, [\"previousSibling\", \"nextSibling\", \"childNodes\", \"parentNode\"]))) {\n            module.fail(\"Incomplete Element implementation\");\n        }\n\n        // innerHTML is required for Range's createContextualFragment method\n        if (!util.isHostProperty(el, \"innerHTML\")) {\n            module.fail(\"Element is missing innerHTML property\");\n        }\n\n        var textNode = document.createTextNode(\"test\");\n        if (!util.areHostMethods(textNode, [\"splitText\", \"deleteData\", \"insertData\", \"appendData\", \"cloneNode\"] ||\n                !util.areHostObjects(el, [\"previousSibling\", \"nextSibling\", \"childNodes\", \"parentNode\"]) ||\n                !util.areHostProperties(textNode, [\"data\"]))) {\n            module.fail(\"Incomplete Text Node implementation\");\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been\n        // able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that\n        // contains just the document as a single element and the value searched for is the document.\n        var arrayContains = /*Array.prototype.indexOf ?\n            function(arr, val) {\n                return arr.indexOf(val) > -1;\n            }:*/\n\n            function(arr, val) {\n                var i = arr.length;\n                while (i--) {\n                    if (arr[i] === val) {\n                        return true;\n                    }\n                }\n                return false;\n            };\n\n        // Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI\n        function isHtmlNamespace(node) {\n            var ns;\n            return typeof node.namespaceURI == UNDEF || ((ns = node.namespaceURI) === null || ns == \"http://www.w3.org/1999/xhtml\");\n        }\n\n        function parentElement(node) {\n            var parent = node.parentNode;\n            return (parent.nodeType == 1) ? parent : null;\n        }\n\n        function getNodeIndex(node) {\n            var i = 0;\n            while( (node = node.previousSibling) ) {\n                ++i;\n            }\n            return i;\n        }\n\n        function getNodeLength(node) {\n            switch (node.nodeType) {\n                case 7:\n                case 10:\n                    return 0;\n                case 3:\n                case 8:\n                    return node.length;\n                default:\n                    return node.childNodes.length;\n            }\n        }\n\n        function getCommonAncestor(node1, node2) {\n            var ancestors = [], n;\n            for (n = node1; n; n = n.parentNode) {\n                ancestors.push(n);\n            }\n\n            for (n = node2; n; n = n.parentNode) {\n                if (arrayContains(ancestors, n)) {\n                    return n;\n                }\n            }\n\n            return null;\n        }\n\n        function isAncestorOf(ancestor, descendant, selfIsAncestor) {\n            var n = selfIsAncestor ? descendant : descendant.parentNode;\n            while (n) {\n                if (n === ancestor) {\n                    return true;\n                } else {\n                    n = n.parentNode;\n                }\n            }\n            return false;\n        }\n\n        function isOrIsAncestorOf(ancestor, descendant) {\n            return isAncestorOf(ancestor, descendant, true);\n        }\n\n        function getClosestAncestorIn(node, ancestor, selfIsAncestor) {\n            var p, n = selfIsAncestor ? node : node.parentNode;\n            while (n) {\n                p = n.parentNode;\n                if (p === ancestor) {\n                    return n;\n                }\n                n = p;\n            }\n            return null;\n        }\n\n        function isCharacterDataNode(node) {\n            var t = node.nodeType;\n            return t == 3 || t == 4 || t == 8 ; // Text, CDataSection or Comment\n        }\n\n        function isTextOrCommentNode(node) {\n            if (!node) {\n                return false;\n            }\n            var t = node.nodeType;\n            return t == 3 || t == 8 ; // Text or Comment\n        }\n\n        function insertAfter(node, precedingNode) {\n            var nextNode = precedingNode.nextSibling, parent = precedingNode.parentNode;\n            if (nextNode) {\n                parent.insertBefore(node, nextNode);\n            } else {\n                parent.appendChild(node);\n            }\n            return node;\n        }\n\n        // Note that we cannot use splitText() because it is bugridden in IE 9.\n        function splitDataNode(node, index, positionsToPreserve) {\n            var newNode = node.cloneNode(false);\n            newNode.deleteData(0, index);\n            node.deleteData(index, node.length - index);\n            insertAfter(newNode, node);\n\n            // Preserve positions\n            if (positionsToPreserve) {\n                for (var i = 0, position; position = positionsToPreserve[i++]; ) {\n                    // Handle case where position was inside the portion of node after the split point\n                    if (position.node == node && position.offset > index) {\n                        position.node = newNode;\n                        position.offset -= index;\n                    }\n                    // Handle the case where the position is a node offset within node's parent\n                    else if (position.node == node.parentNode && position.offset > getNodeIndex(node)) {\n                        ++position.offset;\n                    }\n                }\n            }\n            return newNode;\n        }\n\n        function getDocument(node) {\n            if (node.nodeType == 9) {\n                return node;\n            } else if (typeof node.ownerDocument != UNDEF) {\n                return node.ownerDocument;\n            } else if (typeof node.document != UNDEF) {\n                return node.document;\n            } else if (node.parentNode) {\n                return getDocument(node.parentNode);\n            } else {\n                throw module.createError(\"getDocument: no document found for node\");\n            }\n        }\n\n        function getWindow(node) {\n            var doc = getDocument(node);\n            if (typeof doc.defaultView != UNDEF) {\n                return doc.defaultView;\n            } else if (typeof doc.parentWindow != UNDEF) {\n                return doc.parentWindow;\n            } else {\n                throw module.createError(\"Cannot get a window object for node\");\n            }\n        }\n\n        function getIframeDocument(iframeEl) {\n            if (typeof iframeEl.contentDocument != UNDEF) {\n                return iframeEl.contentDocument;\n            } else if (typeof iframeEl.contentWindow != UNDEF) {\n                return iframeEl.contentWindow.document;\n            } else {\n                throw module.createError(\"getIframeDocument: No Document object found for iframe element\");\n            }\n        }\n\n        function getIframeWindow(iframeEl) {\n            if (typeof iframeEl.contentWindow != UNDEF) {\n                return iframeEl.contentWindow;\n            } else if (typeof iframeEl.contentDocument != UNDEF) {\n                return iframeEl.contentDocument.defaultView;\n            } else {\n                throw module.createError(\"getIframeWindow: No Window object found for iframe element\");\n            }\n        }\n\n        // This looks bad. Is it worth it?\n        function isWindow(obj) {\n            return obj && util.isHostMethod(obj, \"setTimeout\") && util.isHostObject(obj, \"document\");\n        }\n\n        function getContentDocument(obj, module, methodName) {\n            var doc;\n\n            if (!obj) {\n                doc = document;\n            }\n\n            // Test if a DOM node has been passed and obtain a document object for it if so\n            else if (util.isHostProperty(obj, \"nodeType\")) {\n                doc = (obj.nodeType == 1 && obj.tagName.toLowerCase() == \"iframe\") ?\n                    getIframeDocument(obj) : getDocument(obj);\n            }\n\n            // Test if the doc parameter appears to be a Window object\n            else if (isWindow(obj)) {\n                doc = obj.document;\n            }\n\n            if (!doc) {\n                throw module.createError(methodName + \"(): Parameter must be a Window object or DOM node\");\n            }\n\n            return doc;\n        }\n\n        function getRootContainer(node) {\n            var parent;\n            while ( (parent = node.parentNode) ) {\n                node = parent;\n            }\n            return node;\n        }\n\n        function comparePoints(nodeA, offsetA, nodeB, offsetB) {\n            // See http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing\n            var nodeC, root, childA, childB, n;\n            if (nodeA == nodeB) {\n                // Case 1: nodes are the same\n                return offsetA === offsetB ? 0 : (offsetA < offsetB) ? -1 : 1;\n            } else if ( (nodeC = getClosestAncestorIn(nodeB, nodeA, true)) ) {\n                // Case 2: node C (container B or an ancestor) is a child node of A\n                return offsetA <= getNodeIndex(nodeC) ? -1 : 1;\n            } else if ( (nodeC = getClosestAncestorIn(nodeA, nodeB, true)) ) {\n                // Case 3: node C (container A or an ancestor) is a child node of B\n                return getNodeIndex(nodeC) < offsetB  ? -1 : 1;\n            } else {\n                root = getCommonAncestor(nodeA, nodeB);\n                if (!root) {\n                    throw new Error(\"comparePoints error: nodes have no common ancestor\");\n                }\n\n                // Case 4: containers are siblings or descendants of siblings\n                childA = (nodeA === root) ? root : getClosestAncestorIn(nodeA, root, true);\n                childB = (nodeB === root) ? root : getClosestAncestorIn(nodeB, root, true);\n\n                if (childA === childB) {\n                    // This shouldn't be possible\n                    throw module.createError(\"comparePoints got to case 4 and childA and childB are the same!\");\n                } else {\n                    n = root.firstChild;\n                    while (n) {\n                        if (n === childA) {\n                            return -1;\n                        } else if (n === childB) {\n                            return 1;\n                        }\n                        n = n.nextSibling;\n                    }\n                }\n            }\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Test for IE's crash (IE 6/7) or exception (IE >= 8) when a reference to garbage-collected text node is queried\n        var crashyTextNodes = false;\n\n        function isBrokenNode(node) {\n            var n;\n            try {\n                n = node.parentNode;\n                return false;\n            } catch (e) {\n                return true;\n            }\n        }\n\n        (function() {\n            var el = document.createElement(\"b\");\n            el.innerHTML = \"1\";\n            var textNode = el.firstChild;\n            el.innerHTML = \"<br>\";\n            crashyTextNodes = isBrokenNode(textNode);\n\n            api.features.crashyTextNodes = crashyTextNodes;\n        })();\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        function inspectNode(node) {\n            if (!node) {\n                return \"[No node]\";\n            }\n            if (crashyTextNodes && isBrokenNode(node)) {\n                return \"[Broken node]\";\n            }\n            if (isCharacterDataNode(node)) {\n                return '\"' + node.data + '\"';\n            }\n            if (node.nodeType == 1) {\n                var idAttr = node.id ? ' id=\"' + node.id + '\"' : \"\";\n                return \"<\" + node.nodeName + idAttr + \">[index:\" + getNodeIndex(node) + \",length:\" + node.childNodes.length + \"][\" + (node.innerHTML || \"[innerHTML not supported]\").slice(0, 25) + \"]\";\n            }\n            return node.nodeName;\n        }\n\n        function fragmentFromNodeChildren(node) {\n            var fragment = getDocument(node).createDocumentFragment(), child;\n            while ( (child = node.firstChild) ) {\n                fragment.appendChild(child);\n            }\n            return fragment;\n        }\n\n        var getComputedStyleProperty;\n        if (typeof window.getComputedStyle != UNDEF) {\n            getComputedStyleProperty = function(el, propName) {\n                return getWindow(el).getComputedStyle(el, null)[propName];\n            };\n        } else if (typeof document.documentElement.currentStyle != UNDEF) {\n            getComputedStyleProperty = function(el, propName) {\n                return el.currentStyle[propName];\n            };\n        } else {\n            module.fail(\"No means of obtaining computed style properties found\");\n        }\n\n        function NodeIterator(root) {\n            this.root = root;\n            this._next = root;\n        }\n\n        NodeIterator.prototype = {\n            _current: null,\n\n            hasNext: function() {\n                return !!this._next;\n            },\n\n            next: function() {\n                var n = this._current = this._next;\n                var child, next;\n                if (this._current) {\n                    child = n.firstChild;\n                    if (child) {\n                        this._next = child;\n                    } else {\n                        next = null;\n                        while ((n !== this.root) && !(next = n.nextSibling)) {\n                            n = n.parentNode;\n                        }\n                        this._next = next;\n                    }\n                }\n                return this._current;\n            },\n\n            detach: function() {\n                this._current = this._next = this.root = null;\n            }\n        };\n\n        function createIterator(root) {\n            return new NodeIterator(root);\n        }\n\n        function DomPosition(node, offset) {\n            this.node = node;\n            this.offset = offset;\n        }\n\n        DomPosition.prototype = {\n            equals: function(pos) {\n                return !!pos && this.node === pos.node && this.offset == pos.offset;\n            },\n\n            inspect: function() {\n                return \"[DomPosition(\" + inspectNode(this.node) + \":\" + this.offset + \")]\";\n            },\n\n            toString: function() {\n                return this.inspect();\n            }\n        };\n\n        function DOMException(codeName) {\n            this.code = this[codeName];\n            this.codeName = codeName;\n            this.message = \"DOMException: \" + this.codeName;\n        }\n\n        DOMException.prototype = {\n            INDEX_SIZE_ERR: 1,\n            HIERARCHY_REQUEST_ERR: 3,\n            WRONG_DOCUMENT_ERR: 4,\n            NO_MODIFICATION_ALLOWED_ERR: 7,\n            NOT_FOUND_ERR: 8,\n            NOT_SUPPORTED_ERR: 9,\n            INVALID_STATE_ERR: 11,\n            INVALID_NODE_TYPE_ERR: 24\n        };\n\n        DOMException.prototype.toString = function() {\n            return this.message;\n        };\n\n        api.dom = {\n            arrayContains: arrayContains,\n            isHtmlNamespace: isHtmlNamespace,\n            parentElement: parentElement,\n            getNodeIndex: getNodeIndex,\n            getNodeLength: getNodeLength,\n            getCommonAncestor: getCommonAncestor,\n            isAncestorOf: isAncestorOf,\n            isOrIsAncestorOf: isOrIsAncestorOf,\n            getClosestAncestorIn: getClosestAncestorIn,\n            isCharacterDataNode: isCharacterDataNode,\n            isTextOrCommentNode: isTextOrCommentNode,\n            insertAfter: insertAfter,\n            splitDataNode: splitDataNode,\n            getDocument: getDocument,\n            getWindow: getWindow,\n            getIframeWindow: getIframeWindow,\n            getIframeDocument: getIframeDocument,\n            getBody: util.getBody,\n            isWindow: isWindow,\n            getContentDocument: getContentDocument,\n            getRootContainer: getRootContainer,\n            comparePoints: comparePoints,\n            isBrokenNode: isBrokenNode,\n            inspectNode: inspectNode,\n            getComputedStyleProperty: getComputedStyleProperty,\n            fragmentFromNodeChildren: fragmentFromNodeChildren,\n            createIterator: createIterator,\n            DomPosition: DomPosition\n        };\n\n        api.DOMException = DOMException;\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Pure JavaScript implementation of DOM Range\n    api.createCoreModule(\"DomRange\", [\"DomUtil\"], function(api, module) {\n        var dom = api.dom;\n        var util = api.util;\n        var DomPosition = dom.DomPosition;\n        var DOMException = api.DOMException;\n\n        var isCharacterDataNode = dom.isCharacterDataNode;\n        var getNodeIndex = dom.getNodeIndex;\n        var isOrIsAncestorOf = dom.isOrIsAncestorOf;\n        var getDocument = dom.getDocument;\n        var comparePoints = dom.comparePoints;\n        var splitDataNode = dom.splitDataNode;\n        var getClosestAncestorIn = dom.getClosestAncestorIn;\n        var getNodeLength = dom.getNodeLength;\n        var arrayContains = dom.arrayContains;\n        var getRootContainer = dom.getRootContainer;\n        var crashyTextNodes = api.features.crashyTextNodes;\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Utility functions\n\n        function isNonTextPartiallySelected(node, range) {\n            return (node.nodeType != 3) &&\n                   (isOrIsAncestorOf(node, range.startContainer) || isOrIsAncestorOf(node, range.endContainer));\n        }\n\n        function getRangeDocument(range) {\n            return range.document || getDocument(range.startContainer);\n        }\n\n        function getBoundaryBeforeNode(node) {\n            return new DomPosition(node.parentNode, getNodeIndex(node));\n        }\n\n        function getBoundaryAfterNode(node) {\n            return new DomPosition(node.parentNode, getNodeIndex(node) + 1);\n        }\n\n        function insertNodeAtPosition(node, n, o) {\n            var firstNodeInserted = node.nodeType == 11 ? node.firstChild : node;\n            if (isCharacterDataNode(n)) {\n                if (o == n.length) {\n                    dom.insertAfter(node, n);\n                } else {\n                    n.parentNode.insertBefore(node, o == 0 ? n : splitDataNode(n, o));\n                }\n            } else if (o >= n.childNodes.length) {\n                n.appendChild(node);\n            } else {\n                n.insertBefore(node, n.childNodes[o]);\n            }\n            return firstNodeInserted;\n        }\n\n        function rangesIntersect(rangeA, rangeB, touchingIsIntersecting) {\n            assertRangeValid(rangeA);\n            assertRangeValid(rangeB);\n\n            if (getRangeDocument(rangeB) != getRangeDocument(rangeA)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n\n            var startComparison = comparePoints(rangeA.startContainer, rangeA.startOffset, rangeB.endContainer, rangeB.endOffset),\n                endComparison = comparePoints(rangeA.endContainer, rangeA.endOffset, rangeB.startContainer, rangeB.startOffset);\n\n            return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;\n        }\n\n        function cloneSubtree(iterator) {\n            var partiallySelected;\n            for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {\n                partiallySelected = iterator.isPartiallySelectedSubtree();\n                node = node.cloneNode(!partiallySelected);\n                if (partiallySelected) {\n                    subIterator = iterator.getSubtreeIterator();\n                    node.appendChild(cloneSubtree(subIterator));\n                    subIterator.detach();\n                }\n\n                if (node.nodeType == 10) { // DocumentType\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n                frag.appendChild(node);\n            }\n            return frag;\n        }\n\n        function iterateSubtree(rangeIterator, func, iteratorState) {\n            var it, n;\n            iteratorState = iteratorState || { stop: false };\n            for (var node, subRangeIterator; node = rangeIterator.next(); ) {\n                if (rangeIterator.isPartiallySelectedSubtree()) {\n                    if (func(node) === false) {\n                        iteratorState.stop = true;\n                        return;\n                    } else {\n                        // The node is partially selected by the Range, so we can use a new RangeIterator on the portion of\n                        // the node selected by the Range.\n                        subRangeIterator = rangeIterator.getSubtreeIterator();\n                        iterateSubtree(subRangeIterator, func, iteratorState);\n                        subRangeIterator.detach();\n                        if (iteratorState.stop) {\n                            return;\n                        }\n                    }\n                } else {\n                    // The whole node is selected, so we can use efficient DOM iteration to iterate over the node and its\n                    // descendants\n                    it = dom.createIterator(node);\n                    while ( (n = it.next()) ) {\n                        if (func(n) === false) {\n                            iteratorState.stop = true;\n                            return;\n                        }\n                    }\n                }\n            }\n        }\n\n        function deleteSubtree(iterator) {\n            var subIterator;\n            while (iterator.next()) {\n                if (iterator.isPartiallySelectedSubtree()) {\n                    subIterator = iterator.getSubtreeIterator();\n                    deleteSubtree(subIterator);\n                    subIterator.detach();\n                } else {\n                    iterator.remove();\n                }\n            }\n        }\n\n        function extractSubtree(iterator) {\n            for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {\n\n                if (iterator.isPartiallySelectedSubtree()) {\n                    node = node.cloneNode(false);\n                    subIterator = iterator.getSubtreeIterator();\n                    node.appendChild(extractSubtree(subIterator));\n                    subIterator.detach();\n                } else {\n                    iterator.remove();\n                }\n                if (node.nodeType == 10) { // DocumentType\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n                frag.appendChild(node);\n            }\n            return frag;\n        }\n\n        function getNodesInRange(range, nodeTypes, filter) {\n            var filterNodeTypes = !!(nodeTypes && nodeTypes.length), regex;\n            var filterExists = !!filter;\n            if (filterNodeTypes) {\n                regex = new RegExp(\"^(\" + nodeTypes.join(\"|\") + \")$\");\n            }\n\n            var nodes = [];\n            iterateSubtree(new RangeIterator(range, false), function(node) {\n                if (filterNodeTypes && !regex.test(node.nodeType)) {\n                    return;\n                }\n                if (filterExists && !filter(node)) {\n                    return;\n                }\n                // Don't include a boundary container if it is a character data node and the range does not contain any\n                // of its character data. See issue 190.\n                var sc = range.startContainer;\n                if (node == sc && isCharacterDataNode(sc) && range.startOffset == sc.length) {\n                    return;\n                }\n\n                var ec = range.endContainer;\n                if (node == ec && isCharacterDataNode(ec) && range.endOffset == 0) {\n                    return;\n                }\n\n                nodes.push(node);\n            });\n            return nodes;\n        }\n\n        function inspect(range) {\n            var name = (typeof range.getName == \"undefined\") ? \"Range\" : range.getName();\n            return \"[\" + name + \"(\" + dom.inspectNode(range.startContainer) + \":\" + range.startOffset + \", \" +\n                    dom.inspectNode(range.endContainer) + \":\" + range.endOffset + \")]\";\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // RangeIterator code partially borrows from IERange by Tim Ryan (http://github.com/timcameronryan/IERange)\n\n        function RangeIterator(range, clonePartiallySelectedTextNodes) {\n            this.range = range;\n            this.clonePartiallySelectedTextNodes = clonePartiallySelectedTextNodes;\n\n\n            if (!range.collapsed) {\n                this.sc = range.startContainer;\n                this.so = range.startOffset;\n                this.ec = range.endContainer;\n                this.eo = range.endOffset;\n                var root = range.commonAncestorContainer;\n\n                if (this.sc === this.ec && isCharacterDataNode(this.sc)) {\n                    this.isSingleCharacterDataNode = true;\n                    this._first = this._last = this._next = this.sc;\n                } else {\n                    this._first = this._next = (this.sc === root && !isCharacterDataNode(this.sc)) ?\n                        this.sc.childNodes[this.so] : getClosestAncestorIn(this.sc, root, true);\n                    this._last = (this.ec === root && !isCharacterDataNode(this.ec)) ?\n                        this.ec.childNodes[this.eo - 1] : getClosestAncestorIn(this.ec, root, true);\n                }\n            }\n        }\n\n        RangeIterator.prototype = {\n            _current: null,\n            _next: null,\n            _first: null,\n            _last: null,\n            isSingleCharacterDataNode: false,\n\n            reset: function() {\n                this._current = null;\n                this._next = this._first;\n            },\n\n            hasNext: function() {\n                return !!this._next;\n            },\n\n            next: function() {\n                // Move to next node\n                var current = this._current = this._next;\n                if (current) {\n                    this._next = (current !== this._last) ? current.nextSibling : null;\n\n                    // Check for partially selected text nodes\n                    if (isCharacterDataNode(current) && this.clonePartiallySelectedTextNodes) {\n                        if (current === this.ec) {\n                            (current = current.cloneNode(true)).deleteData(this.eo, current.length - this.eo);\n                        }\n                        if (this._current === this.sc) {\n                            (current = current.cloneNode(true)).deleteData(0, this.so);\n                        }\n                    }\n                }\n\n                return current;\n            },\n\n            remove: function() {\n                var current = this._current, start, end;\n\n                if (isCharacterDataNode(current) && (current === this.sc || current === this.ec)) {\n                    start = (current === this.sc) ? this.so : 0;\n                    end = (current === this.ec) ? this.eo : current.length;\n                    if (start != end) {\n                        current.deleteData(start, end - start);\n                    }\n                } else {\n                    if (current.parentNode) {\n                        current.parentNode.removeChild(current);\n                    } else {\n                    }\n                }\n            },\n\n            // Checks if the current node is partially selected\n            isPartiallySelectedSubtree: function() {\n                var current = this._current;\n                return isNonTextPartiallySelected(current, this.range);\n            },\n\n            getSubtreeIterator: function() {\n                var subRange;\n                if (this.isSingleCharacterDataNode) {\n                    subRange = this.range.cloneRange();\n                    subRange.collapse(false);\n                } else {\n                    subRange = new Range(getRangeDocument(this.range));\n                    var current = this._current;\n                    var startContainer = current, startOffset = 0, endContainer = current, endOffset = getNodeLength(current);\n\n                    if (isOrIsAncestorOf(current, this.sc)) {\n                        startContainer = this.sc;\n                        startOffset = this.so;\n                    }\n                    if (isOrIsAncestorOf(current, this.ec)) {\n                        endContainer = this.ec;\n                        endOffset = this.eo;\n                    }\n\n                    updateBoundaries(subRange, startContainer, startOffset, endContainer, endOffset);\n                }\n                return new RangeIterator(subRange, this.clonePartiallySelectedTextNodes);\n            },\n\n            detach: function() {\n                this.range = this._current = this._next = this._first = this._last = this.sc = this.so = this.ec = this.eo = null;\n            }\n        };\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        var beforeAfterNodeTypes = [1, 3, 4, 5, 7, 8, 10];\n        var rootContainerNodeTypes = [2, 9, 11];\n        var readonlyNodeTypes = [5, 6, 10, 12];\n        var insertableNodeTypes = [1, 3, 4, 5, 7, 8, 10, 11];\n        var surroundNodeTypes = [1, 3, 4, 5, 7, 8];\n\n        function createAncestorFinder(nodeTypes) {\n            return function(node, selfIsAncestor) {\n                var t, n = selfIsAncestor ? node : node.parentNode;\n                while (n) {\n                    t = n.nodeType;\n                    if (arrayContains(nodeTypes, t)) {\n                        return n;\n                    }\n                    n = n.parentNode;\n                }\n                return null;\n            };\n        }\n\n        var getDocumentOrFragmentContainer = createAncestorFinder( [9, 11] );\n        var getReadonlyAncestor = createAncestorFinder(readonlyNodeTypes);\n        var getDocTypeNotationEntityAncestor = createAncestorFinder( [6, 10, 12] );\n\n        function assertNoDocTypeNotationEntityAncestor(node, allowSelf) {\n            if (getDocTypeNotationEntityAncestor(node, allowSelf)) {\n                throw new DOMException(\"INVALID_NODE_TYPE_ERR\");\n            }\n        }\n\n        function assertValidNodeType(node, invalidTypes) {\n            if (!arrayContains(invalidTypes, node.nodeType)) {\n                throw new DOMException(\"INVALID_NODE_TYPE_ERR\");\n            }\n        }\n\n        function assertValidOffset(node, offset) {\n            if (offset < 0 || offset > (isCharacterDataNode(node) ? node.length : node.childNodes.length)) {\n                throw new DOMException(\"INDEX_SIZE_ERR\");\n            }\n        }\n\n        function assertSameDocumentOrFragment(node1, node2) {\n            if (getDocumentOrFragmentContainer(node1, true) !== getDocumentOrFragmentContainer(node2, true)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n        }\n\n        function assertNodeNotReadOnly(node) {\n            if (getReadonlyAncestor(node, true)) {\n                throw new DOMException(\"NO_MODIFICATION_ALLOWED_ERR\");\n            }\n        }\n\n        function assertNode(node, codeName) {\n            if (!node) {\n                throw new DOMException(codeName);\n            }\n        }\n\n        function isOrphan(node) {\n            return (crashyTextNodes && dom.isBrokenNode(node)) ||\n                !arrayContains(rootContainerNodeTypes, node.nodeType) && !getDocumentOrFragmentContainer(node, true);\n        }\n\n        function isValidOffset(node, offset) {\n            return offset <= (isCharacterDataNode(node) ? node.length : node.childNodes.length);\n        }\n\n        function isRangeValid(range) {\n            return (!!range.startContainer && !!range.endContainer &&\n                    !isOrphan(range.startContainer) &&\n                    !isOrphan(range.endContainer) &&\n                    isValidOffset(range.startContainer, range.startOffset) &&\n                    isValidOffset(range.endContainer, range.endOffset));\n        }\n\n        function assertRangeValid(range) {\n            if (!isRangeValid(range)) {\n                throw new Error(\"Range error: Range is no longer valid after DOM mutation (\" + range.inspect() + \")\");\n            }\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Test the browser's innerHTML support to decide how to implement createContextualFragment\n        var styleEl = document.createElement(\"style\");\n        var htmlParsingConforms = false;\n        try {\n            styleEl.innerHTML = \"<b>x</b>\";\n            htmlParsingConforms = (styleEl.firstChild.nodeType == 3); // Opera incorrectly creates an element node\n        } catch (e) {\n            // IE 6 and 7 throw\n        }\n\n        api.features.htmlParsingConforms = htmlParsingConforms;\n\n        var createContextualFragment = htmlParsingConforms ?\n\n            // Implementation as per HTML parsing spec, trusting in the browser's implementation of innerHTML. See\n            // discussion and base code for this implementation at issue 67.\n            // Spec: http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface\n            // Thanks to Aleks Williams.\n            function(fragmentStr) {\n                // \"Let node the context object's start's node.\"\n                var node = this.startContainer;\n                var doc = getDocument(node);\n\n                // \"If the context object's start's node is null, raise an INVALID_STATE_ERR\n                // exception and abort these steps.\"\n                if (!node) {\n                    throw new DOMException(\"INVALID_STATE_ERR\");\n                }\n\n                // \"Let element be as follows, depending on node's interface:\"\n                // Document, Document Fragment: null\n                var el = null;\n\n                // \"Element: node\"\n                if (node.nodeType == 1) {\n                    el = node;\n\n                // \"Text, Comment: node's parentElement\"\n                } else if (isCharacterDataNode(node)) {\n                    el = dom.parentElement(node);\n                }\n\n                // \"If either element is null or element's ownerDocument is an HTML document\n                // and element's local name is \"html\" and element's namespace is the HTML\n                // namespace\"\n                if (el === null || (\n                    el.nodeName == \"HTML\" &&\n                    dom.isHtmlNamespace(getDocument(el).documentElement) &&\n                    dom.isHtmlNamespace(el)\n                )) {\n\n                // \"let element be a new Element with \"body\" as its local name and the HTML\n                // namespace as its namespace.\"\"\n                    el = doc.createElement(\"body\");\n                } else {\n                    el = el.cloneNode(false);\n                }\n\n                // \"If the node's document is an HTML document: Invoke the HTML fragment parsing algorithm.\"\n                // \"If the node's document is an XML document: Invoke the XML fragment parsing algorithm.\"\n                // \"In either case, the algorithm must be invoked with fragment as the input\n                // and element as the context element.\"\n                el.innerHTML = fragmentStr;\n\n                // \"If this raises an exception, then abort these steps. Otherwise, let new\n                // children be the nodes returned.\"\n\n                // \"Let fragment be a new DocumentFragment.\"\n                // \"Append all new children to fragment.\"\n                // \"Return fragment.\"\n                return dom.fragmentFromNodeChildren(el);\n            } :\n\n            // In this case, innerHTML cannot be trusted, so fall back to a simpler, non-conformant implementation that\n            // previous versions of Rangy used (with the exception of using a body element rather than a div)\n            function(fragmentStr) {\n                var doc = getRangeDocument(this);\n                var el = doc.createElement(\"body\");\n                el.innerHTML = fragmentStr;\n\n                return dom.fragmentFromNodeChildren(el);\n            };\n\n        function splitRangeBoundaries(range, positionsToPreserve) {\n            assertRangeValid(range);\n\n            var sc = range.startContainer, so = range.startOffset, ec = range.endContainer, eo = range.endOffset;\n            var startEndSame = (sc === ec);\n\n            if (isCharacterDataNode(ec) && eo > 0 && eo < ec.length) {\n                splitDataNode(ec, eo, positionsToPreserve);\n            }\n\n            if (isCharacterDataNode(sc) && so > 0 && so < sc.length) {\n                sc = splitDataNode(sc, so, positionsToPreserve);\n                if (startEndSame) {\n                    eo -= so;\n                    ec = sc;\n                } else if (ec == sc.parentNode && eo >= getNodeIndex(sc)) {\n                    eo++;\n                }\n                so = 0;\n            }\n            range.setStartAndEnd(sc, so, ec, eo);\n        }\n        \n        function rangeToHtml(range) {\n            assertRangeValid(range);\n            var container = range.commonAncestorContainer.parentNode.cloneNode(false);\n            container.appendChild( range.cloneContents() );\n            return container.innerHTML;\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        var rangeProperties = [\"startContainer\", \"startOffset\", \"endContainer\", \"endOffset\", \"collapsed\",\n            \"commonAncestorContainer\"];\n\n        var s2s = 0, s2e = 1, e2e = 2, e2s = 3;\n        var n_b = 0, n_a = 1, n_b_a = 2, n_i = 3;\n\n        util.extend(api.rangePrototype, {\n            compareBoundaryPoints: function(how, range) {\n                assertRangeValid(this);\n                assertSameDocumentOrFragment(this.startContainer, range.startContainer);\n\n                var nodeA, offsetA, nodeB, offsetB;\n                var prefixA = (how == e2s || how == s2s) ? \"start\" : \"end\";\n                var prefixB = (how == s2e || how == s2s) ? \"start\" : \"end\";\n                nodeA = this[prefixA + \"Container\"];\n                offsetA = this[prefixA + \"Offset\"];\n                nodeB = range[prefixB + \"Container\"];\n                offsetB = range[prefixB + \"Offset\"];\n                return comparePoints(nodeA, offsetA, nodeB, offsetB);\n            },\n\n            insertNode: function(node) {\n                assertRangeValid(this);\n                assertValidNodeType(node, insertableNodeTypes);\n                assertNodeNotReadOnly(this.startContainer);\n\n                if (isOrIsAncestorOf(node, this.startContainer)) {\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n\n                // No check for whether the container of the start of the Range is of a type that does not allow\n                // children of the type of node: the browser's DOM implementation should do this for us when we attempt\n                // to add the node\n\n                var firstNodeInserted = insertNodeAtPosition(node, this.startContainer, this.startOffset);\n                this.setStartBefore(firstNodeInserted);\n            },\n\n            cloneContents: function() {\n                assertRangeValid(this);\n\n                var clone, frag;\n                if (this.collapsed) {\n                    return getRangeDocument(this).createDocumentFragment();\n                } else {\n                    if (this.startContainer === this.endContainer && isCharacterDataNode(this.startContainer)) {\n                        clone = this.startContainer.cloneNode(true);\n                        clone.data = clone.data.slice(this.startOffset, this.endOffset);\n                        frag = getRangeDocument(this).createDocumentFragment();\n                        frag.appendChild(clone);\n                        return frag;\n                    } else {\n                        var iterator = new RangeIterator(this, true);\n                        clone = cloneSubtree(iterator);\n                        iterator.detach();\n                    }\n                    return clone;\n                }\n            },\n\n            canSurroundContents: function() {\n                assertRangeValid(this);\n                assertNodeNotReadOnly(this.startContainer);\n                assertNodeNotReadOnly(this.endContainer);\n\n                // Check if the contents can be surrounded. Specifically, this means whether the range partially selects\n                // no non-text nodes.\n                var iterator = new RangeIterator(this, true);\n                var boundariesInvalid = (iterator._first && (isNonTextPartiallySelected(iterator._first, this)) ||\n                        (iterator._last && isNonTextPartiallySelected(iterator._last, this)));\n                iterator.detach();\n                return !boundariesInvalid;\n            },\n\n            surroundContents: function(node) {\n                assertValidNodeType(node, surroundNodeTypes);\n\n                if (!this.canSurroundContents()) {\n                    throw new DOMException(\"INVALID_STATE_ERR\");\n                }\n\n                // Extract the contents\n                var content = this.extractContents();\n\n                // Clear the children of the node\n                if (node.hasChildNodes()) {\n                    while (node.lastChild) {\n                        node.removeChild(node.lastChild);\n                    }\n                }\n\n                // Insert the new node and add the extracted contents\n                insertNodeAtPosition(node, this.startContainer, this.startOffset);\n                node.appendChild(content);\n\n                this.selectNode(node);\n            },\n\n            cloneRange: function() {\n                assertRangeValid(this);\n                var range = new Range(getRangeDocument(this));\n                var i = rangeProperties.length, prop;\n                while (i--) {\n                    prop = rangeProperties[i];\n                    range[prop] = this[prop];\n                }\n                return range;\n            },\n\n            toString: function() {\n                assertRangeValid(this);\n                var sc = this.startContainer;\n                if (sc === this.endContainer && isCharacterDataNode(sc)) {\n                    return (sc.nodeType == 3 || sc.nodeType == 4) ? sc.data.slice(this.startOffset, this.endOffset) : \"\";\n                } else {\n                    var textParts = [], iterator = new RangeIterator(this, true);\n                    iterateSubtree(iterator, function(node) {\n                        // Accept only text or CDATA nodes, not comments\n                        if (node.nodeType == 3 || node.nodeType == 4) {\n                            textParts.push(node.data);\n                        }\n                    });\n                    iterator.detach();\n                    return textParts.join(\"\");\n                }\n            },\n\n            // The methods below are all non-standard. The following batch were introduced by Mozilla but have since\n            // been removed from Mozilla.\n\n            compareNode: function(node) {\n                assertRangeValid(this);\n\n                var parent = node.parentNode;\n                var nodeIndex = getNodeIndex(node);\n\n                if (!parent) {\n                    throw new DOMException(\"NOT_FOUND_ERR\");\n                }\n\n                var startComparison = this.comparePoint(parent, nodeIndex),\n                    endComparison = this.comparePoint(parent, nodeIndex + 1);\n\n                if (startComparison < 0) { // Node starts before\n                    return (endComparison > 0) ? n_b_a : n_b;\n                } else {\n                    return (endComparison > 0) ? n_a : n_i;\n                }\n            },\n\n            comparePoint: function(node, offset) {\n                assertRangeValid(this);\n                assertNode(node, \"HIERARCHY_REQUEST_ERR\");\n                assertSameDocumentOrFragment(node, this.startContainer);\n\n                if (comparePoints(node, offset, this.startContainer, this.startOffset) < 0) {\n                    return -1;\n                } else if (comparePoints(node, offset, this.endContainer, this.endOffset) > 0) {\n                    return 1;\n                }\n                return 0;\n            },\n\n            createContextualFragment: createContextualFragment,\n\n            toHtml: function() {\n                return rangeToHtml(this);\n            },\n\n            // touchingIsIntersecting determines whether this method considers a node that borders a range intersects\n            // with it (as in WebKit) or not (as in Gecko pre-1.9, and the default)\n            intersectsNode: function(node, touchingIsIntersecting) {\n                assertRangeValid(this);\n                assertNode(node, \"NOT_FOUND_ERR\");\n                if (getDocument(node) !== getRangeDocument(this)) {\n                    return false;\n                }\n\n                var parent = node.parentNode, offset = getNodeIndex(node);\n                assertNode(parent, \"NOT_FOUND_ERR\");\n\n                var startComparison = comparePoints(parent, offset, this.endContainer, this.endOffset),\n                    endComparison = comparePoints(parent, offset + 1, this.startContainer, this.startOffset);\n\n                return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;\n            },\n\n            isPointInRange: function(node, offset) {\n                assertRangeValid(this);\n                assertNode(node, \"HIERARCHY_REQUEST_ERR\");\n                assertSameDocumentOrFragment(node, this.startContainer);\n\n                return (comparePoints(node, offset, this.startContainer, this.startOffset) >= 0) &&\n                       (comparePoints(node, offset, this.endContainer, this.endOffset) <= 0);\n            },\n\n            // The methods below are non-standard and invented by me.\n\n            // Sharing a boundary start-to-end or end-to-start does not count as intersection.\n            intersectsRange: function(range) {\n                return rangesIntersect(this, range, false);\n            },\n\n            // Sharing a boundary start-to-end or end-to-start does count as intersection.\n            intersectsOrTouchesRange: function(range) {\n                return rangesIntersect(this, range, true);\n            },\n\n            intersection: function(range) {\n                if (this.intersectsRange(range)) {\n                    var startComparison = comparePoints(this.startContainer, this.startOffset, range.startContainer, range.startOffset),\n                        endComparison = comparePoints(this.endContainer, this.endOffset, range.endContainer, range.endOffset);\n\n                    var intersectionRange = this.cloneRange();\n                    if (startComparison == -1) {\n                        intersectionRange.setStart(range.startContainer, range.startOffset);\n                    }\n                    if (endComparison == 1) {\n                        intersectionRange.setEnd(range.endContainer, range.endOffset);\n                    }\n                    return intersectionRange;\n                }\n                return null;\n            },\n\n            union: function(range) {\n                if (this.intersectsOrTouchesRange(range)) {\n                    var unionRange = this.cloneRange();\n                    if (comparePoints(range.startContainer, range.startOffset, this.startContainer, this.startOffset) == -1) {\n                        unionRange.setStart(range.startContainer, range.startOffset);\n                    }\n                    if (comparePoints(range.endContainer, range.endOffset, this.endContainer, this.endOffset) == 1) {\n                        unionRange.setEnd(range.endContainer, range.endOffset);\n                    }\n                    return unionRange;\n                } else {\n                    throw new DOMException(\"Ranges do not intersect\");\n                }\n            },\n\n            containsNode: function(node, allowPartial) {\n                if (allowPartial) {\n                    return this.intersectsNode(node, false);\n                } else {\n                    return this.compareNode(node) == n_i;\n                }\n            },\n\n            containsNodeContents: function(node) {\n                return this.comparePoint(node, 0) >= 0 && this.comparePoint(node, getNodeLength(node)) <= 0;\n            },\n\n            containsRange: function(range) {\n                var intersection = this.intersection(range);\n                return intersection !== null && range.equals(intersection);\n            },\n\n            containsNodeText: function(node) {\n                var nodeRange = this.cloneRange();\n                nodeRange.selectNode(node);\n                var textNodes = nodeRange.getNodes([3]);\n                if (textNodes.length > 0) {\n                    nodeRange.setStart(textNodes[0], 0);\n                    var lastTextNode = textNodes.pop();\n                    nodeRange.setEnd(lastTextNode, lastTextNode.length);\n                    return this.containsRange(nodeRange);\n                } else {\n                    return this.containsNodeContents(node);\n                }\n            },\n\n            getNodes: function(nodeTypes, filter) {\n                assertRangeValid(this);\n                return getNodesInRange(this, nodeTypes, filter);\n            },\n\n            getDocument: function() {\n                return getRangeDocument(this);\n            },\n\n            collapseBefore: function(node) {\n                this.setEndBefore(node);\n                this.collapse(false);\n            },\n\n            collapseAfter: function(node) {\n                this.setStartAfter(node);\n                this.collapse(true);\n            },\n            \n            getBookmark: function(containerNode) {\n                var doc = getRangeDocument(this);\n                var preSelectionRange = api.createRange(doc);\n                containerNode = containerNode || dom.getBody(doc);\n                preSelectionRange.selectNodeContents(containerNode);\n                var range = this.intersection(preSelectionRange);\n                var start = 0, end = 0;\n                if (range) {\n                    preSelectionRange.setEnd(range.startContainer, range.startOffset);\n                    start = preSelectionRange.toString().length;\n                    end = start + range.toString().length;\n                }\n\n                return {\n                    start: start,\n                    end: end,\n                    containerNode: containerNode\n                };\n            },\n            \n            moveToBookmark: function(bookmark) {\n                var containerNode = bookmark.containerNode;\n                var charIndex = 0;\n                this.setStart(containerNode, 0);\n                this.collapse(true);\n                var nodeStack = [containerNode], node, foundStart = false, stop = false;\n                var nextCharIndex, i, childNodes;\n\n                while (!stop && (node = nodeStack.pop())) {\n                    if (node.nodeType == 3) {\n                        nextCharIndex = charIndex + node.length;\n                        if (!foundStart && bookmark.start >= charIndex && bookmark.start <= nextCharIndex) {\n                            this.setStart(node, bookmark.start - charIndex);\n                            foundStart = true;\n                        }\n                        if (foundStart && bookmark.end >= charIndex && bookmark.end <= nextCharIndex) {\n                            this.setEnd(node, bookmark.end - charIndex);\n                            stop = true;\n                        }\n                        charIndex = nextCharIndex;\n                    } else {\n                        childNodes = node.childNodes;\n                        i = childNodes.length;\n                        while (i--) {\n                            nodeStack.push(childNodes[i]);\n                        }\n                    }\n                }\n            },\n\n            getName: function() {\n                return \"DomRange\";\n            },\n\n            equals: function(range) {\n                return Range.rangesEqual(this, range);\n            },\n\n            isValid: function() {\n                return isRangeValid(this);\n            },\n            \n            inspect: function() {\n                return inspect(this);\n            },\n            \n            detach: function() {\n                // In DOM4, detach() is now a no-op.\n            }\n        });\n\n        function copyComparisonConstantsToObject(obj) {\n            obj.START_TO_START = s2s;\n            obj.START_TO_END = s2e;\n            obj.END_TO_END = e2e;\n            obj.END_TO_START = e2s;\n\n            obj.NODE_BEFORE = n_b;\n            obj.NODE_AFTER = n_a;\n            obj.NODE_BEFORE_AND_AFTER = n_b_a;\n            obj.NODE_INSIDE = n_i;\n        }\n\n        function copyComparisonConstants(constructor) {\n            copyComparisonConstantsToObject(constructor);\n            copyComparisonConstantsToObject(constructor.prototype);\n        }\n\n        function createRangeContentRemover(remover, boundaryUpdater) {\n            return function() {\n                assertRangeValid(this);\n\n                var sc = this.startContainer, so = this.startOffset, root = this.commonAncestorContainer;\n\n                var iterator = new RangeIterator(this, true);\n\n                // Work out where to position the range after content removal\n                var node, boundary;\n                if (sc !== root) {\n                    node = getClosestAncestorIn(sc, root, true);\n                    boundary = getBoundaryAfterNode(node);\n                    sc = boundary.node;\n                    so = boundary.offset;\n                }\n\n                // Check none of the range is read-only\n                iterateSubtree(iterator, assertNodeNotReadOnly);\n\n                iterator.reset();\n\n                // Remove the content\n                var returnValue = remover(iterator);\n                iterator.detach();\n\n                // Move to the new position\n                boundaryUpdater(this, sc, so, sc, so);\n\n                return returnValue;\n            };\n        }\n\n        function createPrototypeRange(constructor, boundaryUpdater) {\n            function createBeforeAfterNodeSetter(isBefore, isStart) {\n                return function(node) {\n                    assertValidNodeType(node, beforeAfterNodeTypes);\n                    assertValidNodeType(getRootContainer(node), rootContainerNodeTypes);\n\n                    var boundary = (isBefore ? getBoundaryBeforeNode : getBoundaryAfterNode)(node);\n                    (isStart ? setRangeStart : setRangeEnd)(this, boundary.node, boundary.offset);\n                };\n            }\n\n            function setRangeStart(range, node, offset) {\n                var ec = range.endContainer, eo = range.endOffset;\n                if (node !== range.startContainer || offset !== range.startOffset) {\n                    // Check the root containers of the range and the new boundary, and also check whether the new boundary\n                    // is after the current end. In either case, collapse the range to the new position\n                    if (getRootContainer(node) != getRootContainer(ec) || comparePoints(node, offset, ec, eo) == 1) {\n                        ec = node;\n                        eo = offset;\n                    }\n                    boundaryUpdater(range, node, offset, ec, eo);\n                }\n            }\n\n            function setRangeEnd(range, node, offset) {\n                var sc = range.startContainer, so = range.startOffset;\n                if (node !== range.endContainer || offset !== range.endOffset) {\n                    // Check the root containers of the range and the new boundary, and also check whether the new boundary\n                    // is after the current end. In either case, collapse the range to the new position\n                    if (getRootContainer(node) != getRootContainer(sc) || comparePoints(node, offset, sc, so) == -1) {\n                        sc = node;\n                        so = offset;\n                    }\n                    boundaryUpdater(range, sc, so, node, offset);\n                }\n            }\n\n            // Set up inheritance\n            var F = function() {};\n            F.prototype = api.rangePrototype;\n            constructor.prototype = new F();\n\n            util.extend(constructor.prototype, {\n                setStart: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n\n                    setRangeStart(this, node, offset);\n                },\n\n                setEnd: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n\n                    setRangeEnd(this, node, offset);\n                },\n\n                /**\n                 * Convenience method to set a range's start and end boundaries. Overloaded as follows:\n                 * - Two parameters (node, offset) creates a collapsed range at that position\n                 * - Three parameters (node, startOffset, endOffset) creates a range contained with node starting at\n                 *   startOffset and ending at endOffset\n                 * - Four parameters (startNode, startOffset, endNode, endOffset) creates a range starting at startOffset in\n                 *   startNode and ending at endOffset in endNode\n                 */\n                setStartAndEnd: function() {\n                    var args = arguments;\n                    var sc = args[0], so = args[1], ec = sc, eo = so;\n\n                    switch (args.length) {\n                        case 3:\n                            eo = args[2];\n                            break;\n                        case 4:\n                            ec = args[2];\n                            eo = args[3];\n                            break;\n                    }\n\n                    boundaryUpdater(this, sc, so, ec, eo);\n                },\n                \n                setBoundary: function(node, offset, isStart) {\n                    this[\"set\" + (isStart ? \"Start\" : \"End\")](node, offset);\n                },\n\n                setStartBefore: createBeforeAfterNodeSetter(true, true),\n                setStartAfter: createBeforeAfterNodeSetter(false, true),\n                setEndBefore: createBeforeAfterNodeSetter(true, false),\n                setEndAfter: createBeforeAfterNodeSetter(false, false),\n\n                collapse: function(isStart) {\n                    assertRangeValid(this);\n                    if (isStart) {\n                        boundaryUpdater(this, this.startContainer, this.startOffset, this.startContainer, this.startOffset);\n                    } else {\n                        boundaryUpdater(this, this.endContainer, this.endOffset, this.endContainer, this.endOffset);\n                    }\n                },\n\n                selectNodeContents: function(node) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n\n                    boundaryUpdater(this, node, 0, node, getNodeLength(node));\n                },\n\n                selectNode: function(node) {\n                    assertNoDocTypeNotationEntityAncestor(node, false);\n                    assertValidNodeType(node, beforeAfterNodeTypes);\n\n                    var start = getBoundaryBeforeNode(node), end = getBoundaryAfterNode(node);\n                    boundaryUpdater(this, start.node, start.offset, end.node, end.offset);\n                },\n\n                extractContents: createRangeContentRemover(extractSubtree, boundaryUpdater),\n\n                deleteContents: createRangeContentRemover(deleteSubtree, boundaryUpdater),\n\n                canSurroundContents: function() {\n                    assertRangeValid(this);\n                    assertNodeNotReadOnly(this.startContainer);\n                    assertNodeNotReadOnly(this.endContainer);\n\n                    // Check if the contents can be surrounded. Specifically, this means whether the range partially selects\n                    // no non-text nodes.\n                    var iterator = new RangeIterator(this, true);\n                    var boundariesInvalid = (iterator._first && isNonTextPartiallySelected(iterator._first, this) ||\n                            (iterator._last && isNonTextPartiallySelected(iterator._last, this)));\n                    iterator.detach();\n                    return !boundariesInvalid;\n                },\n\n                splitBoundaries: function() {\n                    splitRangeBoundaries(this);\n                },\n\n                splitBoundariesPreservingPositions: function(positionsToPreserve) {\n                    splitRangeBoundaries(this, positionsToPreserve);\n                },\n\n                normalizeBoundaries: function() {\n                    assertRangeValid(this);\n\n                    var sc = this.startContainer, so = this.startOffset, ec = this.endContainer, eo = this.endOffset;\n\n                    var mergeForward = function(node) {\n                        var sibling = node.nextSibling;\n                        if (sibling && sibling.nodeType == node.nodeType) {\n                            ec = node;\n                            eo = node.length;\n                            node.appendData(sibling.data);\n                            sibling.parentNode.removeChild(sibling);\n                        }\n                    };\n\n                    var mergeBackward = function(node) {\n                        var sibling = node.previousSibling;\n                        if (sibling && sibling.nodeType == node.nodeType) {\n                            sc = node;\n                            var nodeLength = node.length;\n                            so = sibling.length;\n                            node.insertData(0, sibling.data);\n                            sibling.parentNode.removeChild(sibling);\n                            if (sc == ec) {\n                                eo += so;\n                                ec = sc;\n                            } else if (ec == node.parentNode) {\n                                var nodeIndex = getNodeIndex(node);\n                                if (eo == nodeIndex) {\n                                    ec = node;\n                                    eo = nodeLength;\n                                } else if (eo > nodeIndex) {\n                                    eo--;\n                                }\n                            }\n                        }\n                    };\n\n                    var normalizeStart = true;\n\n                    if (isCharacterDataNode(ec)) {\n                        if (ec.length == eo) {\n                            mergeForward(ec);\n                        }\n                    } else {\n                        if (eo > 0) {\n                            var endNode = ec.childNodes[eo - 1];\n                            if (endNode && isCharacterDataNode(endNode)) {\n                                mergeForward(endNode);\n                            }\n                        }\n                        normalizeStart = !this.collapsed;\n                    }\n\n                    if (normalizeStart) {\n                        if (isCharacterDataNode(sc)) {\n                            if (so == 0) {\n                                mergeBackward(sc);\n                            }\n                        } else {\n                            if (so < sc.childNodes.length) {\n                                var startNode = sc.childNodes[so];\n                                if (startNode && isCharacterDataNode(startNode)) {\n                                    mergeBackward(startNode);\n                                }\n                            }\n                        }\n                    } else {\n                        sc = ec;\n                        so = eo;\n                    }\n\n                    boundaryUpdater(this, sc, so, ec, eo);\n                },\n\n                collapseToPoint: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n                    this.setStartAndEnd(node, offset);\n                }\n            });\n\n            copyComparisonConstants(constructor);\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Updates commonAncestorContainer and collapsed after boundary change\n        function updateCollapsedAndCommonAncestor(range) {\n            range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);\n            range.commonAncestorContainer = range.collapsed ?\n                range.startContainer : dom.getCommonAncestor(range.startContainer, range.endContainer);\n        }\n\n        function updateBoundaries(range, startContainer, startOffset, endContainer, endOffset) {\n            range.startContainer = startContainer;\n            range.startOffset = startOffset;\n            range.endContainer = endContainer;\n            range.endOffset = endOffset;\n            range.document = dom.getDocument(startContainer);\n\n            updateCollapsedAndCommonAncestor(range);\n        }\n\n        function Range(doc) {\n            this.startContainer = doc;\n            this.startOffset = 0;\n            this.endContainer = doc;\n            this.endOffset = 0;\n            this.document = doc;\n            updateCollapsedAndCommonAncestor(this);\n        }\n\n        createPrototypeRange(Range, updateBoundaries);\n\n        util.extend(Range, {\n            rangeProperties: rangeProperties,\n            RangeIterator: RangeIterator,\n            copyComparisonConstants: copyComparisonConstants,\n            createPrototypeRange: createPrototypeRange,\n            inspect: inspect,\n            toHtml: rangeToHtml,\n            getRangeDocument: getRangeDocument,\n            rangesEqual: function(r1, r2) {\n                return r1.startContainer === r2.startContainer &&\n                    r1.startOffset === r2.startOffset &&\n                    r1.endContainer === r2.endContainer &&\n                    r1.endOffset === r2.endOffset;\n            }\n        });\n\n        api.DomRange = Range;\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Wrappers for the browser's native DOM Range and/or TextRange implementation \n    api.createCoreModule(\"WrappedRange\", [\"DomRange\"], function(api, module) {\n        var WrappedRange, WrappedTextRange;\n        var dom = api.dom;\n        var util = api.util;\n        var DomPosition = dom.DomPosition;\n        var DomRange = api.DomRange;\n        var getBody = dom.getBody;\n        var getContentDocument = dom.getContentDocument;\n        var isCharacterDataNode = dom.isCharacterDataNode;\n\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        if (api.features.implementsDomRange) {\n            // This is a wrapper around the browser's native DOM Range. It has two aims:\n            // - Provide workarounds for specific browser bugs\n            // - provide convenient extensions, which are inherited from Rangy's DomRange\n\n            (function() {\n                var rangeProto;\n                var rangeProperties = DomRange.rangeProperties;\n\n                function updateRangeProperties(range) {\n                    var i = rangeProperties.length, prop;\n                    while (i--) {\n                        prop = rangeProperties[i];\n                        range[prop] = range.nativeRange[prop];\n                    }\n                    // Fix for broken collapsed property in IE 9.\n                    range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);\n                }\n\n                function updateNativeRange(range, startContainer, startOffset, endContainer, endOffset) {\n                    var startMoved = (range.startContainer !== startContainer || range.startOffset != startOffset);\n                    var endMoved = (range.endContainer !== endContainer || range.endOffset != endOffset);\n                    var nativeRangeDifferent = !range.equals(range.nativeRange);\n\n                    // Always set both boundaries for the benefit of IE9 (see issue 35)\n                    if (startMoved || endMoved || nativeRangeDifferent) {\n                        range.setEnd(endContainer, endOffset);\n                        range.setStart(startContainer, startOffset);\n                    }\n                }\n\n                var createBeforeAfterNodeSetter;\n\n                WrappedRange = function(range) {\n                    if (!range) {\n                        throw module.createError(\"WrappedRange: Range must be specified\");\n                    }\n                    this.nativeRange = range;\n                    updateRangeProperties(this);\n                };\n\n                DomRange.createPrototypeRange(WrappedRange, updateNativeRange);\n\n                rangeProto = WrappedRange.prototype;\n\n                rangeProto.selectNode = function(node) {\n                    this.nativeRange.selectNode(node);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.cloneContents = function() {\n                    return this.nativeRange.cloneContents();\n                };\n\n                // Due to a long-standing Firefox bug that I have not been able to find a reliable way to detect,\n                // insertNode() is never delegated to the native range.\n\n                rangeProto.surroundContents = function(node) {\n                    this.nativeRange.surroundContents(node);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.collapse = function(isStart) {\n                    this.nativeRange.collapse(isStart);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.cloneRange = function() {\n                    return new WrappedRange(this.nativeRange.cloneRange());\n                };\n\n                rangeProto.refresh = function() {\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.toString = function() {\n                    return this.nativeRange.toString();\n                };\n\n                // Create test range and node for feature detection\n\n                var testTextNode = document.createTextNode(\"test\");\n                getBody(document).appendChild(testTextNode);\n                var range = document.createRange();\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for Firefox 2 bug that prevents moving the start of a Range to a point after its current end and\n                // correct for it\n\n                range.setStart(testTextNode, 0);\n                range.setEnd(testTextNode, 0);\n\n                try {\n                    range.setStart(testTextNode, 1);\n\n                    rangeProto.setStart = function(node, offset) {\n                        this.nativeRange.setStart(node, offset);\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.setEnd = function(node, offset) {\n                        this.nativeRange.setEnd(node, offset);\n                        updateRangeProperties(this);\n                    };\n\n                    createBeforeAfterNodeSetter = function(name) {\n                        return function(node) {\n                            this.nativeRange[name](node);\n                            updateRangeProperties(this);\n                        };\n                    };\n\n                } catch(ex) {\n\n                    rangeProto.setStart = function(node, offset) {\n                        try {\n                            this.nativeRange.setStart(node, offset);\n                        } catch (ex) {\n                            this.nativeRange.setEnd(node, offset);\n                            this.nativeRange.setStart(node, offset);\n                        }\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.setEnd = function(node, offset) {\n                        try {\n                            this.nativeRange.setEnd(node, offset);\n                        } catch (ex) {\n                            this.nativeRange.setStart(node, offset);\n                            this.nativeRange.setEnd(node, offset);\n                        }\n                        updateRangeProperties(this);\n                    };\n\n                    createBeforeAfterNodeSetter = function(name, oppositeName) {\n                        return function(node) {\n                            try {\n                                this.nativeRange[name](node);\n                            } catch (ex) {\n                                this.nativeRange[oppositeName](node);\n                                this.nativeRange[name](node);\n                            }\n                            updateRangeProperties(this);\n                        };\n                    };\n                }\n\n                rangeProto.setStartBefore = createBeforeAfterNodeSetter(\"setStartBefore\", \"setEndBefore\");\n                rangeProto.setStartAfter = createBeforeAfterNodeSetter(\"setStartAfter\", \"setEndAfter\");\n                rangeProto.setEndBefore = createBeforeAfterNodeSetter(\"setEndBefore\", \"setStartBefore\");\n                rangeProto.setEndAfter = createBeforeAfterNodeSetter(\"setEndAfter\", \"setStartAfter\");\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Always use DOM4-compliant selectNodeContents implementation: it's simpler and less code than testing\n                // whether the native implementation can be trusted\n                rangeProto.selectNodeContents = function(node) {\n                    this.setStartAndEnd(node, 0, dom.getNodeLength(node));\n                };\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for and correct WebKit bug that has the behaviour of compareBoundaryPoints round the wrong way for\n                // constants START_TO_END and END_TO_START: https://bugs.webkit.org/show_bug.cgi?id=20738\n\n                range.selectNodeContents(testTextNode);\n                range.setEnd(testTextNode, 3);\n\n                var range2 = document.createRange();\n                range2.selectNodeContents(testTextNode);\n                range2.setEnd(testTextNode, 4);\n                range2.setStart(testTextNode, 2);\n\n                if (range.compareBoundaryPoints(range.START_TO_END, range2) == -1 &&\n                        range.compareBoundaryPoints(range.END_TO_START, range2) == 1) {\n                    // This is the wrong way round, so correct for it\n\n                    rangeProto.compareBoundaryPoints = function(type, range) {\n                        range = range.nativeRange || range;\n                        if (type == range.START_TO_END) {\n                            type = range.END_TO_START;\n                        } else if (type == range.END_TO_START) {\n                            type = range.START_TO_END;\n                        }\n                        return this.nativeRange.compareBoundaryPoints(type, range);\n                    };\n                } else {\n                    rangeProto.compareBoundaryPoints = function(type, range) {\n                        return this.nativeRange.compareBoundaryPoints(type, range.nativeRange || range);\n                    };\n                }\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for IE deleteContents() and extractContents() bug and correct it. See issue 107.\n\n                var el = document.createElement(\"div\");\n                el.innerHTML = \"123\";\n                var textNode = el.firstChild;\n                var body = getBody(document);\n                body.appendChild(el);\n\n                range.setStart(textNode, 1);\n                range.setEnd(textNode, 2);\n                range.deleteContents();\n\n                if (textNode.data == \"13\") {\n                    // Behaviour is correct per DOM4 Range so wrap the browser's implementation of deleteContents() and\n                    // extractContents()\n                    rangeProto.deleteContents = function() {\n                        this.nativeRange.deleteContents();\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.extractContents = function() {\n                        var frag = this.nativeRange.extractContents();\n                        updateRangeProperties(this);\n                        return frag;\n                    };\n                } else {\n                }\n\n                body.removeChild(el);\n                body = null;\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for existence of createContextualFragment and delegate to it if it exists\n                if (util.isHostMethod(range, \"createContextualFragment\")) {\n                    rangeProto.createContextualFragment = function(fragmentStr) {\n                        return this.nativeRange.createContextualFragment(fragmentStr);\n                    };\n                }\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Clean up\n                getBody(document).removeChild(testTextNode);\n\n                rangeProto.getName = function() {\n                    return \"WrappedRange\";\n                };\n\n                api.WrappedRange = WrappedRange;\n\n                api.createNativeRange = function(doc) {\n                    doc = getContentDocument(doc, module, \"createNativeRange\");\n                    return doc.createRange();\n                };\n            })();\n        }\n        \n        if (api.features.implementsTextRange) {\n            /*\n            This is a workaround for a bug where IE returns the wrong container element from the TextRange's parentElement()\n            method. For example, in the following (where pipes denote the selection boundaries):\n\n            <ul id=\"ul\"><li id=\"a\">| a </li><li id=\"b\"> b |</li></ul>\n\n            var range = document.selection.createRange();\n            alert(range.parentElement().id); // Should alert \"ul\" but alerts \"b\"\n\n            This method returns the common ancestor node of the following:\n            - the parentElement() of the textRange\n            - the parentElement() of the textRange after calling collapse(true)\n            - the parentElement() of the textRange after calling collapse(false)\n            */\n            var getTextRangeContainerElement = function(textRange) {\n                var parentEl = textRange.parentElement();\n                var range = textRange.duplicate();\n                range.collapse(true);\n                var startEl = range.parentElement();\n                range = textRange.duplicate();\n                range.collapse(false);\n                var endEl = range.parentElement();\n                var startEndContainer = (startEl == endEl) ? startEl : dom.getCommonAncestor(startEl, endEl);\n\n                return startEndContainer == parentEl ? startEndContainer : dom.getCommonAncestor(parentEl, startEndContainer);\n            };\n\n            var textRangeIsCollapsed = function(textRange) {\n                return textRange.compareEndPoints(\"StartToEnd\", textRange) == 0;\n            };\n\n            // Gets the boundary of a TextRange expressed as a node and an offset within that node. This function started\n            // out as an improved version of code found in Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/)\n            // but has grown, fixing problems with line breaks in preformatted text, adding workaround for IE TextRange\n            // bugs, handling for inputs and images, plus optimizations.\n            var getTextRangeBoundaryPosition = function(textRange, wholeRangeContainerElement, isStart, isCollapsed, startInfo) {\n                var workingRange = textRange.duplicate();\n                workingRange.collapse(isStart);\n                var containerElement = workingRange.parentElement();\n\n                // Sometimes collapsing a TextRange that's at the start of a text node can move it into the previous node, so\n                // check for that\n                if (!dom.isOrIsAncestorOf(wholeRangeContainerElement, containerElement)) {\n                    containerElement = wholeRangeContainerElement;\n                }\n\n\n                // Deal with nodes that cannot \"contain rich HTML markup\". In practice, this means form inputs, images and\n                // similar. See http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx\n                if (!containerElement.canHaveHTML) {\n                    var pos = new DomPosition(containerElement.parentNode, dom.getNodeIndex(containerElement));\n                    return {\n                        boundaryPosition: pos,\n                        nodeInfo: {\n                            nodeIndex: pos.offset,\n                            containerElement: pos.node\n                        }\n                    };\n                }\n\n                var workingNode = dom.getDocument(containerElement).createElement(\"span\");\n\n                // Workaround for HTML5 Shiv's insane violation of document.createElement(). See Rangy issue 104 and HTML5\n                // Shiv issue 64: https://github.com/aFarkas/html5shiv/issues/64\n                if (workingNode.parentNode) {\n                    workingNode.parentNode.removeChild(workingNode);\n                }\n\n                var comparison, workingComparisonType = isStart ? \"StartToStart\" : \"StartToEnd\";\n                var previousNode, nextNode, boundaryPosition, boundaryNode;\n                var start = (startInfo && startInfo.containerElement == containerElement) ? startInfo.nodeIndex : 0;\n                var childNodeCount = containerElement.childNodes.length;\n                var end = childNodeCount;\n\n                // Check end first. Code within the loop assumes that the endth child node of the container is definitely\n                // after the range boundary.\n                var nodeIndex = end;\n\n                while (true) {\n                    if (nodeIndex == childNodeCount) {\n                        containerElement.appendChild(workingNode);\n                    } else {\n                        containerElement.insertBefore(workingNode, containerElement.childNodes[nodeIndex]);\n                    }\n                    workingRange.moveToElementText(workingNode);\n                    comparison = workingRange.compareEndPoints(workingComparisonType, textRange);\n                    if (comparison == 0 || start == end) {\n                        break;\n                    } else if (comparison == -1) {\n                        if (end == start + 1) {\n                            // We know the endth child node is after the range boundary, so we must be done.\n                            break;\n                        } else {\n                            start = nodeIndex;\n                        }\n                    } else {\n                        end = (end == start + 1) ? start : nodeIndex;\n                    }\n                    nodeIndex = Math.floor((start + end) / 2);\n                    containerElement.removeChild(workingNode);\n                }\n\n\n                // We've now reached or gone past the boundary of the text range we're interested in\n                // so have identified the node we want\n                boundaryNode = workingNode.nextSibling;\n\n                if (comparison == -1 && boundaryNode && isCharacterDataNode(boundaryNode)) {\n                    // This is a character data node (text, comment, cdata). The working range is collapsed at the start of\n                    // the node containing the text range's boundary, so we move the end of the working range to the\n                    // boundary point and measure the length of its text to get the boundary's offset within the node.\n                    workingRange.setEndPoint(isStart ? \"EndToStart\" : \"EndToEnd\", textRange);\n\n                    var offset;\n\n                    if (/[\\r\\n]/.test(boundaryNode.data)) {\n                        /*\n                        For the particular case of a boundary within a text node containing rendered line breaks (within a\n                        <pre> element, for example), we need a slightly complicated approach to get the boundary's offset in\n                        IE. The facts:\n                        \n                        - Each line break is represented as \\r in the text node's data/nodeValue properties\n                        - Each line break is represented as \\r\\n in the TextRange's 'text' property\n                        - The 'text' property of the TextRange does not contain trailing line breaks\n                        \n                        To get round the problem presented by the final fact above, we can use the fact that TextRange's\n                        moveStart() and moveEnd() methods return the actual number of characters moved, which is not\n                        necessarily the same as the number of characters it was instructed to move. The simplest approach is\n                        to use this to store the characters moved when moving both the start and end of the range to the\n                        start of the document body and subtracting the start offset from the end offset (the\n                        \"move-negative-gazillion\" method). However, this is extremely slow when the document is large and\n                        the range is near the end of it. Clearly doing the mirror image (i.e. moving the range boundaries to\n                        the end of the document) has the same problem.\n                        \n                        Another approach that works is to use moveStart() to move the start boundary of the range up to the\n                        end boundary one character at a time and incrementing a counter with the value returned by the\n                        moveStart() call. However, the check for whether the start boundary has reached the end boundary is\n                        expensive, so this method is slow (although unlike \"move-negative-gazillion\" is largely unaffected\n                        by the location of the range within the document).\n                        \n                        The approach used below is a hybrid of the two methods above. It uses the fact that a string\n                        containing the TextRange's 'text' property with each \\r\\n converted to a single \\r character cannot\n                        be longer than the text of the TextRange, so the start of the range is moved that length initially\n                        and then a character at a time to make up for any trailing line breaks not contained in the 'text'\n                        property. This has good performance in most situations compared to the previous two methods.\n                        */\n                        var tempRange = workingRange.duplicate();\n                        var rangeLength = tempRange.text.replace(/\\r\\n/g, \"\\r\").length;\n\n                        offset = tempRange.moveStart(\"character\", rangeLength);\n                        while ( (comparison = tempRange.compareEndPoints(\"StartToEnd\", tempRange)) == -1) {\n                            offset++;\n                            tempRange.moveStart(\"character\", 1);\n                        }\n                    } else {\n                        offset = workingRange.text.length;\n                    }\n                    boundaryPosition = new DomPosition(boundaryNode, offset);\n                } else {\n\n                    // If the boundary immediately follows a character data node and this is the end boundary, we should favour\n                    // a position within that, and likewise for a start boundary preceding a character data node\n                    previousNode = (isCollapsed || !isStart) && workingNode.previousSibling;\n                    nextNode = (isCollapsed || isStart) && workingNode.nextSibling;\n                    if (nextNode && isCharacterDataNode(nextNode)) {\n                        boundaryPosition = new DomPosition(nextNode, 0);\n                    } else if (previousNode && isCharacterDataNode(previousNode)) {\n                        boundaryPosition = new DomPosition(previousNode, previousNode.data.length);\n                    } else {\n                        boundaryPosition = new DomPosition(containerElement, dom.getNodeIndex(workingNode));\n                    }\n                }\n\n                // Clean up\n                workingNode.parentNode.removeChild(workingNode);\n\n                return {\n                    boundaryPosition: boundaryPosition,\n                    nodeInfo: {\n                        nodeIndex: nodeIndex,\n                        containerElement: containerElement\n                    }\n                };\n            };\n\n            // Returns a TextRange representing the boundary of a TextRange expressed as a node and an offset within that\n            // node. This function started out as an optimized version of code found in Tim Cameron Ryan's IERange\n            // (http://code.google.com/p/ierange/)\n            var createBoundaryTextRange = function(boundaryPosition, isStart) {\n                var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;\n                var doc = dom.getDocument(boundaryPosition.node);\n                var workingNode, childNodes, workingRange = getBody(doc).createTextRange();\n                var nodeIsDataNode = isCharacterDataNode(boundaryPosition.node);\n\n                if (nodeIsDataNode) {\n                    boundaryNode = boundaryPosition.node;\n                    boundaryParent = boundaryNode.parentNode;\n                } else {\n                    childNodes = boundaryPosition.node.childNodes;\n                    boundaryNode = (boundaryOffset < childNodes.length) ? childNodes[boundaryOffset] : null;\n                    boundaryParent = boundaryPosition.node;\n                }\n\n                // Position the range immediately before the node containing the boundary\n                workingNode = doc.createElement(\"span\");\n\n                // Making the working element non-empty element persuades IE to consider the TextRange boundary to be within\n                // the element rather than immediately before or after it\n                workingNode.innerHTML = \"&#feff;\";\n\n                // insertBefore is supposed to work like appendChild if the second parameter is null. However, a bug report\n                // for IERange suggests that it can crash the browser: http://code.google.com/p/ierange/issues/detail?id=12\n                if (boundaryNode) {\n                    boundaryParent.insertBefore(workingNode, boundaryNode);\n                } else {\n                    boundaryParent.appendChild(workingNode);\n                }\n\n                workingRange.moveToElementText(workingNode);\n                workingRange.collapse(!isStart);\n\n                // Clean up\n                boundaryParent.removeChild(workingNode);\n\n                // Move the working range to the text offset, if required\n                if (nodeIsDataNode) {\n                    workingRange[isStart ? \"moveStart\" : \"moveEnd\"](\"character\", boundaryOffset);\n                }\n\n                return workingRange;\n            };\n\n            /*------------------------------------------------------------------------------------------------------------*/\n\n            // This is a wrapper around a TextRange, providing full DOM Range functionality using rangy's DomRange as a\n            // prototype\n\n            WrappedTextRange = function(textRange) {\n                this.textRange = textRange;\n                this.refresh();\n            };\n\n            WrappedTextRange.prototype = new DomRange(document);\n\n            WrappedTextRange.prototype.refresh = function() {\n                var start, end, startBoundary;\n\n                // TextRange's parentElement() method cannot be trusted. getTextRangeContainerElement() works around that.\n                var rangeContainerElement = getTextRangeContainerElement(this.textRange);\n\n                if (textRangeIsCollapsed(this.textRange)) {\n                    end = start = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true,\n                        true).boundaryPosition;\n                } else {\n                    startBoundary = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true, false);\n                    start = startBoundary.boundaryPosition;\n\n                    // An optimization used here is that if the start and end boundaries have the same parent element, the\n                    // search scope for the end boundary can be limited to exclude the portion of the element that precedes\n                    // the start boundary\n                    end = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, false, false,\n                        startBoundary.nodeInfo).boundaryPosition;\n                }\n\n                this.setStart(start.node, start.offset);\n                this.setEnd(end.node, end.offset);\n            };\n\n            WrappedTextRange.prototype.getName = function() {\n                return \"WrappedTextRange\";\n            };\n\n            DomRange.copyComparisonConstants(WrappedTextRange);\n\n            var rangeToTextRange = function(range) {\n                if (range.collapsed) {\n                    return createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);\n                } else {\n                    var startRange = createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);\n                    var endRange = createBoundaryTextRange(new DomPosition(range.endContainer, range.endOffset), false);\n                    var textRange = getBody( DomRange.getRangeDocument(range) ).createTextRange();\n                    textRange.setEndPoint(\"StartToStart\", startRange);\n                    textRange.setEndPoint(\"EndToEnd\", endRange);\n                    return textRange;\n                }\n            };\n\n            WrappedTextRange.rangeToTextRange = rangeToTextRange;\n\n            WrappedTextRange.prototype.toTextRange = function() {\n                return rangeToTextRange(this);\n            };\n\n            api.WrappedTextRange = WrappedTextRange;\n\n            // IE 9 and above have both implementations and Rangy makes both available. The next few lines sets which\n            // implementation to use by default.\n            if (!api.features.implementsDomRange || api.config.preferTextRange) {\n                // Add WrappedTextRange as the Range property of the global object to allow expression like Range.END_TO_END to work\n                var globalObj = (function(f) { return f(\"return this;\")(); })(Function);\n                if (typeof globalObj.Range == \"undefined\") {\n                    globalObj.Range = WrappedTextRange;\n                }\n\n                api.createNativeRange = function(doc) {\n                    doc = getContentDocument(doc, module, \"createNativeRange\");\n                    return getBody(doc).createTextRange();\n                };\n\n                api.WrappedRange = WrappedTextRange;\n            }\n        }\n\n        api.createRange = function(doc) {\n            doc = getContentDocument(doc, module, \"createRange\");\n            return new api.WrappedRange(api.createNativeRange(doc));\n        };\n\n        api.createRangyRange = function(doc) {\n            doc = getContentDocument(doc, module, \"createRangyRange\");\n            return new DomRange(doc);\n        };\n\n        api.createIframeRange = function(iframeEl) {\n            module.deprecationNotice(\"createIframeRange()\", \"createRange(iframeEl)\");\n            return api.createRange(iframeEl);\n        };\n\n        api.createIframeRangyRange = function(iframeEl) {\n            module.deprecationNotice(\"createIframeRangyRange()\", \"createRangyRange(iframeEl)\");\n            return api.createRangyRange(iframeEl);\n        };\n\n        api.addShimListener(function(win) {\n            var doc = win.document;\n            if (typeof doc.createRange == \"undefined\") {\n                doc.createRange = function() {\n                    return api.createRange(doc);\n                };\n            }\n            doc = win = null;\n        });\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // This module creates a selection object wrapper that conforms as closely as possible to the Selection specification\n    // in the HTML Editing spec (http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections)\n    api.createCoreModule(\"WrappedSelection\", [\"DomRange\", \"WrappedRange\"], function(api, module) {\n        api.config.checkSelectionRanges = true;\n\n        var BOOLEAN = \"boolean\";\n        var NUMBER = \"number\";\n        var dom = api.dom;\n        var util = api.util;\n        var isHostMethod = util.isHostMethod;\n        var DomRange = api.DomRange;\n        var WrappedRange = api.WrappedRange;\n        var DOMException = api.DOMException;\n        var DomPosition = dom.DomPosition;\n        var getNativeSelection;\n        var selectionIsCollapsed;\n        var features = api.features;\n        var CONTROL = \"Control\";\n        var getDocument = dom.getDocument;\n        var getBody = dom.getBody;\n        var rangesEqual = DomRange.rangesEqual;\n\n\n        // Utility function to support direction parameters in the API that may be a string (\"backward\" or \"forward\") or a\n        // Boolean (true for backwards).\n        function isDirectionBackward(dir) {\n            return (typeof dir == \"string\") ? /^backward(s)?$/i.test(dir) : !!dir;\n        }\n\n        function getWindow(win, methodName) {\n            if (!win) {\n                return window;\n            } else if (dom.isWindow(win)) {\n                return win;\n            } else if (win instanceof WrappedSelection) {\n                return win.win;\n            } else {\n                var doc = dom.getContentDocument(win, module, methodName);\n                return dom.getWindow(doc);\n            }\n        }\n\n        function getWinSelection(winParam) {\n            return getWindow(winParam, \"getWinSelection\").getSelection();\n        }\n\n        function getDocSelection(winParam) {\n            return getWindow(winParam, \"getDocSelection\").document.selection;\n        }\n        \n        function winSelectionIsBackward(sel) {\n            var backward = false;\n            if (sel.anchorNode) {\n                backward = (dom.comparePoints(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset) == 1);\n            }\n            return backward;\n        }\n\n        // Test for the Range/TextRange and Selection features required\n        // Test for ability to retrieve selection\n        var implementsWinGetSelection = isHostMethod(window, \"getSelection\"),\n            implementsDocSelection = util.isHostObject(document, \"selection\");\n\n        features.implementsWinGetSelection = implementsWinGetSelection;\n        features.implementsDocSelection = implementsDocSelection;\n\n        var useDocumentSelection = implementsDocSelection && (!implementsWinGetSelection || api.config.preferTextRange);\n\n        if (useDocumentSelection) {\n            getNativeSelection = getDocSelection;\n            api.isSelectionValid = function(winParam) {\n                var doc = getWindow(winParam, \"isSelectionValid\").document, nativeSel = doc.selection;\n\n                // Check whether the selection TextRange is actually contained within the correct document\n                return (nativeSel.type != \"None\" || getDocument(nativeSel.createRange().parentElement()) == doc);\n            };\n        } else if (implementsWinGetSelection) {\n            getNativeSelection = getWinSelection;\n            api.isSelectionValid = function() {\n                return true;\n            };\n        } else {\n            module.fail(\"Neither document.selection or window.getSelection() detected.\");\n        }\n\n        api.getNativeSelection = getNativeSelection;\n\n        var testSelection = getNativeSelection();\n        var testRange = api.createNativeRange(document);\n        var body = getBody(document);\n\n        // Obtaining a range from a selection\n        var selectionHasAnchorAndFocus = util.areHostProperties(testSelection,\n            [\"anchorNode\", \"focusNode\", \"anchorOffset\", \"focusOffset\"]);\n\n        features.selectionHasAnchorAndFocus = selectionHasAnchorAndFocus;\n\n        // Test for existence of native selection extend() method\n        var selectionHasExtend = isHostMethod(testSelection, \"extend\");\n        features.selectionHasExtend = selectionHasExtend;\n        \n        // Test if rangeCount exists\n        var selectionHasRangeCount = (typeof testSelection.rangeCount == NUMBER);\n        features.selectionHasRangeCount = selectionHasRangeCount;\n\n        var selectionSupportsMultipleRanges = false;\n        var collapsedNonEditableSelectionsSupported = true;\n\n        var addRangeBackwardToNative = selectionHasExtend ?\n            function(nativeSelection, range) {\n                var doc = DomRange.getRangeDocument(range);\n                var endRange = api.createRange(doc);\n                endRange.collapseToPoint(range.endContainer, range.endOffset);\n                nativeSelection.addRange(getNativeRange(endRange));\n                nativeSelection.extend(range.startContainer, range.startOffset);\n            } : null;\n\n        if (util.areHostMethods(testSelection, [\"addRange\", \"getRangeAt\", \"removeAllRanges\"]) &&\n                typeof testSelection.rangeCount == NUMBER && features.implementsDomRange) {\n\n            (function() {\n                // Previously an iframe was used but this caused problems in some circumstances in IE, so tests are\n                // performed on the current document's selection. See issue 109.\n\n                // Note also that if a selection previously existed, it is wiped by these tests. This should usually be fine\n                // because initialization usually happens when the document loads, but could be a problem for a script that\n                // loads and initializes Rangy later. If anyone complains, code could be added to save and restore the\n                // selection.\n                var sel = window.getSelection();\n                if (sel) {\n                    // Store the current selection\n                    var originalSelectionRangeCount = sel.rangeCount;\n                    var selectionHasMultipleRanges = (originalSelectionRangeCount > 1);\n                    var originalSelectionRanges = [];\n                    var originalSelectionBackward = winSelectionIsBackward(sel); \n                    for (var i = 0; i < originalSelectionRangeCount; ++i) {\n                        originalSelectionRanges[i] = sel.getRangeAt(i);\n                    }\n                    \n                    // Create some test elements\n                    var body = getBody(document);\n                    var testEl = body.appendChild( document.createElement(\"div\") );\n                    testEl.contentEditable = \"false\";\n                    var textNode = testEl.appendChild( document.createTextNode(\"\\u00a0\\u00a0\\u00a0\") );\n\n                    // Test whether the native selection will allow a collapsed selection within a non-editable element\n                    var r1 = document.createRange();\n\n                    r1.setStart(textNode, 1);\n                    r1.collapse(true);\n                    sel.addRange(r1);\n                    collapsedNonEditableSelectionsSupported = (sel.rangeCount == 1);\n                    sel.removeAllRanges();\n\n                    // Test whether the native selection is capable of supporting multiple ranges.\n                    if (!selectionHasMultipleRanges) {\n                        // Doing the original feature test here in Chrome 36 (and presumably later versions) prints a\n                        // console error of \"Discontiguous selection is not supported.\" that cannot be suppressed. There's\n                        // nothing we can do about this while retaining the feature test so we have to resort to a browser\n                        // sniff. I'm not happy about it. See\n                        // https://code.google.com/p/chromium/issues/detail?id=399791\n                        var chromeMatch = window.navigator.appVersion.match(/Chrome\\/(.*?) /);\n                        if (chromeMatch && parseInt(chromeMatch[1]) >= 36) {\n                            selectionSupportsMultipleRanges = false;\n                        } else {\n                            var r2 = r1.cloneRange();\n                            r1.setStart(textNode, 0);\n                            r2.setEnd(textNode, 3);\n                            r2.setStart(textNode, 2);\n                            sel.addRange(r1);\n                            sel.addRange(r2);\n                            selectionSupportsMultipleRanges = (sel.rangeCount == 2);\n                        }\n                    }\n\n                    // Clean up\n                    body.removeChild(testEl);\n                    sel.removeAllRanges();\n\n                    for (i = 0; i < originalSelectionRangeCount; ++i) {\n                        if (i == 0 && originalSelectionBackward) {\n                            if (addRangeBackwardToNative) {\n                                addRangeBackwardToNative(sel, originalSelectionRanges[i]);\n                            } else {\n                                api.warn(\"Rangy initialization: original selection was backwards but selection has been restored forwards because the browser does not support Selection.extend\");\n                                sel.addRange(originalSelectionRanges[i]);\n                            }\n                        } else {\n                            sel.addRange(originalSelectionRanges[i]);\n                        }\n                    }\n                }\n            })();\n        }\n\n        features.selectionSupportsMultipleRanges = selectionSupportsMultipleRanges;\n        features.collapsedNonEditableSelectionsSupported = collapsedNonEditableSelectionsSupported;\n\n        // ControlRanges\n        var implementsControlRange = false, testControlRange;\n\n        if (body && isHostMethod(body, \"createControlRange\")) {\n            testControlRange = body.createControlRange();\n            if (util.areHostProperties(testControlRange, [\"item\", \"add\"])) {\n                implementsControlRange = true;\n            }\n        }\n        features.implementsControlRange = implementsControlRange;\n\n        // Selection collapsedness\n        if (selectionHasAnchorAndFocus) {\n            selectionIsCollapsed = function(sel) {\n                return sel.anchorNode === sel.focusNode && sel.anchorOffset === sel.focusOffset;\n            };\n        } else {\n            selectionIsCollapsed = function(sel) {\n                return sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1).collapsed : false;\n            };\n        }\n\n        function updateAnchorAndFocusFromRange(sel, range, backward) {\n            var anchorPrefix = backward ? \"end\" : \"start\", focusPrefix = backward ? \"start\" : \"end\";\n            sel.anchorNode = range[anchorPrefix + \"Container\"];\n            sel.anchorOffset = range[anchorPrefix + \"Offset\"];\n            sel.focusNode = range[focusPrefix + \"Container\"];\n            sel.focusOffset = range[focusPrefix + \"Offset\"];\n        }\n\n        function updateAnchorAndFocusFromNativeSelection(sel) {\n            var nativeSel = sel.nativeSelection;\n            sel.anchorNode = nativeSel.anchorNode;\n            sel.anchorOffset = nativeSel.anchorOffset;\n            sel.focusNode = nativeSel.focusNode;\n            sel.focusOffset = nativeSel.focusOffset;\n        }\n\n        function updateEmptySelection(sel) {\n            sel.anchorNode = sel.focusNode = null;\n            sel.anchorOffset = sel.focusOffset = 0;\n            sel.rangeCount = 0;\n            sel.isCollapsed = true;\n            sel._ranges.length = 0;\n        }\n\n        function getNativeRange(range) {\n            var nativeRange;\n            if (range instanceof DomRange) {\n                nativeRange = api.createNativeRange(range.getDocument());\n                nativeRange.setEnd(range.endContainer, range.endOffset);\n                nativeRange.setStart(range.startContainer, range.startOffset);\n            } else if (range instanceof WrappedRange) {\n                nativeRange = range.nativeRange;\n            } else if (features.implementsDomRange && (range instanceof dom.getWindow(range.startContainer).Range)) {\n                nativeRange = range;\n            }\n            return nativeRange;\n        }\n\n        function rangeContainsSingleElement(rangeNodes) {\n            if (!rangeNodes.length || rangeNodes[0].nodeType != 1) {\n                return false;\n            }\n            for (var i = 1, len = rangeNodes.length; i < len; ++i) {\n                if (!dom.isAncestorOf(rangeNodes[0], rangeNodes[i])) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        function getSingleElementFromRange(range) {\n            var nodes = range.getNodes();\n            if (!rangeContainsSingleElement(nodes)) {\n                throw module.createError(\"getSingleElementFromRange: range \" + range.inspect() + \" did not consist of a single element\");\n            }\n            return nodes[0];\n        }\n\n        // Simple, quick test which only needs to distinguish between a TextRange and a ControlRange\n        function isTextRange(range) {\n            return !!range && typeof range.text != \"undefined\";\n        }\n\n        function updateFromTextRange(sel, range) {\n            // Create a Range from the selected TextRange\n            var wrappedRange = new WrappedRange(range);\n            sel._ranges = [wrappedRange];\n\n            updateAnchorAndFocusFromRange(sel, wrappedRange, false);\n            sel.rangeCount = 1;\n            sel.isCollapsed = wrappedRange.collapsed;\n        }\n\n        function updateControlSelection(sel) {\n            // Update the wrapped selection based on what's now in the native selection\n            sel._ranges.length = 0;\n            if (sel.docSelection.type == \"None\") {\n                updateEmptySelection(sel);\n            } else {\n                var controlRange = sel.docSelection.createRange();\n                if (isTextRange(controlRange)) {\n                    // This case (where the selection type is \"Control\" and calling createRange() on the selection returns\n                    // a TextRange) can happen in IE 9. It happens, for example, when all elements in the selected\n                    // ControlRange have been removed from the ControlRange and removed from the document.\n                    updateFromTextRange(sel, controlRange);\n                } else {\n                    sel.rangeCount = controlRange.length;\n                    var range, doc = getDocument(controlRange.item(0));\n                    for (var i = 0; i < sel.rangeCount; ++i) {\n                        range = api.createRange(doc);\n                        range.selectNode(controlRange.item(i));\n                        sel._ranges.push(range);\n                    }\n                    sel.isCollapsed = sel.rangeCount == 1 && sel._ranges[0].collapsed;\n                    updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], false);\n                }\n            }\n        }\n\n        function addRangeToControlSelection(sel, range) {\n            var controlRange = sel.docSelection.createRange();\n            var rangeElement = getSingleElementFromRange(range);\n\n            // Create a new ControlRange containing all the elements in the selected ControlRange plus the element\n            // contained by the supplied range\n            var doc = getDocument(controlRange.item(0));\n            var newControlRange = getBody(doc).createControlRange();\n            for (var i = 0, len = controlRange.length; i < len; ++i) {\n                newControlRange.add(controlRange.item(i));\n            }\n            try {\n                newControlRange.add(rangeElement);\n            } catch (ex) {\n                throw module.createError(\"addRange(): Element within the specified Range could not be added to control selection (does it have layout?)\");\n            }\n            newControlRange.select();\n\n            // Update the wrapped selection based on what's now in the native selection\n            updateControlSelection(sel);\n        }\n\n        var getSelectionRangeAt;\n\n        if (isHostMethod(testSelection, \"getRangeAt\")) {\n            // try/catch is present because getRangeAt() must have thrown an error in some browser and some situation.\n            // Unfortunately, I didn't write a comment about the specifics and am now scared to take it out. Let that be a\n            // lesson to us all, especially me.\n            getSelectionRangeAt = function(sel, index) {\n                try {\n                    return sel.getRangeAt(index);\n                } catch (ex) {\n                    return null;\n                }\n            };\n        } else if (selectionHasAnchorAndFocus) {\n            getSelectionRangeAt = function(sel) {\n                var doc = getDocument(sel.anchorNode);\n                var range = api.createRange(doc);\n                range.setStartAndEnd(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);\n\n                // Handle the case when the selection was selected backwards (from the end to the start in the\n                // document)\n                if (range.collapsed !== this.isCollapsed) {\n                    range.setStartAndEnd(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset);\n                }\n\n                return range;\n            };\n        }\n\n        function WrappedSelection(selection, docSelection, win) {\n            this.nativeSelection = selection;\n            this.docSelection = docSelection;\n            this._ranges = [];\n            this.win = win;\n            this.refresh();\n        }\n\n        WrappedSelection.prototype = api.selectionPrototype;\n\n        function deleteProperties(sel) {\n            sel.win = sel.anchorNode = sel.focusNode = sel._ranges = null;\n            sel.rangeCount = sel.anchorOffset = sel.focusOffset = 0;\n            sel.detached = true;\n        }\n\n        var cachedRangySelections = [];\n\n        function actOnCachedSelection(win, action) {\n            var i = cachedRangySelections.length, cached, sel;\n            while (i--) {\n                cached = cachedRangySelections[i];\n                sel = cached.selection;\n                if (action == \"deleteAll\") {\n                    deleteProperties(sel);\n                } else if (cached.win == win) {\n                    if (action == \"delete\") {\n                        cachedRangySelections.splice(i, 1);\n                        return true;\n                    } else {\n                        return sel;\n                    }\n                }\n            }\n            if (action == \"deleteAll\") {\n                cachedRangySelections.length = 0;\n            }\n            return null;\n        }\n\n        var getSelection = function(win) {\n            // Check if the parameter is a Rangy Selection object\n            if (win && win instanceof WrappedSelection) {\n                win.refresh();\n                return win;\n            }\n\n            win = getWindow(win, \"getNativeSelection\");\n\n            var sel = actOnCachedSelection(win);\n            var nativeSel = getNativeSelection(win), docSel = implementsDocSelection ? getDocSelection(win) : null;\n            if (sel) {\n                sel.nativeSelection = nativeSel;\n                sel.docSelection = docSel;\n                sel.refresh();\n            } else {\n                sel = new WrappedSelection(nativeSel, docSel, win);\n                cachedRangySelections.push( { win: win, selection: sel } );\n            }\n            return sel;\n        };\n\n        api.getSelection = getSelection;\n\n        api.getIframeSelection = function(iframeEl) {\n            module.deprecationNotice(\"getIframeSelection()\", \"getSelection(iframeEl)\");\n            return api.getSelection(dom.getIframeWindow(iframeEl));\n        };\n\n        var selProto = WrappedSelection.prototype;\n\n        function createControlSelection(sel, ranges) {\n            // Ensure that the selection becomes of type \"Control\"\n            var doc = getDocument(ranges[0].startContainer);\n            var controlRange = getBody(doc).createControlRange();\n            for (var i = 0, el, len = ranges.length; i < len; ++i) {\n                el = getSingleElementFromRange(ranges[i]);\n                try {\n                    controlRange.add(el);\n                } catch (ex) {\n                    throw module.createError(\"setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)\");\n                }\n            }\n            controlRange.select();\n\n            // Update the wrapped selection based on what's now in the native selection\n            updateControlSelection(sel);\n        }\n\n        // Selecting a range\n        if (!useDocumentSelection && selectionHasAnchorAndFocus && util.areHostMethods(testSelection, [\"removeAllRanges\", \"addRange\"])) {\n            selProto.removeAllRanges = function() {\n                this.nativeSelection.removeAllRanges();\n                updateEmptySelection(this);\n            };\n\n            var addRangeBackward = function(sel, range) {\n                addRangeBackwardToNative(sel.nativeSelection, range);\n                sel.refresh();\n            };\n\n            if (selectionHasRangeCount) {\n                selProto.addRange = function(range, direction) {\n                    if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {\n                        addRangeToControlSelection(this, range);\n                    } else {\n                        if (isDirectionBackward(direction) && selectionHasExtend) {\n                            addRangeBackward(this, range);\n                        } else {\n                            var previousRangeCount;\n                            if (selectionSupportsMultipleRanges) {\n                                previousRangeCount = this.rangeCount;\n                            } else {\n                                this.removeAllRanges();\n                                previousRangeCount = 0;\n                            }\n                            // Clone the native range so that changing the selected range does not affect the selection.\n                            // This is contrary to the spec but is the only way to achieve consistency between browsers. See\n                            // issue 80.\n                            var clonedNativeRange = getNativeRange(range).cloneRange();\n                            try {\n                                this.nativeSelection.addRange(clonedNativeRange);\n                            } catch (ex) {\n                            }\n\n                            // Check whether adding the range was successful\n                            this.rangeCount = this.nativeSelection.rangeCount;\n\n                            if (this.rangeCount == previousRangeCount + 1) {\n                                // The range was added successfully\n\n                                // Check whether the range that we added to the selection is reflected in the last range extracted from\n                                // the selection\n                                if (api.config.checkSelectionRanges) {\n                                    var nativeRange = getSelectionRangeAt(this.nativeSelection, this.rangeCount - 1);\n                                    if (nativeRange && !rangesEqual(nativeRange, range)) {\n                                        // Happens in WebKit with, for example, a selection placed at the start of a text node\n                                        range = new WrappedRange(nativeRange);\n                                    }\n                                }\n                                this._ranges[this.rangeCount - 1] = range;\n                                updateAnchorAndFocusFromRange(this, range, selectionIsBackward(this.nativeSelection));\n                                this.isCollapsed = selectionIsCollapsed(this);\n                            } else {\n                                // The range was not added successfully. The simplest thing is to refresh\n                                this.refresh();\n                            }\n                        }\n                    }\n                };\n            } else {\n                selProto.addRange = function(range, direction) {\n                    if (isDirectionBackward(direction) && selectionHasExtend) {\n                        addRangeBackward(this, range);\n                    } else {\n                        this.nativeSelection.addRange(getNativeRange(range));\n                        this.refresh();\n                    }\n                };\n            }\n\n            selProto.setRanges = function(ranges) {\n                if (implementsControlRange && implementsDocSelection && ranges.length > 1) {\n                    createControlSelection(this, ranges);\n                } else {\n                    this.removeAllRanges();\n                    for (var i = 0, len = ranges.length; i < len; ++i) {\n                        this.addRange(ranges[i]);\n                    }\n                }\n            };\n        } else if (isHostMethod(testSelection, \"empty\") && isHostMethod(testRange, \"select\") &&\n                   implementsControlRange && useDocumentSelection) {\n\n            selProto.removeAllRanges = function() {\n                // Added try/catch as fix for issue #21\n                try {\n                    this.docSelection.empty();\n\n                    // Check for empty() not working (issue #24)\n                    if (this.docSelection.type != \"None\") {\n                        // Work around failure to empty a control selection by instead selecting a TextRange and then\n                        // calling empty()\n                        var doc;\n                        if (this.anchorNode) {\n                            doc = getDocument(this.anchorNode);\n                        } else if (this.docSelection.type == CONTROL) {\n                            var controlRange = this.docSelection.createRange();\n                            if (controlRange.length) {\n                                doc = getDocument( controlRange.item(0) );\n                            }\n                        }\n                        if (doc) {\n                            var textRange = getBody(doc).createTextRange();\n                            textRange.select();\n                            this.docSelection.empty();\n                        }\n                    }\n                } catch(ex) {}\n                updateEmptySelection(this);\n            };\n\n            selProto.addRange = function(range) {\n                if (this.docSelection.type == CONTROL) {\n                    addRangeToControlSelection(this, range);\n                } else {\n                    api.WrappedTextRange.rangeToTextRange(range).select();\n                    this._ranges[0] = range;\n                    this.rangeCount = 1;\n                    this.isCollapsed = this._ranges[0].collapsed;\n                    updateAnchorAndFocusFromRange(this, range, false);\n                }\n            };\n\n            selProto.setRanges = function(ranges) {\n                this.removeAllRanges();\n                var rangeCount = ranges.length;\n                if (rangeCount > 1) {\n                    createControlSelection(this, ranges);\n                } else if (rangeCount) {\n                    this.addRange(ranges[0]);\n                }\n            };\n        } else {\n            module.fail(\"No means of selecting a Range or TextRange was found\");\n            return false;\n        }\n\n        selProto.getRangeAt = function(index) {\n            if (index < 0 || index >= this.rangeCount) {\n                throw new DOMException(\"INDEX_SIZE_ERR\");\n            } else {\n                // Clone the range to preserve selection-range independence. See issue 80.\n                return this._ranges[index].cloneRange();\n            }\n        };\n\n        var refreshSelection;\n\n        if (useDocumentSelection) {\n            refreshSelection = function(sel) {\n                var range;\n                if (api.isSelectionValid(sel.win)) {\n                    range = sel.docSelection.createRange();\n                } else {\n                    range = getBody(sel.win.document).createTextRange();\n                    range.collapse(true);\n                }\n\n                if (sel.docSelection.type == CONTROL) {\n                    updateControlSelection(sel);\n                } else if (isTextRange(range)) {\n                    updateFromTextRange(sel, range);\n                } else {\n                    updateEmptySelection(sel);\n                }\n            };\n        } else if (isHostMethod(testSelection, \"getRangeAt\") && typeof testSelection.rangeCount == NUMBER) {\n            refreshSelection = function(sel) {\n                if (implementsControlRange && implementsDocSelection && sel.docSelection.type == CONTROL) {\n                    updateControlSelection(sel);\n                } else {\n                    sel._ranges.length = sel.rangeCount = sel.nativeSelection.rangeCount;\n                    if (sel.rangeCount) {\n                        for (var i = 0, len = sel.rangeCount; i < len; ++i) {\n                            sel._ranges[i] = new api.WrappedRange(sel.nativeSelection.getRangeAt(i));\n                        }\n                        updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], selectionIsBackward(sel.nativeSelection));\n                        sel.isCollapsed = selectionIsCollapsed(sel);\n                    } else {\n                        updateEmptySelection(sel);\n                    }\n                }\n            };\n        } else if (selectionHasAnchorAndFocus && typeof testSelection.isCollapsed == BOOLEAN && typeof testRange.collapsed == BOOLEAN && features.implementsDomRange) {\n            refreshSelection = function(sel) {\n                var range, nativeSel = sel.nativeSelection;\n                if (nativeSel.anchorNode) {\n                    range = getSelectionRangeAt(nativeSel, 0);\n                    sel._ranges = [range];\n                    sel.rangeCount = 1;\n                    updateAnchorAndFocusFromNativeSelection(sel);\n                    sel.isCollapsed = selectionIsCollapsed(sel);\n                } else {\n                    updateEmptySelection(sel);\n                }\n            };\n        } else {\n            module.fail(\"No means of obtaining a Range or TextRange from the user's selection was found\");\n            return false;\n        }\n\n        selProto.refresh = function(checkForChanges) {\n            var oldRanges = checkForChanges ? this._ranges.slice(0) : null;\n            var oldAnchorNode = this.anchorNode, oldAnchorOffset = this.anchorOffset;\n\n            refreshSelection(this);\n            if (checkForChanges) {\n                // Check the range count first\n                var i = oldRanges.length;\n                if (i != this._ranges.length) {\n                    return true;\n                }\n\n                // Now check the direction. Checking the anchor position is the same is enough since we're checking all the\n                // ranges after this\n                if (this.anchorNode != oldAnchorNode || this.anchorOffset != oldAnchorOffset) {\n                    return true;\n                }\n\n                // Finally, compare each range in turn\n                while (i--) {\n                    if (!rangesEqual(oldRanges[i], this._ranges[i])) {\n                        return true;\n                    }\n                }\n                return false;\n            }\n        };\n\n        // Removal of a single range\n        var removeRangeManually = function(sel, range) {\n            var ranges = sel.getAllRanges();\n            sel.removeAllRanges();\n            for (var i = 0, len = ranges.length; i < len; ++i) {\n                if (!rangesEqual(range, ranges[i])) {\n                    sel.addRange(ranges[i]);\n                }\n            }\n            if (!sel.rangeCount) {\n                updateEmptySelection(sel);\n            }\n        };\n\n        if (implementsControlRange && implementsDocSelection) {\n            selProto.removeRange = function(range) {\n                if (this.docSelection.type == CONTROL) {\n                    var controlRange = this.docSelection.createRange();\n                    var rangeElement = getSingleElementFromRange(range);\n\n                    // Create a new ControlRange containing all the elements in the selected ControlRange minus the\n                    // element contained by the supplied range\n                    var doc = getDocument(controlRange.item(0));\n                    var newControlRange = getBody(doc).createControlRange();\n                    var el, removed = false;\n                    for (var i = 0, len = controlRange.length; i < len; ++i) {\n                        el = controlRange.item(i);\n                        if (el !== rangeElement || removed) {\n                            newControlRange.add(controlRange.item(i));\n                        } else {\n                            removed = true;\n                        }\n                    }\n                    newControlRange.select();\n\n                    // Update the wrapped selection based on what's now in the native selection\n                    updateControlSelection(this);\n                } else {\n                    removeRangeManually(this, range);\n                }\n            };\n        } else {\n            selProto.removeRange = function(range) {\n                removeRangeManually(this, range);\n            };\n        }\n\n        // Detecting if a selection is backward\n        var selectionIsBackward;\n        if (!useDocumentSelection && selectionHasAnchorAndFocus && features.implementsDomRange) {\n            selectionIsBackward = winSelectionIsBackward;\n\n            selProto.isBackward = function() {\n                return selectionIsBackward(this);\n            };\n        } else {\n            selectionIsBackward = selProto.isBackward = function() {\n                return false;\n            };\n        }\n\n        // Create an alias for backwards compatibility. From 1.3, everything is \"backward\" rather than \"backwards\"\n        selProto.isBackwards = selProto.isBackward;\n\n        // Selection stringifier\n        // This is conformant to the old HTML5 selections draft spec but differs from WebKit and Mozilla's implementation.\n        // The current spec does not yet define this method.\n        selProto.toString = function() {\n            var rangeTexts = [];\n            for (var i = 0, len = this.rangeCount; i < len; ++i) {\n                rangeTexts[i] = \"\" + this._ranges[i];\n            }\n            return rangeTexts.join(\"\");\n        };\n\n        function assertNodeInSameDocument(sel, node) {\n            if (sel.win.document != getDocument(node)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n        }\n\n        // No current browser conforms fully to the spec for this method, so Rangy's own method is always used\n        selProto.collapse = function(node, offset) {\n            assertNodeInSameDocument(this, node);\n            var range = api.createRange(node);\n            range.collapseToPoint(node, offset);\n            this.setSingleRange(range);\n            this.isCollapsed = true;\n        };\n\n        selProto.collapseToStart = function() {\n            if (this.rangeCount) {\n                var range = this._ranges[0];\n                this.collapse(range.startContainer, range.startOffset);\n            } else {\n                throw new DOMException(\"INVALID_STATE_ERR\");\n            }\n        };\n\n        selProto.collapseToEnd = function() {\n            if (this.rangeCount) {\n                var range = this._ranges[this.rangeCount - 1];\n                this.collapse(range.endContainer, range.endOffset);\n            } else {\n                throw new DOMException(\"INVALID_STATE_ERR\");\n            }\n        };\n\n        // The spec is very specific on how selectAllChildren should be implemented so the native implementation is\n        // never used by Rangy.\n        selProto.selectAllChildren = function(node) {\n            assertNodeInSameDocument(this, node);\n            var range = api.createRange(node);\n            range.selectNodeContents(node);\n            this.setSingleRange(range);\n        };\n\n        selProto.deleteFromDocument = function() {\n            // Sepcial behaviour required for IE's control selections\n            if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {\n                var controlRange = this.docSelection.createRange();\n                var element;\n                while (controlRange.length) {\n                    element = controlRange.item(0);\n                    controlRange.remove(element);\n                    element.parentNode.removeChild(element);\n                }\n                this.refresh();\n            } else if (this.rangeCount) {\n                var ranges = this.getAllRanges();\n                if (ranges.length) {\n                    this.removeAllRanges();\n                    for (var i = 0, len = ranges.length; i < len; ++i) {\n                        ranges[i].deleteContents();\n                    }\n                    // The spec says nothing about what the selection should contain after calling deleteContents on each\n                    // range. Firefox moves the selection to where the final selected range was, so we emulate that\n                    this.addRange(ranges[len - 1]);\n                }\n            }\n        };\n\n        // The following are non-standard extensions\n        selProto.eachRange = function(func, returnValue) {\n            for (var i = 0, len = this._ranges.length; i < len; ++i) {\n                if ( func( this.getRangeAt(i) ) ) {\n                    return returnValue;\n                }\n            }\n        };\n\n        selProto.getAllRanges = function() {\n            var ranges = [];\n            this.eachRange(function(range) {\n                ranges.push(range);\n            });\n            return ranges;\n        };\n\n        selProto.setSingleRange = function(range, direction) {\n            this.removeAllRanges();\n            this.addRange(range, direction);\n        };\n\n        selProto.callMethodOnEachRange = function(methodName, params) {\n            var results = [];\n            this.eachRange( function(range) {\n                results.push( range[methodName].apply(range, params) );\n            } );\n            return results;\n        };\n        \n        function createStartOrEndSetter(isStart) {\n            return function(node, offset) {\n                var range;\n                if (this.rangeCount) {\n                    range = this.getRangeAt(0);\n                    range[\"set\" + (isStart ? \"Start\" : \"End\")](node, offset);\n                } else {\n                    range = api.createRange(this.win.document);\n                    range.setStartAndEnd(node, offset);\n                }\n                this.setSingleRange(range, this.isBackward());\n            };\n        }\n\n        selProto.setStart = createStartOrEndSetter(true);\n        selProto.setEnd = createStartOrEndSetter(false);\n        \n        // Add select() method to Range prototype. Any existing selection will be removed.\n        api.rangePrototype.select = function(direction) {\n            getSelection( this.getDocument() ).setSingleRange(this, direction);\n        };\n\n        selProto.changeEachRange = function(func) {\n            var ranges = [];\n            var backward = this.isBackward();\n\n            this.eachRange(function(range) {\n                func(range);\n                ranges.push(range);\n            });\n\n            this.removeAllRanges();\n            if (backward && ranges.length == 1) {\n                this.addRange(ranges[0], \"backward\");\n            } else {\n                this.setRanges(ranges);\n            }\n        };\n\n        selProto.containsNode = function(node, allowPartial) {\n            return this.eachRange( function(range) {\n                return range.containsNode(node, allowPartial);\n            }, true ) || false;\n        };\n\n        selProto.getBookmark = function(containerNode) {\n            return {\n                backward: this.isBackward(),\n                rangeBookmarks: this.callMethodOnEachRange(\"getBookmark\", [containerNode])\n            };\n        };\n\n        selProto.moveToBookmark = function(bookmark) {\n            var selRanges = [];\n            for (var i = 0, rangeBookmark, range; rangeBookmark = bookmark.rangeBookmarks[i++]; ) {\n                range = api.createRange(this.win);\n                range.moveToBookmark(rangeBookmark);\n                selRanges.push(range);\n            }\n            if (bookmark.backward) {\n                this.setSingleRange(selRanges[0], \"backward\");\n            } else {\n                this.setRanges(selRanges);\n            }\n        };\n\n        selProto.toHtml = function() {\n            var rangeHtmls = [];\n            this.eachRange(function(range) {\n                rangeHtmls.push( DomRange.toHtml(range) );\n            });\n            return rangeHtmls.join(\"\");\n        };\n\n        if (features.implementsTextRange) {\n            selProto.getNativeTextRange = function() {\n                var sel, textRange;\n                if ( (sel = this.docSelection) ) {\n                    var range = sel.createRange();\n                    if (isTextRange(range)) {\n                        return range;\n                    } else {\n                        throw module.createError(\"getNativeTextRange: selection is a control selection\"); \n                    }\n                } else if (this.rangeCount > 0) {\n                    return api.WrappedTextRange.rangeToTextRange( this.getRangeAt(0) );\n                } else {\n                    throw module.createError(\"getNativeTextRange: selection contains no range\");\n                }\n            };\n        }\n\n        function inspect(sel) {\n            var rangeInspects = [];\n            var anchor = new DomPosition(sel.anchorNode, sel.anchorOffset);\n            var focus = new DomPosition(sel.focusNode, sel.focusOffset);\n            var name = (typeof sel.getName == \"function\") ? sel.getName() : \"Selection\";\n\n            if (typeof sel.rangeCount != \"undefined\") {\n                for (var i = 0, len = sel.rangeCount; i < len; ++i) {\n                    rangeInspects[i] = DomRange.inspect(sel.getRangeAt(i));\n                }\n            }\n            return \"[\" + name + \"(Ranges: \" + rangeInspects.join(\", \") +\n                    \")(anchor: \" + anchor.inspect() + \", focus: \" + focus.inspect() + \"]\";\n        }\n\n        selProto.getName = function() {\n            return \"WrappedSelection\";\n        };\n\n        selProto.inspect = function() {\n            return inspect(this);\n        };\n\n        selProto.detach = function() {\n            actOnCachedSelection(this.win, \"delete\");\n            deleteProperties(this);\n        };\n\n        WrappedSelection.detachAll = function() {\n            actOnCachedSelection(null, \"deleteAll\");\n        };\n\n        WrappedSelection.inspect = inspect;\n        WrappedSelection.isDirectionBackward = isDirectionBackward;\n\n        api.Selection = WrappedSelection;\n\n        api.selectionPrototype = selProto;\n\n        api.addShimListener(function(win) {\n            if (typeof win.getSelection == \"undefined\") {\n                win.getSelection = function() {\n                    return getSelection(win);\n                };\n            }\n            win = null;\n        });\n    });\n    \n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Wait for document to load before initializing\n    var docReady = false;\n\n    var loadHandler = function(e) {\n        if (!docReady) {\n            docReady = true;\n            if (!api.initialized && api.config.autoInitialize) {\n                init();\n            }\n        }\n    };\n\n    if (isBrowser) {\n        // Test whether the document has already been loaded and initialize immediately if so\n        if (/^(?:complete|interactive)$/.test(document.readyState)) {\n            loadHandler();\n        } else {\n            if (isHostMethod(document, \"addEventListener\")) {\n                document.addEventListener(\"DOMContentLoaded\", loadHandler, false);\n            }\n\n            // Add a fallback in case the DOMContentLoaded event isn't supported\n            addListener(window, \"load\", loadHandler);\n        }\n    }\n\n    return api;\n}, /* build:replaceWithGlobalObject */this/* build:replaceWithGlobalObjectEnd */);\n/**\n * Class Applier module for Rangy.\n * Adds, removes and toggles classes on Ranges and Selections\n *\n * Part of Rangy, a cross-browser JavaScript range and selection library\n * http://code.google.com/p/rangy/\n *\n * Depends on Rangy core.\n *\n * Copyright 2014, Tim Down\n * Licensed under the MIT license.\n * Version: 1.3.0-alpha.20140827\n * Build date: 27 August 2014\n */\n(function(factory, root) {\n    if (typeof define == \"function\" && define.amd) {\n        // AMD. Register as an anonymous module with a dependency on Rangy.\n        define([\"./rangy-core\"], factory);\n    } else if (typeof module != \"undefined\" && typeof exports == \"object\") {\n        // Node/CommonJS style\n        module.exports = factory( require(\"rangy\") );\n    } else {\n        // No AMD or CommonJS support so we use the rangy property of root (probably the global variable)\n        factory(root.rangy);\n    }\n})(function(rangy) {\n    rangy.createModule(\"ClassApplier\", [\"WrappedSelection\"], function(api, module) {\n        var dom = api.dom;\n        var DomPosition = dom.DomPosition;\n        var contains = dom.arrayContains;\n        var isHtmlNamespace = dom.isHtmlNamespace;\n\n\n        var defaultTagName = \"span\";\n\n        function each(obj, func) {\n            for (var i in obj) {\n                if (obj.hasOwnProperty(i)) {\n                    if (func(i, obj[i]) === false) {\n                        return false;\n                    }\n                }\n            }\n            return true;\n        }\n        \n        function trim(str) {\n            return str.replace(/^\\s\\s*/, \"\").replace(/\\s\\s*$/, \"\");\n        }\n\n        function hasClass(el, className) {\n            return el.className && new RegExp(\"(?:^|\\\\s)\" + className + \"(?:\\\\s|$)\").test(el.className);\n        }\n\n        function addClass(el, className) {\n            if (el.className) {\n                if (!hasClass(el, className)) {\n                    el.className += \" \" + className;\n                }\n            } else {\n                el.className = className;\n            }\n        }\n\n        var removeClass = (function() {\n            function replacer(matched, whiteSpaceBefore, whiteSpaceAfter) {\n                return (whiteSpaceBefore && whiteSpaceAfter) ? \" \" : \"\";\n            }\n\n            return function(el, className) {\n                if (el.className) {\n                    el.className = el.className.replace(new RegExp(\"(^|\\\\s)\" + className + \"(\\\\s|$)\"), replacer);\n                }\n            };\n        })();\n\n        function sortClassName(className) {\n            return className && className.split(/\\s+/).sort().join(\" \");\n        }\n\n        function getSortedClassName(el) {\n            return sortClassName(el.className);\n        }\n\n        function haveSameClasses(el1, el2) {\n            return getSortedClassName(el1) == getSortedClassName(el2);\n        }\n\n        function movePosition(position, oldParent, oldIndex, newParent, newIndex) {\n            var posNode = position.node, posOffset = position.offset;\n            var newNode = posNode, newOffset = posOffset;\n\n            if (posNode == newParent && posOffset > newIndex) {\n                ++newOffset;\n            }\n\n            if (posNode == oldParent && (posOffset == oldIndex  || posOffset == oldIndex + 1)) {\n                newNode = newParent;\n                newOffset += newIndex - oldIndex;\n            }\n\n            if (posNode == oldParent && posOffset > oldIndex + 1) {\n                --newOffset;\n            }\n\n            position.node = newNode;\n            position.offset = newOffset;\n        }\n        \n        function movePositionWhenRemovingNode(position, parentNode, index) {\n            if (position.node == parentNode && position.offset > index) {\n                --position.offset;\n            }\n        }\n\n        function movePreservingPositions(node, newParent, newIndex, positionsToPreserve) {\n            // For convenience, allow newIndex to be -1 to mean \"insert at the end\".\n            if (newIndex == -1) {\n                newIndex = newParent.childNodes.length;\n            }\n\n            var oldParent = node.parentNode;\n            var oldIndex = dom.getNodeIndex(node);\n\n            for (var i = 0, position; position = positionsToPreserve[i++]; ) {\n                movePosition(position, oldParent, oldIndex, newParent, newIndex);\n            }\n\n            // Now actually move the node.\n            if (newParent.childNodes.length == newIndex) {\n                newParent.appendChild(node);\n            } else {\n                newParent.insertBefore(node, newParent.childNodes[newIndex]);\n            }\n        }\n        \n        function removePreservingPositions(node, positionsToPreserve) {\n\n            var oldParent = node.parentNode;\n            var oldIndex = dom.getNodeIndex(node);\n\n            for (var i = 0, position; position = positionsToPreserve[i++]; ) {\n                movePositionWhenRemovingNode(position, oldParent, oldIndex);\n            }\n\n            node.parentNode.removeChild(node);\n        }\n\n        function moveChildrenPreservingPositions(node, newParent, newIndex, removeNode, positionsToPreserve) {\n            var child, children = [];\n            while ( (child = node.firstChild) ) {\n                movePreservingPositions(child, newParent, newIndex++, positionsToPreserve);\n                children.push(child);\n            }\n            if (removeNode) {\n                removePreservingPositions(node, positionsToPreserve);\n            }\n            return children;\n        }\n\n        function replaceWithOwnChildrenPreservingPositions(element, positionsToPreserve) {\n            return moveChildrenPreservingPositions(element, element.parentNode, dom.getNodeIndex(element), true, positionsToPreserve);\n        }\n\n        function rangeSelectsAnyText(range, textNode) {\n            var textNodeRange = range.cloneRange();\n            textNodeRange.selectNodeContents(textNode);\n\n            var intersectionRange = textNodeRange.intersection(range);\n            var text = intersectionRange ? intersectionRange.toString() : \"\";\n\n            return text != \"\";\n        }\n\n        function getEffectiveTextNodes(range) {\n            var nodes = range.getNodes([3]);\n            \n            // Optimization as per issue 145\n            \n            // Remove non-intersecting text nodes from the start of the range\n            var start = 0, node;\n            while ( (node = nodes[start]) && !rangeSelectsAnyText(range, node) ) {\n                ++start;\n            }\n\n            // Remove non-intersecting text nodes from the start of the range\n            var end = nodes.length - 1;\n            while ( (node = nodes[end]) && !rangeSelectsAnyText(range, node) ) {\n                --end;\n            }\n            \n            return nodes.slice(start, end + 1);\n        }\n\n        function elementsHaveSameNonClassAttributes(el1, el2) {\n            if (el1.attributes.length != el2.attributes.length) return false;\n            for (var i = 0, len = el1.attributes.length, attr1, attr2, name; i < len; ++i) {\n                attr1 = el1.attributes[i];\n                name = attr1.name;\n                if (name != \"class\") {\n                    attr2 = el2.attributes.getNamedItem(name);\n                    if ( (attr1 === null) != (attr2 === null) ) return false;\n                    if (attr1.specified != attr2.specified) return false;\n                    if (attr1.specified && attr1.nodeValue !== attr2.nodeValue) return false;\n                }\n            }\n            return true;\n        }\n\n        function elementHasNonClassAttributes(el, exceptions) {\n            for (var i = 0, len = el.attributes.length, attrName; i < len; ++i) {\n                attrName = el.attributes[i].name;\n                if ( !(exceptions && contains(exceptions, attrName)) && el.attributes[i].specified && attrName != \"class\") {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        function elementHasProperties(el, props) {\n            return each(props, function(p, propValue) {\n                if (typeof propValue == \"object\") {\n                    if (!elementHasProperties(el[p], propValue)) {\n                        return false;\n                    }\n                } else if (el[p] !== propValue) {\n                    return false;\n                }\n            });\n        }\n\n        var getComputedStyleProperty = dom.getComputedStyleProperty;\n        var isEditableElement = (function() {\n            var testEl = document.createElement(\"div\");\n            return typeof testEl.isContentEditable == \"boolean\" ?\n                function (node) {\n                    return node && node.nodeType == 1 && node.isContentEditable;\n                } :\n                function (node) {\n                    if (!node || node.nodeType != 1 || node.contentEditable == \"false\") {\n                        return false;\n                    }\n                    return node.contentEditable == \"true\" || isEditableElement(node.parentNode);\n                };\n        })();\n\n        function isEditingHost(node) {\n            var parent;\n            return node && node.nodeType == 1 &&\n                (( (parent = node.parentNode) && parent.nodeType == 9 && parent.designMode == \"on\") ||\n                (isEditableElement(node) && !isEditableElement(node.parentNode)));\n        }\n\n        function isEditable(node) {\n            return (isEditableElement(node) || (node.nodeType != 1 && isEditableElement(node.parentNode))) && !isEditingHost(node);\n        }\n\n        var inlineDisplayRegex = /^inline(-block|-table)?$/i;\n\n        function isNonInlineElement(node) {\n            return node && node.nodeType == 1 && !inlineDisplayRegex.test(getComputedStyleProperty(node, \"display\"));\n        }\n\n        // White space characters as defined by HTML 4 (http://www.w3.org/TR/html401/struct/text.html)\n        var htmlNonWhiteSpaceRegex = /[^\\r\\n\\t\\f \\u200B]/;\n\n        function isUnrenderedWhiteSpaceNode(node) {\n            if (node.data.length == 0) {\n                return true;\n            }\n            if (htmlNonWhiteSpaceRegex.test(node.data)) {\n                return false;\n            }\n            var cssWhiteSpace = getComputedStyleProperty(node.parentNode, \"whiteSpace\");\n            switch (cssWhiteSpace) {\n                case \"pre\":\n                case \"pre-wrap\":\n                case \"-moz-pre-wrap\":\n                    return false;\n                case \"pre-line\":\n                    if (/[\\r\\n]/.test(node.data)) {\n                        return false;\n                    }\n            }\n\n            // We now have a whitespace-only text node that may be rendered depending on its context. If it is adjacent to a\n            // non-inline element, it will not be rendered. This seems to be a good enough definition.\n            return isNonInlineElement(node.previousSibling) || isNonInlineElement(node.nextSibling);\n        }\n\n        function getRangeBoundaries(ranges) {\n            var positions = [], i, range;\n            for (i = 0; range = ranges[i++]; ) {\n                positions.push(\n                    new DomPosition(range.startContainer, range.startOffset),\n                    new DomPosition(range.endContainer, range.endOffset)\n                );\n            }\n            return positions;\n        }\n\n        function updateRangesFromBoundaries(ranges, positions) {\n            for (var i = 0, range, start, end, len = ranges.length; i < len; ++i) {\n                range = ranges[i];\n                start = positions[i * 2];\n                end = positions[i * 2 + 1];\n                range.setStartAndEnd(start.node, start.offset, end.node, end.offset);\n            }\n        }\n\n        function isSplitPoint(node, offset) {\n            if (dom.isCharacterDataNode(node)) {\n                if (offset == 0) {\n                    return !!node.previousSibling;\n                } else if (offset == node.length) {\n                    return !!node.nextSibling;\n                } else {\n                    return true;\n                }\n            }\n\n            return offset > 0 && offset < node.childNodes.length;\n        }\n\n        function splitNodeAt(node, descendantNode, descendantOffset, positionsToPreserve) {\n            var newNode, parentNode;\n            var splitAtStart = (descendantOffset == 0);\n\n            if (dom.isAncestorOf(descendantNode, node)) {\n                return node;\n            }\n\n            if (dom.isCharacterDataNode(descendantNode)) {\n                var descendantIndex = dom.getNodeIndex(descendantNode);\n                if (descendantOffset == 0) {\n                    descendantOffset = descendantIndex;\n                } else if (descendantOffset == descendantNode.length) {\n                    descendantOffset = descendantIndex + 1;\n                } else {\n                    throw module.createError(\"splitNodeAt() should not be called with offset in the middle of a data node (\" +\n                        descendantOffset + \" in \" + descendantNode.data);\n                }\n                descendantNode = descendantNode.parentNode;\n            }\n\n            if (isSplitPoint(descendantNode, descendantOffset)) {\n                // descendantNode is now guaranteed not to be a text or other character node\n                newNode = descendantNode.cloneNode(false);\n                parentNode = descendantNode.parentNode;\n                if (newNode.id) {\n                    newNode.removeAttribute(\"id\");\n                }\n                var child, newChildIndex = 0;\n\n                while ( (child = descendantNode.childNodes[descendantOffset]) ) {\n                    movePreservingPositions(child, newNode, newChildIndex++, positionsToPreserve);\n                }\n                movePreservingPositions(newNode, parentNode, dom.getNodeIndex(descendantNode) + 1, positionsToPreserve);\n                return (descendantNode == node) ? newNode : splitNodeAt(node, parentNode, dom.getNodeIndex(newNode), positionsToPreserve);\n            } else if (node != descendantNode) {\n                newNode = descendantNode.parentNode;\n\n                // Work out a new split point in the parent node\n                var newNodeIndex = dom.getNodeIndex(descendantNode);\n\n                if (!splitAtStart) {\n                    newNodeIndex++;\n                }\n                return splitNodeAt(node, newNode, newNodeIndex, positionsToPreserve);\n            }\n            return node;\n        }\n\n        function areElementsMergeable(el1, el2) {\n            return el1.namespaceURI == el2.namespaceURI &&\n                el1.tagName.toLowerCase() == el2.tagName.toLowerCase() &&\n                haveSameClasses(el1, el2) &&\n                elementsHaveSameNonClassAttributes(el1, el2) &&\n                getComputedStyleProperty(el1, \"display\") == \"inline\" &&\n                getComputedStyleProperty(el2, \"display\") == \"inline\";\n        }\n\n        function createAdjacentMergeableTextNodeGetter(forward) {\n            var siblingPropName = forward ? \"nextSibling\" : \"previousSibling\";\n\n            return function(textNode, checkParentElement) {\n                var el = textNode.parentNode;\n                var adjacentNode = textNode[siblingPropName];\n                if (adjacentNode) {\n                    // Can merge if the node's previous/next sibling is a text node\n                    if (adjacentNode && adjacentNode.nodeType == 3) {\n                        return adjacentNode;\n                    }\n                } else if (checkParentElement) {\n                    // Compare text node parent element with its sibling\n                    adjacentNode = el[siblingPropName];\n                    if (adjacentNode && adjacentNode.nodeType == 1 && areElementsMergeable(el, adjacentNode)) {\n                        var adjacentNodeChild = adjacentNode[forward ? \"firstChild\" : \"lastChild\"];\n                        if (adjacentNodeChild && adjacentNodeChild.nodeType == 3) {\n                            return adjacentNodeChild;\n                        }\n                    }\n                }\n                return null;\n            };\n        }\n\n        var getPreviousMergeableTextNode = createAdjacentMergeableTextNodeGetter(false),\n            getNextMergeableTextNode = createAdjacentMergeableTextNodeGetter(true);\n\n    \n        function Merge(firstNode) {\n            this.isElementMerge = (firstNode.nodeType == 1);\n            this.textNodes = [];\n            var firstTextNode = this.isElementMerge ? firstNode.lastChild : firstNode;\n            if (firstTextNode) {\n                this.textNodes[0] = firstTextNode;\n            }\n        }\n\n        Merge.prototype = {\n            doMerge: function(positionsToPreserve) {\n                var textNodes = this.textNodes;\n                var firstTextNode = textNodes[0];\n                if (textNodes.length > 1) {\n                    var firstTextNodeIndex = dom.getNodeIndex(firstTextNode);\n                    var textParts = [], combinedTextLength = 0, textNode, parent;\n                    for (var i = 0, len = textNodes.length, j, position; i < len; ++i) {\n                        textNode = textNodes[i];\n                        parent = textNode.parentNode;\n                        if (i > 0) {\n                            parent.removeChild(textNode);\n                            if (!parent.hasChildNodes()) {\n                                parent.parentNode.removeChild(parent);\n                            }\n                            if (positionsToPreserve) {\n                                for (j = 0; position = positionsToPreserve[j++]; ) {\n                                    // Handle case where position is inside the text node being merged into a preceding node\n                                    if (position.node == textNode) {\n                                        position.node = firstTextNode;\n                                        position.offset += combinedTextLength;\n                                    }\n                                    // Handle case where both text nodes precede the position within the same parent node\n                                    if (position.node == parent && position.offset > firstTextNodeIndex) {\n                                        --position.offset;\n                                        if (position.offset == firstTextNodeIndex + 1 && i < len - 1) {\n                                            position.node = firstTextNode;\n                                            position.offset = combinedTextLength;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        textParts[i] = textNode.data;\n                        combinedTextLength += textNode.data.length;\n                    }\n                    firstTextNode.data = textParts.join(\"\");\n                }\n                return firstTextNode.data;\n            },\n\n            getLength: function() {\n                var i = this.textNodes.length, len = 0;\n                while (i--) {\n                    len += this.textNodes[i].length;\n                }\n                return len;\n            },\n\n            toString: function() {\n                var textParts = [];\n                for (var i = 0, len = this.textNodes.length; i < len; ++i) {\n                    textParts[i] = \"'\" + this.textNodes[i].data + \"'\";\n                }\n                return \"[Merge(\" + textParts.join(\",\") + \")]\";\n            }\n        };\n\n        var optionProperties = [\"elementTagName\", \"ignoreWhiteSpace\", \"applyToEditableOnly\", \"useExistingElements\",\n            \"removeEmptyElements\", \"onElementCreate\"];\n\n        // TODO: Populate this with every attribute name that corresponds to a property with a different name. Really??\n        var attrNamesForProperties = {};\n\n        function ClassApplier(className, options, tagNames) {\n            var normalize, i, len, propName, applier = this;\n            applier.cssClass = applier.className = className; // cssClass property is for backward compatibility\n\n            var elementPropertiesFromOptions = null, elementAttributes = {};\n\n            // Initialize from options object\n            if (typeof options == \"object\" && options !== null) {\n                tagNames = options.tagNames;\n                elementPropertiesFromOptions = options.elementProperties;\n                elementAttributes = options.elementAttributes;\n\n                for (i = 0; propName = optionProperties[i++]; ) {\n                    if (options.hasOwnProperty(propName)) {\n                        applier[propName] = options[propName];\n                    }\n                }\n                normalize = options.normalize;\n            } else {\n                normalize = options;\n            }\n\n            // Backward compatibility: the second parameter can also be a Boolean indicating to normalize after unapplying\n            applier.normalize = (typeof normalize == \"undefined\") ? true : normalize;\n\n            // Initialize element properties and attribute exceptions\n            applier.attrExceptions = [];\n            var el = document.createElement(applier.elementTagName);\n            applier.elementProperties = applier.copyPropertiesToElement(elementPropertiesFromOptions, el, true);\n            each(elementAttributes, function(attrName) {\n                applier.attrExceptions.push(attrName);\n            });\n            applier.elementAttributes = elementAttributes;\n\n            applier.elementSortedClassName = applier.elementProperties.hasOwnProperty(\"className\") ?\n                applier.elementProperties.className : className;\n\n            // Initialize tag names\n            applier.applyToAnyTagName = false;\n            var type = typeof tagNames;\n            if (type == \"string\") {\n                if (tagNames == \"*\") {\n                    applier.applyToAnyTagName = true;\n                } else {\n                    applier.tagNames = trim(tagNames.toLowerCase()).split(/\\s*,\\s*/);\n                }\n            } else if (type == \"object\" && typeof tagNames.length == \"number\") {\n                applier.tagNames = [];\n                for (i = 0, len = tagNames.length; i < len; ++i) {\n                    if (tagNames[i] == \"*\") {\n                        applier.applyToAnyTagName = true;\n                    } else {\n                        applier.tagNames.push(tagNames[i].toLowerCase());\n                    }\n                }\n            } else {\n                applier.tagNames = [applier.elementTagName];\n            }\n        }\n\n        ClassApplier.prototype = {\n            elementTagName: defaultTagName,\n            elementProperties: {},\n            elementAttributes: {},\n            ignoreWhiteSpace: true,\n            applyToEditableOnly: false,\n            useExistingElements: true,\n            removeEmptyElements: true,\n            onElementCreate: null,\n\n            copyPropertiesToElement: function(props, el, createCopy) {\n                var s, elStyle, elProps = {}, elPropsStyle, propValue, elPropValue, attrName;\n\n                for (var p in props) {\n                    if (props.hasOwnProperty(p)) {\n                        propValue = props[p];\n                        elPropValue = el[p];\n\n                        // Special case for class. The copied properties object has the applier's CSS class as well as its\n                        // own to simplify checks when removing styling elements\n                        if (p == \"className\") {\n                            addClass(el, propValue);\n                            addClass(el, this.className);\n                            el[p] = sortClassName(el[p]);\n                            if (createCopy) {\n                                elProps[p] = el[p];\n                            }\n                        }\n\n                        // Special case for style\n                        else if (p == \"style\") {\n                            elStyle = elPropValue;\n                            if (createCopy) {\n                                elProps[p] = elPropsStyle = {};\n                            }\n                            for (s in props[p]) {\n                                elStyle[s] = propValue[s];\n                                if (createCopy) {\n                                    elPropsStyle[s] = elStyle[s];\n                                }\n                            }\n                            this.attrExceptions.push(p);\n                        } else {\n                            el[p] = propValue;\n                            // Copy the property back from the dummy element so that later comparisons to check whether\n                            // elements may be removed are checking against the right value. For example, the href property\n                            // of an element returns a fully qualified URL even if it was previously assigned a relative\n                            // URL.\n                            if (createCopy) {\n                                elProps[p] = el[p];\n\n                                // Not all properties map to identically-named attributes\n                                attrName = attrNamesForProperties.hasOwnProperty(p) ? attrNamesForProperties[p] : p;\n                                this.attrExceptions.push(attrName);\n                            }\n                        }\n                    }\n                }\n\n                return createCopy ? elProps : \"\";\n            },\n            \n            copyAttributesToElement: function(attrs, el) {\n                for (var attrName in attrs) {\n                    if (attrs.hasOwnProperty(attrName)) {\n                        el.setAttribute(attrName, attrs[attrName]);\n                    }\n                }\n            },\n\n            hasClass: function(node) {\n                return node.nodeType == 1 &&\n                    contains(this.tagNames, node.tagName.toLowerCase()) &&\n                    hasClass(node, this.className);\n            },\n\n            getSelfOrAncestorWithClass: function(node) {\n                while (node) {\n                    if (this.hasClass(node)) {\n                        return node;\n                    }\n                    node = node.parentNode;\n                }\n                return null;\n            },\n\n            isModifiable: function(node) {\n                return !this.applyToEditableOnly || isEditable(node);\n            },\n\n            // White space adjacent to an unwrappable node can be ignored for wrapping\n            isIgnorableWhiteSpaceNode: function(node) {\n                return this.ignoreWhiteSpace && node && node.nodeType == 3 && isUnrenderedWhiteSpaceNode(node);\n            },\n\n            // Normalizes nodes after applying a CSS class to a Range.\n            postApply: function(textNodes, range, positionsToPreserve, isUndo) {\n                var firstNode = textNodes[0], lastNode = textNodes[textNodes.length - 1];\n\n                var merges = [], currentMerge;\n\n                var rangeStartNode = firstNode, rangeEndNode = lastNode;\n                var rangeStartOffset = 0, rangeEndOffset = lastNode.length;\n\n                var textNode, precedingTextNode;\n\n                // Check for every required merge and create a Merge object for each\n                for (var i = 0, len = textNodes.length; i < len; ++i) {\n                    textNode = textNodes[i];\n                    precedingTextNode = getPreviousMergeableTextNode(textNode, !isUndo);\n                    if (precedingTextNode) {\n                        if (!currentMerge) {\n                            currentMerge = new Merge(precedingTextNode);\n                            merges.push(currentMerge);\n                        }\n                        currentMerge.textNodes.push(textNode);\n                        if (textNode === firstNode) {\n                            rangeStartNode = currentMerge.textNodes[0];\n                            rangeStartOffset = rangeStartNode.length;\n                        }\n                        if (textNode === lastNode) {\n                            rangeEndNode = currentMerge.textNodes[0];\n                            rangeEndOffset = currentMerge.getLength();\n                        }\n                    } else {\n                        currentMerge = null;\n                    }\n                }\n\n                // Test whether the first node after the range needs merging\n                var nextTextNode = getNextMergeableTextNode(lastNode, !isUndo);\n\n                if (nextTextNode) {\n                    if (!currentMerge) {\n                        currentMerge = new Merge(lastNode);\n                        merges.push(currentMerge);\n                    }\n                    currentMerge.textNodes.push(nextTextNode);\n                }\n\n                // Apply the merges\n                if (merges.length) {\n                    for (i = 0, len = merges.length; i < len; ++i) {\n                        merges[i].doMerge(positionsToPreserve);\n                    }\n\n                    // Set the range boundaries\n                    range.setStartAndEnd(rangeStartNode, rangeStartOffset, rangeEndNode, rangeEndOffset);\n                }\n            },\n\n            createContainer: function(doc) {\n                var el = doc.createElement(this.elementTagName);\n                this.copyPropertiesToElement(this.elementProperties, el, false);\n                this.copyAttributesToElement(this.elementAttributes, el);\n                addClass(el, this.className);\n                if (this.onElementCreate) {\n                    this.onElementCreate(el, this);\n                }\n                return el;\n            },\n\n            applyToTextNode: function(textNode, positionsToPreserve) {\n                var parent = textNode.parentNode;\n                if (parent.childNodes.length == 1 &&\n                        this.useExistingElements &&\n                        isHtmlNamespace(parent) &&\n                        contains(this.tagNames, parent.tagName.toLowerCase()) &&\n                        elementHasProperties(parent, this.elementProperties)) {\n\n                    addClass(parent, this.className);\n                } else {\n                    var el = this.createContainer(dom.getDocument(textNode));\n                    textNode.parentNode.insertBefore(el, textNode);\n                    el.appendChild(textNode);\n                }\n            },\n\n            isRemovable: function(el) {\n                return isHtmlNamespace(el) &&\n                    el.tagName.toLowerCase() == this.elementTagName &&\n                    getSortedClassName(el) == this.elementSortedClassName &&\n                    elementHasProperties(el, this.elementProperties) &&\n                    !elementHasNonClassAttributes(el, this.attrExceptions) &&\n                    this.isModifiable(el);\n            },\n\n            isEmptyContainer: function(el) {\n                var childNodeCount = el.childNodes.length;\n                return el.nodeType == 1 &&\n                    this.isRemovable(el) &&\n                    (childNodeCount == 0 || (childNodeCount == 1 && this.isEmptyContainer(el.firstChild)));\n            },\n            \n            removeEmptyContainers: function(range) {\n                var applier = this;\n                var nodesToRemove = range.getNodes([1], function(el) {\n                    return applier.isEmptyContainer(el);\n                });\n                \n                var rangesToPreserve = [range];\n                var positionsToPreserve = getRangeBoundaries(rangesToPreserve);\n                \n                for (var i = 0, node; node = nodesToRemove[i++]; ) {\n                    removePreservingPositions(node, positionsToPreserve);\n                }\n\n                // Update the range from the preserved boundary positions\n                updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);\n            },\n\n            undoToTextNode: function(textNode, range, ancestorWithClass, positionsToPreserve) {\n                if (!range.containsNode(ancestorWithClass)) {\n                    // Split out the portion of the ancestor from which we can remove the CSS class\n                    //var parent = ancestorWithClass.parentNode, index = dom.getNodeIndex(ancestorWithClass);\n                    var ancestorRange = range.cloneRange();\n                    ancestorRange.selectNode(ancestorWithClass);\n                    if (ancestorRange.isPointInRange(range.endContainer, range.endOffset)) {\n                        splitNodeAt(ancestorWithClass, range.endContainer, range.endOffset, positionsToPreserve);\n                        range.setEndAfter(ancestorWithClass);\n                    }\n                    if (ancestorRange.isPointInRange(range.startContainer, range.startOffset)) {\n                        ancestorWithClass = splitNodeAt(ancestorWithClass, range.startContainer, range.startOffset, positionsToPreserve);\n                    }\n                }\n                if (this.isRemovable(ancestorWithClass)) {\n                    replaceWithOwnChildrenPreservingPositions(ancestorWithClass, positionsToPreserve);\n                } else {\n                    removeClass(ancestorWithClass, this.className);\n                }\n            },\n\n            applyToRange: function(range, rangesToPreserve) {\n                rangesToPreserve = rangesToPreserve || [];\n\n                // Create an array of range boundaries to preserve\n                var positionsToPreserve = getRangeBoundaries(rangesToPreserve || []);\n                \n                range.splitBoundariesPreservingPositions(positionsToPreserve);\n\n                // Tidy up the DOM by removing empty containers \n                if (this.removeEmptyElements) {\n                    this.removeEmptyContainers(range);\n                }\n\n                var textNodes = getEffectiveTextNodes(range);\n\n                if (textNodes.length) {\n                    for (var i = 0, textNode; textNode = textNodes[i++]; ) {\n                        if (!this.isIgnorableWhiteSpaceNode(textNode) && !this.getSelfOrAncestorWithClass(textNode) &&\n                                this.isModifiable(textNode)) {\n                            this.applyToTextNode(textNode, positionsToPreserve);\n                        }\n                    }\n                    textNode = textNodes[textNodes.length - 1];\n                    range.setStartAndEnd(textNodes[0], 0, textNode, textNode.length);\n                    if (this.normalize) {\n                        this.postApply(textNodes, range, positionsToPreserve, false);\n                    }\n\n                    // Update the ranges from the preserved boundary positions\n                    updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);\n                }\n            },\n\n            applyToRanges: function(ranges) {\n\n                var i = ranges.length;\n                while (i--) {\n                    this.applyToRange(ranges[i], ranges);\n                }\n\n\n                return ranges;\n            },\n\n            applyToSelection: function(win) {\n                var sel = api.getSelection(win);\n                sel.setRanges( this.applyToRanges(sel.getAllRanges()) );\n            },\n\n            undoToRange: function(range, rangesToPreserve) {\n                // Create an array of range boundaries to preserve\n                rangesToPreserve = rangesToPreserve || [];\n                var positionsToPreserve = getRangeBoundaries(rangesToPreserve);\n\n\n                range.splitBoundariesPreservingPositions(positionsToPreserve);\n\n                // Tidy up the DOM by removing empty containers \n                if (this.removeEmptyElements) {\n                    this.removeEmptyContainers(range, positionsToPreserve);\n                }\n\n                var textNodes = getEffectiveTextNodes(range);\n                var textNode, ancestorWithClass;\n                var lastTextNode = textNodes[textNodes.length - 1];\n\n                if (textNodes.length) {\n                    for (var i = 0, len = textNodes.length; i < len; ++i) {\n                        textNode = textNodes[i];\n                        ancestorWithClass = this.getSelfOrAncestorWithClass(textNode);\n                        if (ancestorWithClass && this.isModifiable(textNode)) {\n                            this.undoToTextNode(textNode, range, ancestorWithClass, positionsToPreserve);\n                        }\n\n                        // Ensure the range is still valid\n                        range.setStartAndEnd(textNodes[0], 0, lastTextNode, lastTextNode.length);\n                    }\n\n\n                    if (this.normalize) {\n                        this.postApply(textNodes, range, positionsToPreserve, true);\n                    }\n\n                    // Update the ranges from the preserved boundary positions\n                    updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);\n                }\n            },\n\n            undoToRanges: function(ranges) {\n                // Get ranges returned in document order\n                var i = ranges.length;\n\n                while (i--) {\n                    this.undoToRange(ranges[i], ranges);\n                }\n\n                return ranges;\n            },\n\n            undoToSelection: function(win) {\n                var sel = api.getSelection(win);\n                var ranges = api.getSelection(win).getAllRanges();\n                this.undoToRanges(ranges);\n                sel.setRanges(ranges);\n            },\n\n    /*\n            getTextSelectedByRange: function(textNode, range) {\n                var textRange = range.cloneRange();\n                textRange.selectNodeContents(textNode);\n\n                var intersectionRange = textRange.intersection(range);\n                var text = intersectionRange ? intersectionRange.toString() : \"\";\n                textRange.detach();\n\n                return text;\n            },\n    */\n\n            isAppliedToRange: function(range) {\n                if (range.collapsed || range.toString() == \"\") {\n                    return !!this.getSelfOrAncestorWithClass(range.commonAncestorContainer);\n                } else {\n                    var textNodes = range.getNodes( [3] );\n                    if (textNodes.length)\n                    for (var i = 0, textNode; textNode = textNodes[i++]; ) {\n                        if (!this.isIgnorableWhiteSpaceNode(textNode) && rangeSelectsAnyText(range, textNode) &&\n                                this.isModifiable(textNode) && !this.getSelfOrAncestorWithClass(textNode)) {\n                            return false;\n                        }\n                    }\n                    return true;\n                }\n            },\n\n            isAppliedToRanges: function(ranges) {\n                var i = ranges.length;\n                if (i == 0) {\n                    return false;\n                }\n                while (i--) {\n                    if (!this.isAppliedToRange(ranges[i])) {\n                        return false;\n                    }\n                }\n                return true;\n            },\n\n            isAppliedToSelection: function(win) {\n                var sel = api.getSelection(win);\n                return this.isAppliedToRanges(sel.getAllRanges());\n            },\n\n            toggleRange: function(range) {\n                if (this.isAppliedToRange(range)) {\n                    this.undoToRange(range);\n                } else {\n                    this.applyToRange(range);\n                }\n            },\n\n    /*\n            toggleRanges: function(ranges) {\n                if (this.isAppliedToRanges(ranges)) {\n                    this.undoToRanges(ranges);\n                } else {\n                    this.applyToRanges(ranges);\n                }\n            },\n    */\n\n            toggleSelection: function(win) {\n                if (this.isAppliedToSelection(win)) {\n                    this.undoToSelection(win);\n                } else {\n                    this.applyToSelection(win);\n                }\n            },\n            \n            getElementsWithClassIntersectingRange: function(range) {\n                var elements = [];\n                var applier = this;\n                range.getNodes([3], function(textNode) {\n                    var el = applier.getSelfOrAncestorWithClass(textNode);\n                    if (el && !contains(elements, el)) {\n                        elements.push(el);\n                    }\n                });\n                return elements;\n            },\n\n    /*\n            getElementsWithClassIntersectingSelection: function(win) {\n                var sel = api.getSelection(win);\n                var elements = [];\n                var applier = this;\n                sel.eachRange(function(range) {\n                    var rangeElements = applier.getElementsWithClassIntersectingRange(range);\n                    for (var i = 0, el; el = rangeElements[i++]; ) {\n                        if (!contains(elements, el)) {\n                            elements.push(el);\n                        }\n                    }\n                });\n                return elements;\n            },\n    */\n\n            detach: function() {}\n        };\n\n        function createClassApplier(className, options, tagNames) {\n            return new ClassApplier(className, options, tagNames);\n        }\n\n        ClassApplier.util = {\n            hasClass: hasClass,\n            addClass: addClass,\n            removeClass: removeClass,\n            hasSameClasses: haveSameClasses,\n            replaceWithOwnChildren: replaceWithOwnChildrenPreservingPositions,\n            elementsHaveSameNonClassAttributes: elementsHaveSameNonClassAttributes,\n            elementHasNonClassAttributes: elementHasNonClassAttributes,\n            splitNodeAt: splitNodeAt,\n            isEditableElement: isEditableElement,\n            isEditingHost: isEditingHost,\n            isEditable: isEditable\n        };\n\n        api.CssClassApplier = api.ClassApplier = ClassApplier;\n        api.createCssClassApplier = api.createClassApplier = createClassApplier;\n    });\n    \n}, this);\n/*\n * Medium.js\n *\n * Copyright 2013, Jacob Kelley - http://jakiestfu.com/\n * Released under the MIT Licence\n * http://opensource.org/licenses/MIT\n *\n * Github:  http://github.com/jakiestfu/Medium.js/\n * Version: 1.0\n */\n\n(function (w, d) {\n\t'use strict';\n\t\n\t// check if the selection contains noneditable element\n\tfunction checkNonEditable(e, selRange) {\n\t\tvar i =0;\n\t\tvar nodes = selRange.cloneContents().querySelectorAll(\"[contenteditable='false']\");\n\t\tfor (i =0; i< nodes.length; i++) {\n\t\t\tif (nodes[i].tagName !=\"A\") {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\t\n\tfunction checkBackspaceForNoEditable(elem)\n\t{\n\t\tvar elem = elem.previousElementSibling;\n\t\twhile (elem) {\n\t\t   if ((elem.contentEditable == \"false\" || elem.readonly == \"true\" || elem.classList.contains('lasso-undeletable')) && elem.tagName !=\"A\") {\n\t\t\t   return true;\n\t\t   }\n\t\t   if (elem.innerHTML.includes(\"<!--\") || jQuery.trim( elem.innerHTML)==\"\"){\n\t\t\t   elem = elem.previousElementSibling;\n\t\t   } else {\n\t\t\t   return false;\n\t\t   }\n\t\t};\n\t\treturn false;\n\t}\n\t\n\tfunction checkDeleteForNoEditable(elem)\n\t{\n\t\tvar elem = elem.nextElementSibling;\n\t\twhile (elem) {\n\t\t   if ((elem.contentEditable == \"false\" || elem.readonly == \"true\" || elem.classList.contains('lasso-undeletable')) && elem.tagName !=\"A\"){\n\t\t\t   return true;\n\t\t   }\n\t\t   if (elem.innerHTML.includes(\"<!--\") || jQuery.trim( elem.innerHTML)==\"\"){\n\t\t\t   elem = elem.nextElementSibling;\n\t\t   } else {\n\t\t\t   return false;\n\t\t   }\n\t\t};\n\t\treturn false;\n\t}\n\t\n\tvar Medium = (function () {\n\t\t\n\t\tvar trim = function (string) {\n\t\t\t\treturn string.replace(/^\\s+|\\s+$/g, '');\n\t\t\t},\n\t\t\tarrayContains = function (array, variable) {\n\t\t\t\tvar i = array.length;\n\t\t\t\twhile (i--) {\n\t\t\t\t\tif (array[i] === variable) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t    //two modes, wild (native) or domesticated (rangy + undo.js)\n\t\t\trangy = w['rangy'] || null,\n\t\t\tundo = w['Undo'] || null,\n\t\t\twild = (!rangy || !undo),\n\t\t\tdomesticated = (!wild),\n\t\t\tkey = w.Key = {\n\t\t\t\t'backspace': 8,\n\t\t\t\t'tab': 9,\n\t\t\t\t'enter': 13,\n\t\t\t\t'shift': 16,\n\t\t\t\t'ctrl': 17,\n\t\t\t\t'alt': 18,\n\t\t\t\t'pause': 19,\n\t\t\t\t'capsLock': 20,\n\t\t\t\t'escape': 27,\n\t\t\t\t'pageUp': 33,\n\t\t\t\t'pageDown': 34,\n\t\t\t\t'end': 35,\n\t\t\t\t'home': 36,\n\t\t\t\t'leftArrow': 37,\n\t\t\t\t'upArrow': 38,\n\t\t\t\t'rightArrow': 39,\n\t\t\t\t'downArrow': 40,\n\t\t\t\t'insert': 45,\n\t\t\t\t'delete': 46,\n\t\t\t\t'0': 48,\n\t\t\t\t'1': 49,\n\t\t\t\t'2': 50,\n\t\t\t\t'3': 51,\n\t\t\t\t'4': 52,\n\t\t\t\t'5': 53,\n\t\t\t\t'6': 54,\n\t\t\t\t'7': 55,\n\t\t\t\t'8': 56,\n\t\t\t\t'9': 57,\n\t\t\t\t'a': 65,\n\t\t\t\t'b': 66,\n\t\t\t\t'c': 67,\n\t\t\t\t'd': 68,\n\t\t\t\t'e': 69,\n\t\t\t\t'f': 70,\n\t\t\t\t'g': 71,\n\t\t\t\t'h': 72,\n\t\t\t\t'i': 73,\n\t\t\t\t'j': 74,\n\t\t\t\t'k': 75,\n\t\t\t\t'l': 76,\n\t\t\t\t'm': 77,\n\t\t\t\t'n': 78,\n\t\t\t\t'o': 79,\n\t\t\t\t'p': 80,\n\t\t\t\t'q': 81,\n\t\t\t\t'r': 82,\n\t\t\t\t's': 83,\n\t\t\t\t't': 84,\n\t\t\t\t'u': 85,\n\t\t\t\t'v': 86,\n\t\t\t\t'w': 87,\n\t\t\t\t'x': 88,\n\t\t\t\t'y': 89,\n\t\t\t\t'z': 90,\n\t\t\t\t'leftWindow': 91,\n\t\t\t\t'rightWindowKey': 92,\n\t\t\t\t'select': 93,\n\t\t\t\t'numpad0': 96,\n\t\t\t\t'numpad1': 97,\n\t\t\t\t'numpad2': 98,\n\t\t\t\t'numpad3': 99,\n\t\t\t\t'numpad4': 100,\n\t\t\t\t'numpad5': 101,\n\t\t\t\t'numpad6': 102,\n\t\t\t\t'numpad7': 103,\n\t\t\t\t'numpad8': 104,\n\t\t\t\t'numpad9': 105,\n\t\t\t\t'multiply': 106,\n\t\t\t\t'add': 107,\n\t\t\t\t'subtract': 109,\n\t\t\t\t'decimalPoint': 110,\n\t\t\t\t'divide': 111,\n\t\t\t\t'f1': 112,\n\t\t\t\t'f2': 113,\n\t\t\t\t'f3': 114,\n\t\t\t\t'f4': 115,\n\t\t\t\t'f5': 116,\n\t\t\t\t'f6': 117,\n\t\t\t\t'f7': 118,\n\t\t\t\t'f8': 119,\n\t\t\t\t'f9': 120,\n\t\t\t\t'f10': 121,\n\t\t\t\t'f11': 122,\n\t\t\t\t'f12': 123,\n\t\t\t\t'numLock': 144,\n\t\t\t\t'scrollLock': 145,\n\t\t\t\t'semiColon': 186,\n\t\t\t\t'equalSign': 187,\n\t\t\t\t'comma': 188,\n\t\t\t\t'dash': 189,\n\t\t\t\t'period': 190,\n\t\t\t\t'forwardSlash': 191,\n\t\t\t\t'graveAccent': 192,\n\t\t\t\t'openBracket': 219,\n\t\t\t\t'backSlash': 220,\n\t\t\t\t'closeBraket': 221,\n\t\t\t\t'singleQuote': 222\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Medium.js - Taking control of content editable\n\t\t\t * @constructor\n\t\t\t * @param {Object} [userSettings] user options\n\t\t\t */\n\t\t\tMedium = function (userSettings) {\n\t\t\t\tvar medium = this,\n\t\t\t\t\taction = new Medium.Action(),\n\t\t\t\t\tcache = new Medium.Cache(),\n\t\t\t\t\tcursor = new Medium.Cursor(),\n\t\t\t\t\thtml = new Medium.HtmlAssistant(),\n\t\t\t\t\tutils = new Medium.Utilities(),\n\t\t\t\t\tselection = new Medium.Selection(),\n\t\t\t\t\tintercept = {\n\t\t\t\t\t\tfocus: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\t\t\t\t\t\t\tMedium.activeElement = el;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tblur: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\t\t\t\t\t\t\tif (Medium.activeElement === el) {\n\t\t\t\t\t\t\t\tMedium.activeElement = null;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\thtml.placeholders();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdown: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\n\t\t\t\t\t\t\tvar keepEvent = true;\n\n\t\t\t\t\t\t\t//in Chrome it sends out this event before every regular event, not sure why\n\t\t\t\t\t\t\tif (e.keyCode === 229) return;\n\n\t\t\t\t\t\t\tutils.isCommand(e, function () {\n\t\t\t\t\t\t\t\tcache.cmd = true;\n\t\t\t\t\t\t\t}, function () {\n\t\t\t\t\t\t\t\tcache.cmd = false;\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tutils.isShift(e, function () {\n\t\t\t\t\t\t\t\tcache.shift = true;\n\t\t\t\t\t\t\t}, function () {\n\t\t\t\t\t\t\t\tcache.shift = false;\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tutils.isModifier(e, function (cmd) {\n\t\t\t\t\t\t\t\tif (cache.cmd) {\n\n\t\t\t\t\t\t\t\t\tif (( (settings.mode === Medium.inlineMode) || (settings.mode === Medium.partialMode) ) && cmd !== \"paste\") {\n\t\t\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tvar cmdType = typeof cmd,\n\t\t\t\t\t\t\t\t\t\tfn = null;\n\n\t\t\t\t\t\t\t\t\tif (cmdType === \"function\") {\n\t\t\t\t\t\t\t\t\t\tfn = cmd;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tfn = intercept.command[cmd];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tkeepEvent = fn.call(medium, e);\n\n\t\t\t\t\t\t\t\t\tif (keepEvent === false) {\n\t\t\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t\t\tutils.stopPropagation(e);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (settings.maxLength !== -1) {\n\t\t\t\t\t\t\t\tvar len = html.text().length,\n\t\t\t\t\t\t\t\t\thasSelection = false,\n\t\t\t\t\t\t\t\t\tselection = w.getSelection();\n\n\t\t\t\t\t\t\t\tif (selection) {\n\t\t\t\t\t\t\t\t\thasSelection = !selection.isCollapsed;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (len >= settings.maxLength && !utils.isSpecial(e) && !utils.isNavigational(e) && !hasSelection) {\n\t\t\t\t\t\t\t\t\treturn utils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tswitch (e.keyCode) {\n\t\t\t\t\t\t\t\tcase key['enter']:\n                                    //disable enter inside FIGURE\n                                    var sel = w.getSelection();\n\t\t\t\t\t\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\t\t\t\t\t\tvar selRange = sel.getRangeAt(0);\n                                        if (window.getSelection().isCollapsed) {\n                                            var container = selRange.endContainer;\n                                            if (container.nodeName==\"FIGURE\") {\n\n                                                e.preventDefault();\n                                                break;\n                                            }\n                                        }\n                                    }\n\t\t\t\t\t\t\t\t\tintercept.enterKey(e);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase key['backspace']:\n\t\t\t\t\t\t\t\tcase key['delete']:\n\t\t\t\t\t\t\t\t    // we do this to prevent non editable elments being deleted\n\t\t\t\t\t\t\t\t\tif (lasso_editor.readOnlyExists) {\n\t\t\t\t\t\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\t\t\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\t\t\t\t\t\t\tvar selRange = sel.getRangeAt(0);\n\t\t\t\t\t\t\t\t\t\t\tif (window.getSelection().isCollapsed) {\n\t\t\t\t\t\t\t\t\t\t\t\tvar container = selRange.endContainer;\n\t\t\t\t\t\t\t\t\t\t\t\tvar container1 = container;\n\t\t\t\t\t\t\t\t\t\t\t\twhile (container && container.parentNode !== articleMedium.element) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tvar nodes = container.parentNode.querySelectorAll(\"[contenteditable='false']\");\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (nodes.length >0) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer = container.parentNode;\n\t\t\t\t\t\t\t\t\t\t\t\t} \t\n\t\t\t\t\t\t\t\t\t\t\t\tif (container.contentEditable == \"false\") {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\tif (e.keyCode == key['backspace'] && checkBackspaceForNoEditable(container)){\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (sel.focusOffset == 0 ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (container1.length == sel.focusOffset && container1.length == 1) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer1.data = \"\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t} else if (e.keyCode == key['delete'] &&  checkDeleteForNoEditable(container)) {\n\t\t\t\t\t\t\t\t\t\t\t\t    if (sel.focusOffset == sel.focusNode.length || sel.focusNode.length === undefined) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (container1.length == 1 && sel.focusOffset == 0){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer1.data = \"\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t// check if the selection contains noneditable element\n\t\t\t\t\t\t\t\t\t\t\t\tif (checkNonEditable(e,selRange)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t   break;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// the undeletable elements can be edited unlike the readonly elements, but should not be deleted\n\t\t\t\t\t\t\t\t\t// they are marked with class lasso-undeletable\n\t\t\t\t\t\t\t\t\tif (lasso_editor.undeletableExists) {\n\t\t\t\t\t\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\t\t\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\t\t\t\t\t\t\tvar selRange = sel.getRangeAt(0);\n\t\t\t\t\t\t\t\t\t\t\tif (window.getSelection().isCollapsed) {\n\t\t\t\t\t\t\t\t\t\t\t\tvar container1 = selRange.endContainer;\n\t\t\t\t\t\t\t\t\t\t\t\tvar container = container1.parentNode;\n\t\t\t\t\t\t\t\t\t\t\t\twhile (container !== articleMedium.element) {\t\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (container.classList.contains('lasso-undeletable')) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (e.keyCode == key['backspace']) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (sel.focusOffset == 0 ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (container1.length == sel.focusOffset && container1.length == 1) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer1.data = \"\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (e.keyCode == key['delete']) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (sel.focusOffset == sel.focusNode.length || sel.focusNode.length === undefined) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (container1.length == 1 && sel.focusOffset == 0){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer1.data = \"\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer = container.parentNode;\n\t\t\t\t\t\t\t\t\t\t\t\t} \t\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t// check if the selection contains non deletable element\n\t\t\t\t\t\t\t\t\t\t\t\tvar nodes = selRange.cloneContents().querySelectorAll(\".lasso-undeletable\");\n\t\t\t\t\t\t\t\t\t\t\t\tif (nodes.length) {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tintercept.backspaceOrDeleteKey(e);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tdefault: \n\t\t\t\t\t\t\t\t\tif (lasso_editor.readOnlyExists || lasso_editor.undeletableExists) {\n\t\t\t\t\t\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\t\t\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\t\t\t\t\t\t\tvar selRange = sel.getRangeAt(0);\n\t\t\t\t\t\t\t\t\t\t\tif (!window.getSelection().isCollapsed) {\n\t\t\t\t\t\t\t\t\t\t\t\tif (checkNonEditable(e, selRange)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\t\t}\t\n\t\t\t\t\t\t\t\t\t\t\t\t// check if the selection contains non deletable element\n\t\t\t\t\t\t\t\t\t\t\t\tvar nodes = selRange.cloneContents().querySelectorAll(\".lasso-undeletable\");\n\t\t\t\t\t\t\t\t\t\t\t\tif (nodes.length) {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn keepEvent;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tup: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\t\t\t\t\t\t\tutils.isCommand(e, function () {\n\t\t\t\t\t\t\t\tcache.cmd = false;\n\t\t\t\t\t\t\t}, function () {\n\t\t\t\t\t\t\t\tcache.cmd = true;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\thtml.placeholders();\n\n\t\t\t\t\t\t\t//here we have a key context, so if you need to create your own object within a specific context it is doable\n\t\t\t\t\t\t\tvar keyContext;\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tsettings.keyContext !== null\n\t\t\t\t\t\t\t\t&& ( keyContext = settings.keyContext[e.keyCode] )\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tvar el = cursor.parent();\n\n\t\t\t\t\t\t\t\tif (el) {\n\t\t\t\t\t\t\t\t\tkeyContext.call(medium, e, el);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n                            \n                            lasso_editor.checkForPopup();\n\n\t\t\t\t\t\t\taction.preserveElementFocus();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcommand: {\n\t\t\t\t\t\t\tbold: function (e) {\n\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t// IE uses strong instead of b\n\t\t\t\t\t\t\t\t(new Medium.Element(medium, 'bold'))\n\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t.invoke(settings.beforeInvokeElement);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tunderline: function (e) {\n\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t(new Medium.Element(medium, 'underline'))\n\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t.invoke(settings.beforeInvokeElement);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\titalicize: function (e) {\n\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t(new Medium.Element(medium, 'italic'))\n\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t.invoke(settings.beforeInvokeElement);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tquote: function (e) {\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tpaste: function (e) {\n\t\t\t\t\t\t\t\tmedium.makeUndoable();\n\t\t\t\t\t\t\t\t/*if (settings.pasteAsText) {\n\t\t\t\t\t\t\t\t\tvar sel = utils.selection.saveSelection();\n\t\t\t\t\t\t\t\t\tutils.pasteHook(function (text) {\n\t\t\t\t\t\t\t\t\t\tutils.selection.restoreSelection(sel);\n\n\t\t\t\t\t\t\t\t\t\ttext = text.replace(/\\n/g, '<br>');\n\n\t\t\t\t\t\t\t\t\t\t(new Medium.Html(medium, text))\n\t\t\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t\t\t.insert(settings.beforeInsertHtml, true);\n\n\t\t\t\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\t\t\t\thtml.placeholders();\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\t\t\thtml.placeholders();\n\t\t\t\t\t\t\t\t}*/\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tenterKey: function (e) {\n\t\t\t\t\t\t\tif (settings.mode === Medium.inlineMode) {\n\t\t\t\t\t\t\t\treturn utils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!cache.shift) {\n\n\t\t\t\t\t\t\t\tvar focusedElement = html.atCaret() || {},\n\t\t\t\t\t\t\t\t\tchildren = el.children,\n\t\t\t\t\t\t\t\t\tlastChild = focusedElement === el.lastChild ? el.lastChild : null,\n\t\t\t\t\t\t\t\t\tmakeHR,\n\t\t\t\t\t\t\t\t\tsecondToLast,\n\t\t\t\t\t\t\t\t\tparagraph;\n\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tlastChild\n\t\t\t\t\t\t\t\t\t&& lastChild !== el.firstChild\n\t\t\t\t\t\t\t\t\t&& settings.autoHR\n\t\t\t\t\t\t\t\t\t&& settings.mode !== 'partial'\n\t\t\t\t\t\t\t\t\t&& settings.tags.horizontalRule\n\t\t\t\t\t\t\t\t) {\n\n\t\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\n\t\t\t\t\t\t\t\t\tmakeHR =\n\t\t\t\t\t\t\t\t\t\thtml.text(lastChild) === \"\"\n\t\t\t\t\t\t\t\t\t\t&& lastChild.nodeName.toLowerCase() === settings.tags.paragraph;\n\n\t\t\t\t\t\t\t\t\tif (makeHR && children.length >= 2) {\n\t\t\t\t\t\t\t\t\t\tsecondToLast = children[children.length - 2];\n\n\t\t\t\t\t\t\t\t\t\tif (secondToLast.nodeName.toLowerCase() === settings.tags.horizontalRule) {\n\t\t\t\t\t\t\t\t\t\t\tmakeHR = false;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (makeHR) {\n\t\t\t\t\t\t\t\t\t\thtml.addTag(settings.tags.horizontalRule, false, true, focusedElement);\n\t\t\t\t\t\t\t\t\t\tfocusedElement = focusedElement.nextSibling;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ((paragraph = html.addTag(settings.tags.paragraph, true, null, focusedElement)) !== null) {\n\t\t\t\t\t\t\t\t\t\tparagraph.innerHTML = '';\n\t\t\t\t\t\t\t\t\t\tcursor.set(0, paragraph);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbackspaceOrDeleteKey: function (e) {\n\t\t\t\t\t\t\tif (el.lastChild === null) return;\n\n\t\t\t\t\t\t\tvar lastChild = el.lastChild,\n\t\t\t\t\t\t\t\tbeforeLastChild = lastChild.previousSibling;\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tlastChild\n\t\t\t\t\t\t\t\t&& settings.tags.horizontalRule\n\t\t\t\t\t\t\t\t&& lastChild.nodeName.toLocaleLowerCase() === settings.tags.horizontalRule\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tel.removeChild(lastChild);\n\t\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\t\tlastChild\n\t\t\t\t\t\t\t\t&& beforeLastChild\n\t\t\t\t\t\t\t\t&& utils.html.text(lastChild).length < 1\n\n\t\t\t\t\t\t\t\t&& beforeLastChild.nodeName.toLowerCase() === settings.tags.horizontalRule\n\t\t\t\t\t\t\t\t&& lastChild.nodeName.toLowerCase() === settings.tags.paragraph\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tel.removeChild(lastChild);\n\t\t\t\t\t\t\t\tel.removeChild(beforeLastChild);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tdefaultSettings = {\n\t\t\t\t\t\telement: null,\n\t\t\t\t\t\tmodifier: 'auto',\n\t\t\t\t\t\tplaceholder: \"\",\n\t\t\t\t\t\tautofocus: false,\n\t\t\t\t\t\tautoHR: true,\n\t\t\t\t\t\tmode: Medium.richMode,\n\t\t\t\t\t\tmaxLength: -1,\n\t\t\t\t\t\tmodifiers: {\n\t\t\t\t\t\t\t'b': 'bold',\n\t\t\t\t\t\t\t'i': 'italicize',\n\t\t\t\t\t\t\t'u': 'underline',\n\t\t\t\t\t\t\t'v': 'paste'\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttags: {\n\t\t\t\t\t\t\t'break': 'br',\n\t\t\t\t\t\t\t'horizontalRule': 'hr',\n\t\t\t\t\t\t\t'paragraph': 'p',\n\t\t\t\t\t\t\t'outerLevel': ['pre', 'blockquote', 'figure'],\n\t\t\t\t\t\t\t'innerLevel': ['a', 'b', 'u', 'i', 'img', 'strong']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcssClasses: {\n\t\t\t\t\t\t\teditor: 'Medium',\n\t\t\t\t\t\t\tpasteHook: 'Medium-paste-hook',\n\t\t\t\t\t\t\tplaceholder: 'Medium-placeholder',\n\t\t\t\t\t\t\tclear: 'Medium-clear'\n\t\t\t\t\t\t},\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\tremove: ['style', 'class']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpasteAsText: true,\n\t\t\t\t\t\tbeforeInvokeElement: function () {\n\t\t\t\t\t\t\t//this = Medium.Element\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbeforeInsertHtml: function () {\n\t\t\t\t\t\t\t//this = Medium.Html\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbeforeAddTag: function (tag, shouldFocus, isEditable, afterElement) {\n\t\t\t\t\t\t},\n\t\t\t\t\t\tkeyContext: null,\n\t\t\t\t\t\tpasteEventHandler: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\t\t\t\t\t\t\tmedium.makeUndoable();\n\t\t\t\t\t\t\tvar length = medium.value().length;\n\n\t\t\t\t\t\t\tif (settings.pasteAsText) {\n\t\t\t\t\t\t\t\tvar t = e.clipboardData.getData('text/html');\n\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\tif (t.length ==0 )\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tt = e.clipboardData.getData('text/plain');\n\t\t\t\t\t\t\t\t\tt = t.replace(/\\n/g, '<br>');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t\t\tsel = utils.selection.saveSelection(),\n\t\t\t\t\t\t\t\t\ttext = t;//prompt(Medium.Messages.pastHere) || '';\n\n\t\t\t\t\t\t\t\tel.focus();\n\t\t\t\t\t\t\t\tMedium.activeElement = el;\n\t\t\t\t\t\t\t\tutils.selection.restoreSelection(sel);\n\t\t\t\t\t\t\t\tif (text.match(/microsoft-com/)) {\n\t\t\t\t\t\t\t\t\t// if the source is ms word\n\t\t\t\t\t\t\t\t\ttext = e.clipboardData.getData('text/plain');\n\t\t\t\t\t\t\t\t\ttext = text.replace(/\\n/g, '<br>');\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t//limit its length\n\t\t\t\t\t\t\t\t\t//totalLength = text.length + length;\n\t\t\t\t\t\t\t\t\t//if (settings.maxLength > 0 && totalLength > settings.maxLength) {\n\t\t\t\t\t\t\t\t\t//\ttext = text.substring(0, settings.maxLength - length);\n\t\t\t\t\t\t\t\t\t//}\n\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\ttext = text.replace(/<\\/p>/g, '<br>');\n\t\t\t\t\t\t\t\t\tvar regex = /<(?=(?!\\/a))(?=(?!a ))(?=(?!br))([^>]+)>/ig;\n\t\t\t\t\t\t\t\t\ttext = text.replace(regex, \"\");\n\t\t\t\t\t\t\t\t\tregex = /style=\\\"[^\\\"]+\\\"/ig;\n\t\t\t\t\t\t\t\t\ttext = text.replace(regex, \"\");\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t} \n\t\t\t\t\t\t\t\t(new Medium.Html(medium, text))\n\t\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t\t.insert(settings.beforeInsertHtml, true);\n\n\t\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\t\thtml.placeholders();\n\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\t\t\thtml.placeholders();\n\t\t\t\t\t\t\t\t}, 20);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tsettings = utils.deepExtend(defaultSettings, userSettings),\n\t\t\t\t\tel,\n\t\t\t\t\tnewVal,\n\t\t\t\t\ti,\n\t\t\t\t\tbridge = {};\n\n\t\t\t\tfor (i in defaultSettings) {\n\t\t\t\t\t// Override defaults with data-attributes\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof defaultSettings[i] !== 'object'\n\t\t\t\t\t\t&& defaultSettings.hasOwnProperty(i)\n\t\t\t\t\t\t&& settings.element.getAttribute('data-medium-' + key)\n\t\t\t\t\t) {\n\t\t\t\t\t\tnewVal = settings.element.getAttribute('data-medium-' + key);\n\n\t\t\t\t\t\tif (newVal.toLowerCase() === \"false\" || newVal.toLowerCase() === \"true\") {\n\t\t\t\t\t\t\tnewVal = newVal.toLowerCase() === \"true\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsettings[i] = newVal;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (settings.modifiers) {\n\t\t\t\t\tfor (i in settings.modifiers) {\n\t\t\t\t\t\tif (typeof(key[i]) !== 'undefined') {\n\t\t\t\t\t\t\tsettings.modifiers[key[i]] = settings.modifiers[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (settings.keyContext) {\n\t\t\t\t\tfor (i in settings.keyContext) {\n\t\t\t\t\t\tif (typeof(key[i]) !== 'undefined') {\n\t\t\t\t\t\t\tsettings.keyContext[key[i]] = settings.keyContext[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Extend Settings\n\t\t\t\tel = settings.element;\n\n\t\t\t\t// Editable, \n\t\t\t\t//set all editable elements to explicitly editable\n\t\t\t\tvar y = el.children;\n\t\t\t\tvar i;\n\t\t\t\tfor (i = 0; i < y.length; i++) {\n\t\t\t\t\tif (y[i].contentEditable != false) {\n\t\t\t\t\t   y[i].contentEditable = true;\n\t\t\t\t\t} \n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tel.contentEditable = true;\n\t\t\t\tel.className\n\t\t\t\t\t+= (' ' + settings.cssClasses.editor)\n\t\t\t\t+ (' ' + settings.cssClasses.editor + '-' + settings.mode);\n\n\t\t\t\tsettings.tags = (settings.tags || {});\n\t\t\t\tif (settings.tags.outerLevel) {\n\t\t\t\t\tsettings.tags.outerLevel = settings.tags.outerLevel.concat([settings.tags.paragraph, settings.tags.horizontalRule]);\n\t\t\t\t}\n\n\t\t\t\tthis.settings = settings;\n\t\t\t\tthis.element = el;\n\t\t\t\tthis.intercept = intercept;\n\n\t\t\t\tthis.action = action;\n\t\t\t\tthis.cache = cache;\n\t\t\t\tthis.cursor = cursor;\n\t\t\t\tthis.html = html;\n\t\t\t\tthis.utils = utils;\n\t\t\t\tthis.selection = selection;\n\n\t\t\t\tbridge.element = el;\n\t\t\t\tbridge.medium = this;\n\t\t\t\tbridge.settings = settings;\n\n\t\t\t\tbridge.action = action;\n\t\t\t\tbridge.cache = cache;\n\t\t\t\tbridge.cursor = cursor;\n\t\t\t\tbridge.html = html;\n\t\t\t\tbridge.intercept = intercept;\n\t\t\t\tbridge.utils = utils;\n\t\t\t\tbridge.selection = selection;\n\n\t\t\t\taction.setBridge(bridge);\n\t\t\t\tcache.setBridge(bridge);\n\t\t\t\tcursor.setBridge(bridge);\n\t\t\t\thtml.setBridge(bridge);\n\t\t\t\tutils.setBridge(bridge);\n\t\t\t\tselection.setBridge(bridge);\n\n\t\t\t\t// Initialize editor\n\t\t\t\thtml.clean();\n\t\t\t\thtml.placeholders();\n\t\t\t\taction.preserveElementFocus();\n\n\t\t\t\t// Capture Events\n\t\t\t\taction.listen();\n\n\t\t\t\tif (wild) {\n\t\t\t\t\tthis.makeUndoable = function () {\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tthis.dirty = false;\n\t\t\t\t\tthis.undoable = new Medium.Undoable(this);\n\t\t\t\t\tthis.undo = this.undoable.undo;\n\t\t\t\t\tthis.redo = this.undoable.redo;\n\t\t\t\t\tthis.makeUndoable = this.undoable.makeUndoable;\n\t\t\t\t}\n\n\t\t\t\tel.medium = this;\n\n\t\t\t\t// Set as initialized\n\t\t\t\tcache.initialized = true;\n\t\t\t};\n\n\t\tMedium.prototype = {\n\t\t\t/**\n\t\t\t *\n\t\t\t * @param {String|Object} html\n\t\t\t * @param {Function} [callback]\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tinsertHtml: function (html, callback) {\n\t\t\t\tvar result = (new Medium.Html(this, html))\n\t\t\t\t\t.insert(this.settings.beforeInsertHtml);\n\n\t\t\t\tthis.utils.triggerEvent(this.element, \"change\");\n\n\t\t\t\tif (callback) {\n\t\t\t\t\tcallback.apply(result);\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t *\n\t\t\t * @param {String} tagName\n\t\t\t * @param {Object} [attributes]\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tinvokeElement: function (tagName, attributes) {\n\t\t\t\tvar settings = this.settings,\n\t\t\t\t\tattributes = attributes || {},\n\t\t\t\t\tremove = attributes.remove || [];\n\n\t\t\t\tswitch (settings.mode) {\n\t\t\t\t\tcase Medium.inlineMode:\n\t\t\t\t\tcase Medium.partialMode:\n\t\t\t\t\t\treturn this;\n\t\t\t\t\tdefault:\n\t\t\t\t}\n\n\t\t\t\t//invoke works off class, so if it isn't there, we just add it\n\t\t\t\tif (remove.length > 0) {\n\t\t\t\t\tif (!arrayContains(settings, 'class')) {\n\t\t\t\t\t\tremove.push('class');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t(new Medium.Element(this, tagName, attributes))\n\t\t\t\t\t.invoke(this.settings.beforeInvokeElement);\n\n\t\t\t\tthis.utils.triggerEvent(this.element, \"change\");\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\tbehavior: function () {\n\t\t\t\treturn (wild ? 'wild' : 'domesticated');\n\t\t\t},\n\n\t\t\t/**\n\t\t\t *\n\t\t\t * @param value\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tvalue: function (value) {\n\t\t\t\tif (typeof value !== 'undefined') {\n\t\t\t\t\tthis.element.innerHTML = value;\n\n\t\t\t\t\tthis.html.clean();\n\t\t\t\t\tthis.html.placeholders();\n\t\t\t\t} else {\n\t\t\t\t\treturn this.element.innerHTML;\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Focus on element\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tfocus: function () {\n\t\t\t\tvar el = this.element;\n\t\t\t\tel.focus();\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Select all text\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tselect: function () {\n\t\t\t\tvar el = this.element,\n\t\t\t\t\trange,\n\t\t\t\t\tselection;\n\n\t\t\t\tel.focus();\n\n\t\t\t\tif (d.body.createTextRange) {\n\t\t\t\t\trange = d.body.createTextRange();\n\t\t\t\t\trange.moveToElementText(el);\n\t\t\t\t\trange.select();\n\t\t\t\t} else if (w.getSelection) {\n\t\t\t\t\tselection = w.getSelection();\n\t\t\t\t\trange = d.createRange();\n\t\t\t\t\trange.selectNodeContents(el);\n\t\t\t\t\tselection.removeAllRanges();\n\t\t\t\t\tselection.addRange(range);\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\tisActive: function () {\n\t\t\t\treturn (Medium.activeElement === this.element);\n\t\t\t},\n\n\t\t\tdestroy: function () {\n\t\t\t\tvar el = this.element,\n\t\t\t\t\tintercept = this.intercept,\n\t\t\t\t\tsettings = this.settings,\n\t\t\t\t\tplaceholder = this.placeholder || null;\n\n\t\t\t\tif (placeholder !== null && placeholder.setup) {\n\t\t\t\t\t//remove placeholder\n\t\t\t\t\tplaceholder.parentNode.removeChild(placeholder);\n\t\t\t\t\tdelete el.placeHolderActive;\n\t\t\t\t}\n\n\t\t\t\t//remove contenteditable\n\t\t\t\tel.removeAttribute('contenteditable');\n\n\t\t\t\t//remove classes\n\t\t\t\tel.className = trim(el.className\n\t\t\t\t\t.replace(settings.cssClasses.editor, '')\n\t\t\t\t\t.replace(settings.cssClasses.clear, '')\n\t\t\t\t\t.replace(settings.cssClasses.editor + '-' + settings.mode, ''));\n\n\t\t\t\t//remove events\n\t\t\t\tthis.utils\n\t\t\t\t\t.removeEvent(el, 'keyup', intercept.up)\n\t\t\t\t\t.removeEvent(el, 'keydown', intercept.down)\n\t\t\t\t\t.removeEvent(el, 'focus', intercept.focus)\n\t\t\t\t\t.removeEvent(el, 'blur', intercept.focus)\n\t\t\t\t\t.removeEvent(el, 'paste', settings.pasteEventHandler);\n\t\t\t},\n\n\t\t\t// Clears the element and restores the placeholder\n\t\t\tclear: function () {\n\t\t\t\tthis.element.innerHTML = '';\n\t\t\t\tthis.html.placeholders();\n\t\t\t}\n\t\t};\n\n\t\t/**\n\t\t * @param {Medium} medium\n\t\t * @param {String} tagName\n\t\t * @param {Object} [attributes]\n\t\t * @constructor\n\t\t */\n\t\tMedium.Element = function (medium, tagName, attributes) {\n\t\t\tthis.medium = medium;\n\t\t\tthis.element = medium.settings.element;\n\t\t\tif (wild) {\n\t\t\t\tthis.tagName = tagName;\n\t\t\t} else {\n\t\t\t\tswitch (tagName.toLowerCase()) {\n\t\t\t\t\tcase 'bold':\n\t\t\t\t\t\tthis.tagName = 'b';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'italic':\n\t\t\t\t\t\tthis.tagName = 'i';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'underline':\n\t\t\t\t\t\tthis.tagName = 'u';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.tagName = tagName;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.attributes = attributes || {};\n\t\t\tthis.clean = true;\n\t\t};\n\n\n\t\t/**\n\t\t * @constructor\n\t\t * @param {Medium} medium\n\t\t * @param {String|HtmlElement} html\n\t\t */\n\t\tMedium.Html = function (medium, html) {\n\t\t\tthis.medium = medium;\n\t\t\tthis.element = medium.settings.element;\n\t\t\tthis.html = html;\n\t\t\tthis.clean = true;\n\t\t};\n\n\t\t/**\n\t\t *\n\t\t * @constructor\n\t\t */\n\t\tMedium.Injector = function () {\n\t\t};\n\n\t\tif (wild) {\n\t\t\tMedium.Element.prototype = {\n\t\t\t\t/**\n\t\t\t\t * @methodOf Medium.Element\n\t\t\t\t * @param {Function} [fn]\n\t\t\t\t */\n\t\t\t\tinvoke: function (fn) {\n\t\t\t\t\tif (Medium.activeElement === this.element) {\n\t\t\t\t\t\tif (fn) {\n\t\t\t\t\t\t\tfn.apply(this);\n\t\t\t\t\t\t}\n\t\t\t\t\t\td.execCommand(this.tagName, false);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tsetClean: function () {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tMedium.Injector.prototype = {\n\t\t\t\t/**\n\t\t\t\t * @methodOf Medium.Injector\n\t\t\t\t * @param {String|HtmlElement} htmlRaw\n\t\t\t\t * @param {Boolean} [selectInserted]\n\t\t\t\t * @returns {null}\n\t\t\t\t */\n\t\t\t\tinject: function (htmlRaw, selectInserted) {\n\t\t\t\t\tthis.insertHTML(htmlRaw, selectInserted);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t/**\n\t\t\t *\n\t\t\t * @constructor\n\t\t\t */\n\t\t\tMedium.Undoable = function () {\n\t\t\t};\n\t\t}\n\n\t\t//if medium is domesticated (ie, not wild)\n\t\telse {\n\t\t\trangy.rangePrototype.insertNodeAtEnd = function (node) {\n\t\t\t\tvar range = this.cloneRange();\n\t\t\t\trange.collapse(false);\n\t\t\t\trange.insertNode(node);\n\t\t\t\trange.detach();\n\t\t\t\tthis.setEndAfter(node);\n\t\t\t};\n\n\t\t\tMedium.Element.prototype = {\n\t\t\t\t/**\n\t\t\t\t * @methodOf Medium.Element\n\t\t\t\t * @param {Function} [fn]\n\t\t\t\t */\n\t\t\t\tinvoke: function (fn) {\n\t\t\t\t\tif (Medium.activeElement === this.element) {\n\t\t\t\t\t\tif (fn) {\n\t\t\t\t\t\t\tfn.apply(this);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\tattr = this.attributes,\n\t\t\t\t\t\t\ttagName = this.tagName.toLowerCase(),\n\t\t\t\t\t\t\tapplier,\n\t\t\t\t\t\t\tcl;\n\n\t\t\t\t\t\tif (attr.className !== undefined) {\n\t\t\t\t\t\t\tcl = (attr.className.split[' '] || [attr.className]).shift();\n\t\t\t\t\t\t\tdelete attr.className;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcl = 'lasso-noclass';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tapplier = rangy.createClassApplier(cl, {\n\t\t\t\t\t\t\telementTagName: tagName,\n\t\t\t\t\t\t\telementAttributes: this.attributes\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t//this.medium.makeUndoable();\n\n\t\t\t\t\t\tapplier.toggleSelection(w);\n\n\t\t\t\t\t\tif (this.clean) {\n\t\t\t\t\t\t\t//cleanup\n\t\t\t\t\t\t\tthis.medium.html.clean();\n\t\t\t\t\t\t\tthis.medium.html.placeholders();\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t *\n\t\t\t\t * @param {Boolean} clean\n\t\t\t\t * @returns {Medium.Element}\n\t\t\t\t */\n\t\t\t\tsetClean: function (clean) {\n\t\t\t\t\tthis.clean = clean;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tMedium.Injector.prototype = {\n\t\t\t\t/**\n\t\t\t\t * @methodOf Medium.Injector\n\t\t\t\t * @param {String|HtmlElement} htmlRaw\n\t\t\t\t * @returns {HtmlElement}\n\t\t\t\t */\n\t\t\t\tinject: function (htmlRaw) {\n\t\t\t\t\tvar html, isConverted = false;\n\t\t\t\t\tif (typeof htmlRaw === 'string') {\n\t\t\t\t\t\tvar htmlConverter = d.createElement('div');\n\t\t\t\t\t\thtmlConverter.innerHTML = htmlRaw;\n\t\t\t\t\t\thtml = htmlConverter.childNodes;\n\t\t\t\t\t\tisConverted = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thtml = htmlRaw;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.insertHTML('<span id=\"wedge\"></span>');\n\n\t\t\t\t\tvar wedge = d.getElementById('wedge'),\n\t\t\t\t\t\tparent = wedge.parentNode,\n\t\t\t\t\t\ti = 0;\n\t\t\t\t\twedge.removeAttribute('id');\n\n\t\t\t\t\tif (isConverted) {\n\t\t\t\t\t\twhile (i < html.length) {\n\t\t\t\t\t\t\tparent.insertBefore(html[i], wedge);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparent.insertBefore(html, wedge);\n\t\t\t\t\t}\n\t\t\t\t\tparent.removeChild(wedge);\n\t\t\t\t\twedge = null;\n\n\t\t\t\t\treturn html;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * @param {Medium} medium\n\t\t\t * @constructor\n\t\t\t */\n\t\t\tMedium.Undoable = function (medium) {\n\t\t\t\tvar me = this,\n\t\t\t\t\telement = medium.settings.element,\n\t\t\t\t\tutils = medium.utils,\n\t\t\t\t\taddEvent = utils.addEvent,\n\t\t\t\t\tstartValue = element.innerHTML,\n\t\t\t\t\ttimer,\n\t\t\t\t\tstack = new Undo.Stack(),\n\t\t\t\t\tEditCommand = Undo.Command.extend({\n\t\t\t\t\t\tconstructor: function (oldValue, newValue) {\n\t\t\t\t\t\t\tthis.oldValue = oldValue;\n\t\t\t\t\t\t\tthis.newValue = newValue;\n\t\t\t\t\t\t},\n\t\t\t\t\t\texecute: function () {\n\t\t\t\t\t\t},\n\t\t\t\t\t\tundo: function () {\n\t\t\t\t\t\t\telement.innerHTML = this.oldValue;\n\t\t\t\t\t\t\tstartValue = this.oldValue;\n\t\t\t\t\t\t\tmedium.canUndo = stack.canUndo();\n\t\t\t\t\t\t\tmedium.canRedo = stack.canRedo();\n\t\t\t\t\t\t\tmedium.dirty = stack.dirty();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tredo: function () {\n\t\t\t\t\t\t\telement.innerHTML = this.newValue;\n\t\t\t\t\t\t\tmedium.canUndo = stack.canUndo();\n\t\t\t\t\t\t\tmedium.canRedo = stack.canRedo();\n\t\t\t\t\t\t\tmedium.dirty = stack.dirty();\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tmakeUndoable = function () {\n\t\t\t\t\t\tvar newValue = element.innerHTML;\n\t\t\t\t\t\t// ignore meta key presses\n\t\t\t\t\t\tif (newValue != startValue) {\n\n\t\t\t\t\t\t\tif (!me.movingThroughStack) {\n\t\t\t\t\t\t\t\t// this could try and make a diff instead of storing snapshots\n\t\t\t\t\t\t\t\tstack.execute(new EditCommand(startValue, newValue));\n\t\t\t\t\t\t\t\tstartValue = newValue;\n\t\t\t\t\t\t\t\tmedium.dirty = stack.dirty();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tutils.triggerEvent(medium.settings.element, \"change\");\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\tthis.medium = medium;\n\t\t\t\tthis.timer = timer;\n\t\t\t\tthis.stack = stack;\n\t\t\t\tthis.makeUndoable = makeUndoable;\n\t\t\t\tthis.EditCommand = EditCommand;\n\t\t\t\tthis.movingThroughStack = false;\n\n\t\t\t\taddEvent(element, 'keyup', function (e) {\n\t\t\t\t\tif (e.ctrlKey || e.keyCode === key.z) {\n\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// a way too simple algorithm in place of single-character undo\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\ttimer = setTimeout(function () {\n\t\t\t\t\t\tmakeUndoable();\n\t\t\t\t\t\t// check if we need to add the component button\n\t\t\t\t\t\tlasso_editor.addComponentButton();\n\t\t\t\t\t}, 250);\n\t\t\t\t});\n\n\t\t\t\taddEvent(element, 'keydown', function (e) {\n\t\t\t\t\tif (!e.ctrlKey || e.keyCode !== key.z) {\n\t\t\t\t\t\tme.movingThroughStack = false;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tutils.preventDefaultEvent(e);\n\n\t\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\t\tme.movingThroughStack = true;\n\t\t\t\t\t\tstack.canRedo() && stack.redo()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tme.movingThroughStack = true;\n\t\t\t\t\t\tstack.canUndo() && stack.undo();\n\t\t\t\t\t}\n\t\t\t\t\tme.movingThroughStack = false;\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\t//Thank you Tim Down (super uber genius): http://stackoverflow.com/questions/6690752/insert-html-at-caret-in-a-contenteditable-div/6691294#6691294\n\t\tMedium.Injector.prototype.insertHTML = function (html, selectPastedContent) {\n\t\t\tvar sel, range;\n\t\t\tif (window.getSelection) {\n\t\t\t\t// IE9 and non-IE\n\t\t\t\tsel = window.getSelection();\n\t\t\t\tif (sel.getRangeAt && sel.rangeCount) {\n\t\t\t\t\trange = sel.getRangeAt(0);\n\t\t\t\t\trange.deleteContents();\n\n\t\t\t\t\t// Range.createContextualFragment() would be useful here but is\n\t\t\t\t\t// only relatively recently standardized and is not supported in\n\t\t\t\t\t// some browsers (IE9, for one)\n\t\t\t\t\tvar el = d.createElement(\"div\");\n\t\t\t\t\tel.innerHTML = html;\n\t\t\t\t\tvar frag = d.createDocumentFragment(), node, lastNode;\n\t\t\t\t\twhile ((node = el.firstChild)) {\n\t\t\t\t\t\tlastNode = frag.appendChild(node);\n\t\t\t\t\t}\n\t\t\t\t\tvar firstNode = frag.firstChild;\n\t\t\t\t\trange.insertNode(frag);\n\n\t\t\t\t\t// Preserve the selection\n\t\t\t\t\tif (lastNode) {\n\t\t\t\t\t\trange = range.cloneRange();\n\t\t\t\t\t\trange.setStartAfter(lastNode);\n\t\t\t\t\t\tif (selectPastedContent) {\n\t\t\t\t\t\t\trange.setStartBefore(firstNode);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\trange.collapse(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsel.removeAllRanges();\n\t\t\t\t\t\tsel.addRange(range);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ((sel = d.selection) && sel.type != \"Control\") {\n\t\t\t\t// IE < 9\n\t\t\t\tvar originalRange = sel.createRange();\n\t\t\t\toriginalRange.collapse(true);\n\t\t\t\tsel.createRange().pasteHTML(html);\n\t\t\t\tif (selectPastedContent) {\n\t\t\t\t\trange = sel.createRange();\n\t\t\t\t\trange.setEndPoint(\"StartToStart\", originalRange);\n\t\t\t\t\trange.select();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tMedium.Html.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\t/**\n\t\t\t * @methodOf Medium.Html\n\t\t\t * @param {Function} [fn]\n\t\t\t * @param {Boolean} [selectInserted]\n\t\t\t * @returns {HtmlElement}\n\t\t\t */\n\t\t\tinsert: function (fn, selectInserted) {\n\t\t\t\tif (Medium.activeElement === this.element) {\n\t\t\t\t\tif (fn) {\n\t\t\t\t\t\tfn.apply(this);\n\t\t\t\t\t}\n\n\t\t\t\t\tvar inserted = this.injector.inject(this.html, selectInserted);\n\n\t\t\t\t\tif (this.clean) {\n\t\t\t\t\t\t//cleanup\n\t\t\t\t\t\tthis.medium.html.clean();\n\t\t\t\t\t\tthis.medium.html.placeholders();\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.medium.makeUndoable();\n\n\t\t\t\t\treturn inserted;\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @attributeOf {Medium.Injector} Medium.Html\n\t\t\t */\n\t\t\tinjector: new Medium.Injector(),\n\n\t\t\t/**\n\t\t\t * @methodOf Medium.Html\n\t\t\t * @param clean\n\t\t\t * @returns {Medium.Html}\n\t\t\t */\n\t\t\tsetClean: function (clean) {\n\t\t\t\tthis.clean = clean;\n\t\t\t\treturn this;\n\t\t\t}\n\t\t};\n\n\t\tMedium.Utilities = function () {\n\t\t};\n\t\tMedium.Utilities.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\t/*\n\t\t\t * Keyboard Interface events\n\t\t\t */\n\t\t\tisCommand: function (e, fnTrue, fnFalse) {\n\t\t\t\tvar s = this.settings;\n\t\t\t\tif ((s.modifier === 'ctrl' && e.ctrlKey ) ||\n\t\t\t\t\t(s.modifier === 'cmd' && e.metaKey ) ||\n\t\t\t\t\t(s.modifier === 'auto' && (e.ctrlKey || e.metaKey) )\n\t\t\t\t) {\n\t\t\t\t\treturn fnTrue.call();\n\t\t\t\t} else {\n\t\t\t\t\treturn fnFalse.call();\n\t\t\t\t}\n\t\t\t},\n\t\t\tisShift: function (e, fnTrue, fnFalse) {\n\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\treturn fnTrue.call();\n\t\t\t\t} else {\n\t\t\t\t\treturn fnFalse.call();\n\t\t\t\t}\n\t\t\t},\n\t\t\tisModifier: function (e, fn) {\n\t\t\t\tvar cmd = this.settings.modifiers[e.keyCode];\n\t\t\t\tif (cmd) {\n\t\t\t\t\treturn fn.call(null, cmd);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tspecial: (function () {\n\t\t\t\tvar special = {};\n\n\t\t\t\tspecial[key['backspace']] = true;\n\t\t\t\tspecial[key['shift']] = true;\n\t\t\t\tspecial[key['ctrl']] = true;\n\t\t\t\tspecial[key['alt']] = true;\n\t\t\t\tspecial[key['delete']] = true;\n\t\t\t\tspecial[key['cmd']] = true;\n\n\t\t\t\treturn special;\n\t\t\t})(),\n\t\t\tisSpecial: function (e) {\n\n\t\t\t\tif (this.cache.cmd) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn typeof this.special[e.keyCode] !== 'undefined';\n\t\t\t},\n\t\t\tnavigational: (function () {\n\t\t\t\tvar navigational = {};\n\n\t\t\t\tnavigational[key['upArrow']] = true;\n\t\t\t\tnavigational[key['downArrow']] = true;\n\t\t\t\tnavigational[key['leftArrow']] = true;\n\t\t\t\tnavigational[key['rightArrow']] = true;\n\n\t\t\t\treturn navigational;\n\t\t\t})(),\n\t\t\tisNavigational: function (e) {\n\t\t\t\treturn typeof this.navigational[e.keyCode] !== 'undefined';\n\t\t\t},\n\n\t\t\t/*\n\t\t\t * Handle Events\n\t\t\t */\n\t\t\taddEvent: function addEvent(element, eventName, func) {\n\t\t\t\tif (element.addEventListener) {\n\t\t\t\t\telement.addEventListener(eventName, func, false);\n\t\t\t\t} else if (element.attachEvent) {\n\t\t\t\t\telement.attachEvent(\"on\" + eventName, func);\n\t\t\t\t} else {\n\t\t\t\t\telement['on' + eventName] = func;\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tremoveEvent: function removeEvent(element, eventName, func) {\n\t\t\t\tif (element.removeEventListener) {\n\t\t\t\t\telement.removeEventListener(eventName, func, false);\n\t\t\t\t} else if (element.detachEvent) {\n\t\t\t\t\telement.detachEvent(\"on\" + eventName, func);\n\t\t\t\t} else {\n\t\t\t\t\telement['on' + eventName] = null;\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tpreventDefaultEvent: function (e) {\n\t\t\t\tif (e.preventDefault) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t} else {\n\t\t\t\t\te.returnValue = false;\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tstopPropagation: function (e) {\n\t\t\t\te = e || window.event;\n\t\t\t\te.cancelBubble = true;\n\n\t\t\t\tif (e.stopPropagation !== undefined) {\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t}\n\t\t\t},\n\t\t\ttriggerEvent: function (element, eventName) {\n\t\t\t\tvar e;\n\t\t\t\tif (d.createEvent) {\n\t\t\t\t\te = d.createEvent(\"HTMLEvents\");\n\t\t\t\t\te.initEvent(eventName, true, true);\n\t\t\t\t\te.eventName = eventName;\n\t\t\t\t\telement.dispatchEvent(e);\n\t\t\t\t} else {\n\t\t\t\t\te = d.createEventObject();\n\t\t\t\t\telement.fireEvent(\"on\" + eventName, e);\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\tdeepExtend: function (destination, source) {\n\t\t\t\tfor (var property in source) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tsource[property]\n\t\t\t\t\t\t&& source[property].constructor\n\t\t\t\t\t\t&& source[property].constructor === Object\n\t\t\t\t\t) {\n\t\t\t\t\t\tdestination[property] = destination[property] || {};\n\t\t\t\t\t\tthis.deepExtend(destination[property], source[property]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdestination[property] = source[property];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn destination;\n\t\t\t},\n\t\t\t/*\n\t\t\t * This is a Paste Hook. When the user pastes\n\t\t\t * content, this ultimately converts it into\n\t\t\t * plain text before inserting the data.\n\t\t\t */\n\t\t\tpasteHook: function (fn) {\n\t\t\t\t/*var textarea = d.createElement('textarea'),\n\t\t\t\t\tel = this.element,\n\t\t\t\t\texistingValue,\n\t\t\t\t\texistingLength,\n\t\t\t\t\toverallLength,\n\t\t\t\t\ts = this.settings,\n\t\t\t\t\tmedium = this.medium,\n\t\t\t\t\thtml = this.html;\n\n\t\t\t\ttextarea.className = s.cssClasses.pasteHook;\n\n\t\t\t\tel.parentNode.appendChild(textarea);\n\n\t\t\t\t//textarea.focus();\n\n\t\t\t\tif (!wild) {\n\t\t\t\t\tmedium.makeUndoable();\n\t\t\t\t}\n\t\t\t\tsetTimeout(function () {\n\t\t\t\t\tel.focus();\n\t\t\t\t\tif (s.maxLength > 0) {\n\t\t\t\t\t\texistingValue = html.text(el);\n\t\t\t\t\t\texistingLength = existingValue.length;\n\t\t\t\t\t\toverallLength = existingLength + textarea.value.length;\n\t\t\t\t\t\tif (overallLength > existingLength) {\n\t\t\t\t\t\t\ttextarea.value = textarea.value.substring(0, s.maxLength - existingLength);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfn(textarea.value);\n\t\t\t\t\thtml.deleteNode(textarea);\n\t\t\t\t}, 2);*/\n\t\t\t},\n\t\t\tsetupContents: function () {\n\t\t\t\tvar el = this.element,\n\t\t\t\t\tchildren = el.children,\n\t\t\t\t\tchildNodes = el.childNodes,\n\t\t\t\t\tinitialParagraph;\n\n\t\t\t\tif (\n\t\t\t\t\t!this.settings.tags.paragraph\n\t\t\t\t\t|| children.length > 0\n\t\t\t\t\t|| this.settings.mode === Medium.inlineMode\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t//has content, but no children\n\t\t\t\tif (childNodes.length > 0) {\n\t\t\t\t\tinitialParagraph = d.createElement(this.settings.tags.paragraph);\n\t\t\t\t\tif (el.innerHTML.match('^[&]nbsp[;]')) {\n\t\t\t\t\t\tel.innerHTML = el.innerHTML.substring(6, el.innerHTML.length - 1);\n\t\t\t\t\t}\n\t\t\t\t\tinitialParagraph.innerHTML = el.innerHTML;\n\t\t\t\t\tel.innerHTML = '';\n\t\t\t\t\tel.appendChild(initialParagraph);\n\t\t\t\t\tthis.cursor.set(initialParagraph.innerHTML.length, initialParagraph);\n\t\t\t\t} else {\n\t\t\t\t\tinitialParagraph = d.createElement(this.settings.tags.paragraph);\n\t\t\t\t\tinitialParagraph.innerHTML = '&nbsp;';\n\t\t\t\t\tel.appendChild(initialParagraph);\n\t\t\t\t}\n\t\t\t},\n\t\t\ttraverseAll: function (element, options, depth) {\n\t\t\t\tvar children = element.childNodes,\n\t\t\t\t\tlength = children.length,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tnode,\n\t\t\t\t\tdepth = depth || 1;\n\n\t\t\t\toptions = options || {};\n\n\t\t\t\tif (length > 0) {\n\t\t\t\t\tfor (; i < length; i++) {\n\t\t\t\t\t\tnode = children[i];\n\t\t\t\t\t\tswitch (node.nodeType) {\n\t\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\t\tthis.traverseAll(node, options, depth + 1);\n\t\t\t\t\t\t\t\tif (options.element !== undefined) options.element(node, i, depth, element);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\tif (options.fragment !== undefined) options.fragment(node, i, depth, element);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//length may change\n\t\t\t\t\t\tlength = children.length;\n\t\t\t\t\t\t//if length did change, and we are at the last item, this causes infinite recursion, so if we are at the last item, then stop to prevent this\n\t\t\t\t\t\tif (node === element.lastChild) {\n\t\t\t\t\t\t\ti = length;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t};\n\n\t\t/*\n\t\t * Handle Selection Logic\n\t\t */\n\t\tMedium.Selection = function () {\n\t\t};\n\t\tMedium.Selection.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\tsaveSelection: function () {\n\t\t\t\tif (w.getSelection) {\n\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\tif (sel.rangeCount > 0) {\n\t\t\t\t\t\treturn sel.getRangeAt(0);\n\t\t\t\t\t}\n\t\t\t\t} else if (d.selection && d.selection.createRange) { // IE\n\t\t\t\t\treturn d.selection.createRange();\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\n\t\t\trestoreSelection: function (range) {\n\t\t\t\tif (range) {\n\t\t\t\t\tif (w.getSelection) {\n\t\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\t\tsel.removeAllRanges();\n\t\t\t\t\t\tsel.addRange(range);\n\t\t\t\t\t} else if (d.selection && range.select) { // IE\n\t\t\t\t\t\trange.select();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t/*\n\t\t * Handle Cursor Logic\n\t\t */\n\t\tMedium.Cursor = function () {\n\t\t};\n\t\tMedium.Cursor.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\tset: function (pos, el) {\n\t\t\t\tvar range,\n\t\t\t\t\thtml = this.html;\n\n\t\t\t\tif (d.createRange) {\n\t\t\t\t\tvar selection = w.getSelection(),\n\t\t\t\t\t\tlastChild = html.lastChild(),\n\t\t\t\t\t\tlength = html.text(lastChild).length - 1,\n\t\t\t\t\t\ttoModify = el ? el : lastChild,\n\t\t\t\t\t\ttheLength = ((typeof pos !== 'undefined') && (pos !== null) ? pos : length);\n\n\t\t\t\t\trange = d.createRange();\n\t\t\t\t\trange.setStart(toModify, theLength);\n\t\t\t\t\trange.collapse(true);\n\t\t\t\t\tselection.removeAllRanges();\n\t\t\t\t\tselection.addRange(range);\n\t\t\t\t} else {\n\t\t\t\t\trange = d.body.createTextRange();\n\t\t\t\t\trange.moveToElementText(el);\n\t\t\t\t\trange.collapse(false);\n\t\t\t\t\trange.select();\n\t\t\t\t}\n\t\t\t},\n\t\t\tparent: function () {\n\t\t\t\tvar target = null, range;\n\n\t\t\t\tif (w.getSelection) {\n\t\t\t\t\trange = w.getSelection().getRangeAt(0);\n\t\t\t\t\ttarget = range.commonAncestorContainer;\n\n\t\t\t\t\ttarget = (target.nodeType === 1\n\t\t\t\t\t\t? target\n\t\t\t\t\t\t: target.parentNode\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\telse if (d.selection) {\n\t\t\t\t\ttarget = d.selection.createRange().parentElement();\n\t\t\t\t}\n\n\t\t\t\tif (target.tagName == 'SPAN') {\n\t\t\t\t\ttarget = target.parentNode;\n\t\t\t\t}\n\n\t\t\t\treturn target;\n\t\t\t},\n\t\t\tcaretToBeginning: function (el) {\n\t\t\t\tthis.set(0, el);\n\t\t\t},\n\t\t\tcaretToEnd: function (el) {\n\t\t\t\tthis.set(this.html.text(el).length, el);\n\t\t\t}\n\t\t};\n\n\t\t/*\n\t\t * HTML Abstractions\n\t\t */\n\t\tMedium.HtmlAssistant = function () {\n\t\t};\n\t\tMedium.HtmlAssistant.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\tencodeHtml: function (html) {\n\t\t\t\treturn d.createElement('a').appendChild(\n\t\t\t\t\td.createTextNode(html)).parentNode.innerHTML;\n\t\t\t},\n\t\t\ttext: function (node, val) {\n\t\t\t\tnode = node || this.settings.element;\n\t\t\t\tif (val) {\n\t\t\t\t\tif ((node.textContent) && (typeof (node.textContent) != \"undefined\")) {\n\t\t\t\t\t\tnode.textContent = val;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.innerText = val;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telse if (node.innerText) {\n\t\t\t\t\treturn trim(node.innerText);\n\t\t\t\t}\n\n\t\t\t\telse if (node.textContent) {\n\t\t\t\t\treturn trim(node.textContent);\n\t\t\t\t}\n\t\t\t\t//document fragment\n\t\t\t\telse if (node.data) {\n\t\t\t\t\treturn trim(node.data);\n\t\t\t\t}\n\n\t\t\t\t//for good measure\n\t\t\t\treturn '';\n\t\t\t},\n\t\t\tchangeTag: function (oldNode, newTag) {\n\t\t\t\tvar newNode = d.createElement(newTag),\n\t\t\t\t\tnode,\n\t\t\t\t\tnextNode;\n\n\t\t\t\tnode = oldNode.firstChild;\n\t\t\t\twhile (node) {\n\t\t\t\t\tnextNode = node.nextSibling;\n\t\t\t\t\tnewNode.appendChild(node);\n\t\t\t\t\tnode = nextNode;\n\t\t\t\t}\n\n\t\t\t\toldNode.parentNode.insertBefore(newNode, oldNode);\n\t\t\t\toldNode.parentNode.removeChild(oldNode);\n\n\t\t\t\treturn newNode;\n\t\t\t},\n\t\t\tdeleteNode: function (el) {\n\t\t\t\tel.parentNode.removeChild(el);\n\t\t\t},\n\t\t\tplaceholders: function () {\n\t\t\t\t//in IE8, just gracefully degrade to no placeholders\n\t\t\t\tif (!w.getComputedStyle) return;\n\n\t\t\t\tvar that = this,\n\t\t\t\t\ts = this.settings,\n\t\t\t\t\tplaceholder = this.medium.placeholder || (this.medium.placeholder = d.createElement('div')),\n\t\t\t\t\tel = s.element,\n\t\t\t\t\tstyle = placeholder.style,\n\t\t\t\t\telStyle = w.getComputedStyle(el, null),\n\t\t\t\t\tqStyle = function (prop) {\n\t\t\t\t\t\treturn elStyle.getPropertyValue(prop)\n\t\t\t\t\t},\n\t\t\t\t\tutils = this.utils,\n\t\t\t\t\ttext = utils.html.text(el),\n\t\t\t\t\tcursor = this.cursor,\n\t\t\t\t\tchildCount = el.children.length;\n\n\t\t\t\tel.placeholder = placeholder;\n\n\t\t\t\t// Empty Editor\n\t\t\t\tif (text.length < 1 && childCount < 2) {\n                    //the behavior when the editable content becomes empty.\n                    //simplified from the previous version\n\t\t\t\t\tel.innerHTML = '<p><br></p>';\n                 \n\t\t\t\t\t/*if (el.placeHolderActive) return;\n\n\t\t\t\t\tif (!el.innerHTML.match('<' + s.tags.paragraph)) {\n\t\t\t\t\t\tel.innerHTML = '';\n\t\t\t\t\t}\n\n\t\t\t\t\t// We need to add placeholders\n\t\t\t\t\tif (s.placeholder.length > 0) {\n\t\t\t\t\t\tif (!placeholder.setup) {\n\t\t\t\t\t\t\tplaceholder.setup = true;\n\n\t\t\t\t\t\t\t//background & background color\n\t\t\t\t\t\t\tstyle.background = qStyle('background');\n\t\t\t\t\t\t\tstyle.backgroundColor = qStyle('background-color');\n\n\t\t\t\t\t\t\t//text size & text color\n\t\t\t\t\t\t\tstyle.fontSize = qStyle('font-size');\n\t\t\t\t\t\t\tstyle.color = elStyle.color;\n\n\t\t\t\t\t\t\t//begin box-model\n\t\t\t\t\t\t\t//margin\n\t\t\t\t\t\t\tstyle.marginTop = qStyle('margin-top');\n\t\t\t\t\t\t\tstyle.marginBottom = qStyle('margin-bottom');\n\t\t\t\t\t\t\tstyle.marginLeft = qStyle('margin-left');\n\t\t\t\t\t\t\tstyle.marginRight = qStyle('margin-right');\n\n\t\t\t\t\t\t\t//padding\n\t\t\t\t\t\t\tstyle.paddingTop = qStyle('padding-top');\n\t\t\t\t\t\t\tstyle.paddingBottom = qStyle('padding-bottom');\n\t\t\t\t\t\t\tstyle.paddingLeft = qStyle('padding-left');\n\t\t\t\t\t\t\tstyle.paddingRight = qStyle('padding-right');\n\n\t\t\t\t\t\t\t//border\n\t\t\t\t\t\t\tstyle.borderTopWidth = qStyle('border-top-width');\n\t\t\t\t\t\t\tstyle.borderTopColor = qStyle('border-top-color');\n\t\t\t\t\t\t\tstyle.borderTopStyle = qStyle('border-top-style');\n\t\t\t\t\t\t\tstyle.borderBottomWidth = qStyle('border-bottom-width');\n\t\t\t\t\t\t\tstyle.borderBottomColor = qStyle('border-bottom-color');\n\t\t\t\t\t\t\tstyle.borderBottomStyle = qStyle('border-bottom-style');\n\t\t\t\t\t\t\tstyle.borderLeftWidth = qStyle('border-left-width');\n\t\t\t\t\t\t\tstyle.borderLeftColor = qStyle('border-left-color');\n\t\t\t\t\t\t\tstyle.borderLeftStyle = qStyle('border-left-style');\n\t\t\t\t\t\t\tstyle.borderRightWidth = qStyle('border-right-width');\n\t\t\t\t\t\t\tstyle.borderRightColor = qStyle('border-right-color');\n\t\t\t\t\t\t\tstyle.borderRightStyle = qStyle('border-right-style');\n\t\t\t\t\t\t\t//end box model\n\n\t\t\t\t\t\t\t//element setup\n\t\t\t\t\t\t\tplaceholder.className = s.cssClasses.placeholder + ' ' + s.cssClasses.placeholder + '-' + s.mode;\n\t\t\t\t\t\t\tplaceholder.innerHTML = '<div>' + s.placeholder + '</div>';\n\t\t\t\t\t\t\tel.parentNode.insertBefore(placeholder, el);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tel.className += ' ' + s.cssClasses.clear;\n\n\t\t\t\t\t\tstyle.display = '';\n\t\t\t\t\t\t// Add base P tag and do auto focus, give it a min height if el has one\n\t\t\t\t\t\tstyle.minHeight = el.clientHeight + 'px';\n\t\t\t\t\t\tstyle.minWidth = el.clientWidth + 'px';\n\n\t\t\t\t\t\tif (s.mode !== Medium.inlineMode) {\n\t\t\t\t\t\t\tutils.setupContents();\n\n\t\t\t\t\t\t\tif (childCount === 0 && el.firstChild) {\n\t\t\t\t\t\t\t\tcursor.set(0, el.firstChild);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tel.placeHolderActive = true;*/\n\t\t\t\t} else if (el.placeHolderActive) {\n\t\t\t\t\tel.placeHolderActive = false;\n\t\t\t\t\tstyle.display = 'none';\n\t\t\t\t\tel.className = trim(el.className.replace(s.cssClasses.clear, ''));\n\t\t\t\t\tutils.setupContents();\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Cleans element\n\t\t\t * @param {HtmlElement} [el] default is settings.element\n\t\t\t */\n\t\t\tclean: function (el) {\n\n\t\t\t\t/*\n\t\t\t\t * Deletes invalid nodes\n\t\t\t\t * Removes Attributes\n\t\t\t\t */\n\t\t\t\tvar s = this.settings,\n\t\t\t\t\tplaceholderClass = s.cssClasses.placeholder,\n\t\t\t\t\tattributesToRemove = (s.attributes || {}).remove || [],\n\t\t\t\t\ttags = s.tags || {},\n\t\t\t\t\tonlyOuter = tags.outerLevel || null,\n\t\t\t\t\tonlyInner = tags.innerLevel || null,\n\t\t\t\t\touterSwitch = {},\n\t\t\t\t\tinnerSwitch = {},\n\t\t\t\t\tparagraphTag = (tags.paragraph || '').toUpperCase(),\n\t\t\t\t\thtml = this.html,\n\t\t\t\t\tattr,\n\t\t\t\t\ttext,\n\t\t\t\t\tj;\n\n\t\t\t\tel = el || s.element;\n\n\t\t\t\tif (onlyOuter !== null) {\n\t\t\t\t\tfor (j = 0; j < onlyOuter.length; j++) {\n\t\t\t\t\t\touterSwitch[onlyOuter[j].toUpperCase()] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (onlyInner !== null) {\n\t\t\t\t\tfor (j = 0; j < onlyInner.length; j++) {\n\t\t\t\t\t\tinnerSwitch[onlyInner[j].toUpperCase()] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.utils.traverseAll(el, {\n\t\t\t\t\telement: function (child, i, depth, parent) {\n\t\t\t\t\t\tvar nodeName = child.nodeName,\n\t\t\t\t\t\t\tshouldDelete = true;\n\n\t\t\t\t\t\t// Remove attributes\n\t\t\t\t\t\tfor (j = 0; j < attributesToRemove.length; j++) {\n\t\t\t\t\t\t\tattr = attributesToRemove[j];\n\t\t\t\t\t\t\tif (child.hasAttribute(attr)) {\n\t\t\t\t\t\t\t\tif (child.getAttribute(attr) !== placeholderClass) {\n\t\t\t\t\t\t\t\t\tchild.removeAttribute(attr);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (onlyOuter === null && onlyInner === null) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (depth === 1 && outerSwitch[nodeName] !== undefined) {\n\t\t\t\t\t\t\tshouldDelete = false;\n\t\t\t\t\t\t} else if (depth > 1 && innerSwitch[nodeName] !== undefined) {\n\t\t\t\t\t\t\tshouldDelete = false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Convert tags or delete\n\t\t\t\t\t\tif (shouldDelete) {\n\t\t\t\t\t\t\tif (w.getComputedStyle(child, null).getPropertyValue('display') === 'block') {\n\t\t\t\t\t\t\t\tif (paragraphTag.length > 0 && paragraphTag !== nodeName) {\n\t\t\t\t\t\t\t\t\thtml.changeTag(child, paragraphTag);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (depth > 1) {\n\t\t\t\t\t\t\t\t\twhile (parent.childNodes.length > i) {\n\t\t\t\t\t\t\t\t\t\tparent.parentNode.insertBefore(parent.lastChild, parent.nextSibling);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tswitch (nodeName) {\n\t\t\t\t\t\t\t\t\tcase 'BR':\n\t\t\t\t\t\t\t\t\t\tif (child === child.parentNode.lastChild) {\n\t\t\t\t\t\t\t\t\t\t\tif (child === child.parentNode.firstChild) {\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\ttext = document.createTextNode(\"\");\n\t\t\t\t\t\t\t\t\t\t\ttext.innerHTML = '&nbsp';\n\t\t\t\t\t\t\t\t\t\t\tparent.insertBefore(text, child);\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\twhile (child.firstChild !== null) {\n\t\t\t\t\t\t\t\t\t\t\tparent.insertBefore(child.firstChild, child);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\thtml.deleteNode(child);\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tlastChild: function () {\n\t\t\t\treturn this.element.lastChild;\n\t\t\t},\n\t\t\taddTag: function (tag, shouldFocus, isEditable, afterElement) {\n\t\t\t\tif (!this.settings.beforeAddTag(tag, shouldFocus, isEditable, afterElement)) {\n\t\t\t\t\tvar newEl = d.createElement(tag),\n\t\t\t\t\t\ttoFocus;\n\n\t\t\t\t\tif (typeof isEditable !== \"undefined\" && isEditable === false) {\n\t\t\t\t\t\tnewEl.contentEditable = false;\n\t\t\t\t\t}\n\t\t\t\t\tif (newEl.innerHTML.length == 0) {\n\t\t\t\t\t\tnewEl.innerHTML = ' ';\n\t\t\t\t\t}\n\t\t\t\t\tif (afterElement && afterElement.nextSibling) {\n\t\t\t\t\t\tafterElement.parentNode.insertBefore(newEl, afterElement.nextSibling);\n\t\t\t\t\t\ttoFocus = afterElement.nextSibling;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.settings.element.appendChild(newEl);\n\t\t\t\t\t\ttoFocus = this.html.lastChild();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (shouldFocus) {\n\t\t\t\t\t\tthis.cache.focusedElement = toFocus;\n\t\t\t\t\t\tthis.cursor.set(0, toFocus);\n\t\t\t\t\t}\n\t\t\t\t\treturn newEl;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\tbaseAtCaret: function () {\n\t\t\t\tif (!this.medium.isActive()) return null;\n\n\t\t\t\tvar sel = w.getSelection ? w.getSelection() : document.selection;\n\n\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\tvar selRange = sel.getRangeAt(0),\n\t\t\t\t\t\tcontainer = selRange.endContainer;\n\n\t\t\t\t\tswitch (container.nodeType) {\n\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\tif (container.data && container.data.length != selRange.endOffset) return false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn container;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\tgetTopLevel: function (container) {\n\t\t\t\twhile (container && container.parentNode !== this.element) {\n\t\t\t\t\tcontainer = container.parentNode;\n\t\t\t\t}\n\t\t\t\treturn container;\n\t\t\t},\n\t\t\tatCaret: function () {\n\t\t\t\tvar container = this.baseAtCaret() || {},\n\t\t\t\t\tel = this.element;\n\n\t\t\t\tif (container === false) return null;\n\n\t\t\t\tcontainer = this.getTopLevel(container);\n\t\t\t\t//while (container && container.parentNode !== el) {\n\t\t\t\t//\tcontainer = container.parentNode;\n\t\t\t\t//}\n\n\t\t\t\tif (container && container.nodeType == 1) {\n\t\t\t\t\treturn container;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttextElementsAtCaret: function () {\n\t\t\t\tif (!this.medium.isActive()) return null;\n\n\t\t\t\tvar sel = w.getSelection ? w.getSelection() : document.selection;\n\n\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\tvar selRange = sel.getRangeAt(0),\n\t\t\t\t\t\t//container = selRange.endContainer;\n\t\t\t\t\t\tcontainerStart = this.getTopLevel(selRange.startContainer),\n\t\t\t\t\t\tcontainerEnd = this.getTopLevel(selRange.endContainer);\n\n\t\t\t\t\tvar arr = [];\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tif (containerStart.nodeType ==1) { \n\t\t\t\t\t\t    arr.push(containerStart);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (containerStart === containerEnd || !containerStart.nextElementSibling) break;\n                        containerStart = containerStart.nextElementSibling;\t\t\t\t\t\n\t\t\t\t\t};\n\t\t\t\t\t\n\t\t\t\t\t//while (containerStart && containerStart.parentNode !== this.element) {\n\t\t\t\t\t//\tcontainerStart = containerStart.parentNode;\n\t\t\t\t\t//}\n\t\t\t\t\t\n\n\t\t\t\t\treturn arr;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t};\n\n\t\tMedium.Action = function () {\n\t\t};\n\t\tMedium.Action.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\tlisten: function () {\n\t\t\t\tvar el = this.element,\n\t\t\t\t\tintercept = this.intercept;\n\n\t\t\t\tthis.utils\n\t\t\t\t\t.addEvent(el, 'keyup', intercept.up)\n\t\t\t\t\t.addEvent(el, 'keydown', intercept.down)\n\t\t\t\t\t.addEvent(el, 'focus', intercept.focus)\n\t\t\t\t\t.addEvent(el, 'blur', intercept.blur)\n\t\t\t\t\t.addEvent(el, 'paste', this.settings.pasteEventHandler);\n\t\t\t},\n\t\t\tpreserveElementFocus: function () {\n\t\t\t\t// Fetch node that has focus\n\t\t\t\tvar anchorNode = w.getSelection ? w.getSelection().anchorNode : d.activeElement;\n\t\t\t\tif (anchorNode) {\n\t\t\t\t\tvar cache = this.medium.cache,\n\t\t\t\t\t\ts = this.settings,\n\t\t\t\t\t\tcur = anchorNode.parentNode,\n\t\t\t\t\t\tchildren = s.element.children,\n\t\t\t\t\t\tdiff = cur !== cache.focusedElement,\n\t\t\t\t\t\telementIndex = 0,\n\t\t\t\t\t\ti;\n\n\t\t\t\t\t// anchorNode is our target if element is empty\n\t\t\t\t\tif (cur === s.element) {\n\t\t\t\t\t\tcur = anchorNode;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Find our child index\n\t\t\t\t\tfor (i = 0; i < children.length; i++) {\n\t\t\t\t\t\tif (cur === children[i]) {\n\t\t\t\t\t\t\telementIndex = i;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Focused element is different\n\t\t\t\t\tif (diff) {\n\t\t\t\t\t\tcache.focusedElement = cur;\n\t\t\t\t\t\tcache.focusedElementIndex = elementIndex;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tMedium.Cache = function () {\n\t\t\tthis.initialized = false;\n\t\t\tthis.cmd = false;\n\t\t\tthis.focusedElement = null\n\t\t};\n\t\tMedium.Cache.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t//Modes;\n\t\tMedium.inlineMode = 'inline';\n\t\tMedium.partialMode = 'partial';\n\t\tMedium.richMode = 'rich';\n\t\tMedium.Messages = {\n\t\t\tpastHere: 'Paste Here'\n\t\t};\n\n\t\treturn Medium;\n\t}());\n\n\tif (typeof define === 'function' && define['amd']) {\n\t\tdefine(function () { return Medium; });\n\t} else if (typeof module !== 'undefined' && module.exports) {\n\t\tmodule.exports = Medium;\n\t} else if (typeof this !== 'undefined') {\n\t\tthis.Medium = Medium;\n\t}\n\n}).call(this, window, document);\n\n/* Copyright (c) 2012, 2014 Hyunje Alex Jun and other contributors\n * Licensed under the MIT License\n */\n(function (factory) {\n  'use strict';\n\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS\n    factory(require('jquery'));\n  } else {\n    // Browser globals\n    factory(jQuery);\n  }\n})(function ($) {\n  'use strict';\n\n  function getInt(x) {\n    if (typeof x === 'string') {\n      return parseInt(x, 10);\n    } else {\n      return ~~x;\n    }\n  }\n\n  var defaultSettings = {\n    wheelSpeed: 1,\n    wheelPropagation: false,\n    swipePropagation: true,\n    minScrollbarLength: null,\n    maxScrollbarLength: null,\n    useBothWheelAxes: false,\n    useKeyboard: true,\n    suppressScrollX: false,\n    suppressScrollY: false,\n    scrollXMarginOffset: 0,\n    scrollYMarginOffset: 0,\n    includePadding: false\n  };\n\n  var incrementingId = 0;\n  var eventClassFactory = function () {\n    var id = incrementingId++;\n    return function (eventName) {\n      var className = '.perfect-scrollbar-' + id;\n      if (typeof eventName === 'undefined') {\n        return className;\n      } else {\n        return eventName + className;\n      }\n    };\n  };\n\n  var isWebkit = 'WebkitAppearance' in document.documentElement.style;\n\n  $.fn.perfectScrollbar = function (suppliedSettings, option) {\n\n    return this.each(function () {\n      var settings = $.extend(true, {}, defaultSettings);\n      var $this = $(this);\n      var isPluginAlive = function () { return !!$this; };\n\n      if (typeof suppliedSettings === \"object\") {\n        // Override default settings with any supplied\n        $.extend(true, settings, suppliedSettings);\n      } else {\n        // If no setting was supplied, then the first param must be the option\n        option = suppliedSettings;\n      }\n\n      // Catch options\n      if (option === 'update') {\n        if ($this.data('perfect-scrollbar-update')) {\n          $this.data('perfect-scrollbar-update')();\n        }\n        return $this;\n      }\n      else if (option === 'destroy') {\n        if ($this.data('perfect-scrollbar-destroy')) {\n          $this.data('perfect-scrollbar-destroy')();\n        }\n        return $this;\n      }\n\n      if ($this.data('perfect-scrollbar')) {\n        // if there's already perfect-scrollbar\n        return $this.data('perfect-scrollbar');\n      }\n\n\n      // Or generate new perfectScrollbar\n\n      $this.addClass('ps-container');\n\n      var containerWidth;\n      var containerHeight;\n      var contentWidth;\n      var contentHeight;\n\n      var isRtl = $this.css('direction') === \"rtl\";\n      var eventClass = eventClassFactory();\n      var ownerDocument = this.ownerDocument || document;\n\n      var $scrollbarXRail = $(\"<div class='ps-scrollbar-x-rail'>\").appendTo($this);\n      var $scrollbarX = $(\"<div class='ps-scrollbar-x'>\").appendTo($scrollbarXRail);\n      var scrollbarXActive;\n      var scrollbarXWidth;\n      var scrollbarXLeft;\n      var scrollbarXBottom = getInt($scrollbarXRail.css('bottom'));\n      var isScrollbarXUsingBottom = scrollbarXBottom === scrollbarXBottom; // !isNaN\n      var scrollbarXTop = isScrollbarXUsingBottom ? null : getInt($scrollbarXRail.css('top'));\n      var railBorderXWidth = getInt($scrollbarXRail.css('borderLeftWidth')) + getInt($scrollbarXRail.css('borderRightWidth'));\n      var railXMarginWidth = getInt($scrollbarXRail.css('marginLeft')) + getInt($scrollbarXRail.css('marginRight'));\n      var railXWidth;\n\n      var $scrollbarYRail = $(\"<div class='ps-scrollbar-y-rail'>\").appendTo($this);\n      var $scrollbarY = $(\"<div class='ps-scrollbar-y'>\").appendTo($scrollbarYRail);\n      var scrollbarYActive;\n      var scrollbarYHeight;\n      var scrollbarYTop;\n      var scrollbarYRight = getInt($scrollbarYRail.css('right'));\n      var isScrollbarYUsingRight = scrollbarYRight === scrollbarYRight; // !isNaN\n      var scrollbarYLeft = isScrollbarYUsingRight ? null : getInt($scrollbarYRail.css('left'));\n      var railBorderYWidth = getInt($scrollbarYRail.css('borderTopWidth')) + getInt($scrollbarYRail.css('borderBottomWidth'));\n      var railYMarginHeight = getInt($scrollbarYRail.css('marginTop')) + getInt($scrollbarYRail.css('marginBottom'));\n      var railYHeight;\n\n      function updateScrollTop(currentTop, deltaY) {\n        var newTop = currentTop + deltaY;\n        var maxTop = containerHeight - scrollbarYHeight;\n\n        if (newTop < 0) {\n          scrollbarYTop = 0;\n        } else if (newTop > maxTop) {\n          scrollbarYTop = maxTop;\n        } else {\n          scrollbarYTop = newTop;\n        }\n\n        var scrollTop = getInt(scrollbarYTop * (contentHeight - containerHeight) / (containerHeight - scrollbarYHeight));\n        $this.scrollTop(scrollTop);\n      }\n\n      function updateScrollLeft(currentLeft, deltaX) {\n        var newLeft = currentLeft + deltaX;\n        var maxLeft = containerWidth - scrollbarXWidth;\n\n        if (newLeft < 0) {\n          scrollbarXLeft = 0;\n        } else if (newLeft > maxLeft) {\n          scrollbarXLeft = maxLeft;\n        } else {\n          scrollbarXLeft = newLeft;\n        }\n\n        var scrollLeft = getInt(scrollbarXLeft * (contentWidth - containerWidth) / (containerWidth - scrollbarXWidth));\n        $this.scrollLeft(scrollLeft);\n      }\n\n      function getThumbSize(thumbSize) {\n        if (settings.minScrollbarLength) {\n          thumbSize = Math.max(thumbSize, settings.minScrollbarLength);\n        }\n        if (settings.maxScrollbarLength) {\n          thumbSize = Math.min(thumbSize, settings.maxScrollbarLength);\n        }\n        return thumbSize;\n      }\n\n      function updateCss() {\n        var xRailOffset = {width: railXWidth};\n        if (isRtl) {\n          xRailOffset.left = $this.scrollLeft() + containerWidth - contentWidth;\n        } else {\n          xRailOffset.left = $this.scrollLeft();\n        }\n        if (isScrollbarXUsingBottom) {\n          xRailOffset.bottom = scrollbarXBottom - $this.scrollTop();\n        } else {\n          xRailOffset.top = scrollbarXTop + $this.scrollTop();\n        }\n        $scrollbarXRail.css(xRailOffset);\n\n        var railYOffset = {top: $this.scrollTop(), height: railYHeight};\n\n        if (isScrollbarYUsingRight) {\n          if (isRtl) {\n            railYOffset.right = contentWidth - $this.scrollLeft() - scrollbarYRight - $scrollbarY.outerWidth();\n          } else {\n            railYOffset.right = scrollbarYRight - $this.scrollLeft();\n          }\n        } else {\n          if (isRtl) {\n            railYOffset.left = $this.scrollLeft() + containerWidth * 2 - contentWidth - scrollbarYLeft - $scrollbarY.outerWidth();\n          } else {\n            railYOffset.left = scrollbarYLeft + $this.scrollLeft();\n          }\n        }\n        $scrollbarYRail.css(railYOffset);\n\n        $scrollbarX.css({left: scrollbarXLeft, width: scrollbarXWidth - railBorderXWidth});\n        $scrollbarY.css({top: scrollbarYTop, height: scrollbarYHeight - railBorderYWidth});\n      }\n\n      function updateGeometry() {\n        // Hide scrollbars not to affect scrollWidth and scrollHeight\n        $this.removeClass('ps-active-x');\n        $this.removeClass('ps-active-y');\n\n        containerWidth = settings.includePadding ? $this.innerWidth() : $this.width();\n        containerHeight = settings.includePadding ? $this.innerHeight() : $this.height();\n        contentWidth = $this.prop('scrollWidth');\n        contentHeight = $this.prop('scrollHeight');\n\n        if (!settings.suppressScrollX && containerWidth + settings.scrollXMarginOffset < contentWidth) {\n          scrollbarXActive = true;\n          railXWidth = containerWidth - railXMarginWidth;\n          scrollbarXWidth = getThumbSize(getInt(railXWidth * containerWidth / contentWidth));\n          scrollbarXLeft = getInt($this.scrollLeft() * (railXWidth - scrollbarXWidth) / (contentWidth - containerWidth));\n        } else {\n          scrollbarXActive = false;\n          scrollbarXWidth = 0;\n          scrollbarXLeft = 0;\n          $this.scrollLeft(0);\n        }\n\n        if (!settings.suppressScrollY && containerHeight + settings.scrollYMarginOffset < contentHeight) {\n          scrollbarYActive = true;\n          railYHeight = containerHeight - railYMarginHeight;\n          scrollbarYHeight = getThumbSize(getInt(railYHeight * containerHeight / contentHeight));\n          scrollbarYTop = getInt($this.scrollTop() * (railYHeight - scrollbarYHeight) / (contentHeight - containerHeight));\n        } else {\n          scrollbarYActive = false;\n          scrollbarYHeight = 0;\n          scrollbarYTop = 0;\n          $this.scrollTop(0);\n        }\n\n        if (scrollbarXLeft >= railXWidth - scrollbarXWidth) {\n          scrollbarXLeft = railXWidth - scrollbarXWidth;\n        }\n        if (scrollbarYTop >= railYHeight - scrollbarYHeight) {\n          scrollbarYTop = railYHeight - scrollbarYHeight;\n        }\n\n        updateCss();\n\n        if (scrollbarXActive) {\n          $this.addClass('ps-active-x');\n        }\n        if (scrollbarYActive) {\n          $this.addClass('ps-active-y');\n        }\n      }\n\n      function bindMouseScrollXHandler() {\n        var currentLeft;\n        var currentPageX;\n\n        var mouseMoveHandler = function (e) {\n          updateScrollLeft(currentLeft, e.pageX - currentPageX);\n          updateGeometry();\n          e.stopPropagation();\n          e.preventDefault();\n        };\n\n        var mouseUpHandler = function (e) {\n          $scrollbarXRail.removeClass('in-scrolling');\n          $(ownerDocument).unbind(eventClass('mousemove'), mouseMoveHandler);\n        };\n\n        $scrollbarX.bind(eventClass('mousedown'), function (e) {\n          currentPageX = e.pageX;\n          currentLeft = $scrollbarX.position().left;\n          $scrollbarXRail.addClass('in-scrolling');\n\n          $(ownerDocument).bind(eventClass('mousemove'), mouseMoveHandler);\n          $(ownerDocument).one(eventClass('mouseup'), mouseUpHandler);\n\n          e.stopPropagation();\n          e.preventDefault();\n        });\n\n        currentLeft =\n        currentPageX = null;\n      }\n\n      function bindMouseScrollYHandler() {\n        var currentTop;\n        var currentPageY;\n\n        var mouseMoveHandler = function (e) {\n          updateScrollTop(currentTop, e.pageY - currentPageY);\n          updateGeometry();\n          e.stopPropagation();\n          e.preventDefault();\n        };\n\n        var mouseUpHandler = function (e) {\n          $scrollbarYRail.removeClass('in-scrolling');\n          $(ownerDocument).unbind(eventClass('mousemove'), mouseMoveHandler);\n        };\n\n        $scrollbarY.bind(eventClass('mousedown'), function (e) {\n          currentPageY = e.pageY;\n          currentTop = $scrollbarY.position().top;\n          $scrollbarYRail.addClass('in-scrolling');\n\n          $(ownerDocument).bind(eventClass('mousemove'), mouseMoveHandler);\n          $(ownerDocument).one(eventClass('mouseup'), mouseUpHandler);\n\n          e.stopPropagation();\n          e.preventDefault();\n        });\n\n        currentTop =\n        currentPageY = null;\n      }\n\n      function shouldPreventWheel(deltaX, deltaY) {\n        var scrollTop = $this.scrollTop();\n        if (deltaX === 0) {\n          if (!scrollbarYActive) {\n            return false;\n          }\n          if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= contentHeight - containerHeight && deltaY < 0)) {\n            return !settings.wheelPropagation;\n          }\n        }\n\n        var scrollLeft = $this.scrollLeft();\n        if (deltaY === 0) {\n          if (!scrollbarXActive) {\n            return false;\n          }\n          if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= contentWidth - containerWidth && deltaX > 0)) {\n            return !settings.wheelPropagation;\n          }\n        }\n        return true;\n      }\n\n      function shouldPreventSwipe(deltaX, deltaY) {\n        var scrollTop = $this.scrollTop();\n        var scrollLeft = $this.scrollLeft();\n        var magnitudeX = Math.abs(deltaX);\n        var magnitudeY = Math.abs(deltaY);\n\n        if (magnitudeY > magnitudeX) {\n          // user is perhaps trying to swipe up/down the page\n\n          if (((deltaY < 0) && (scrollTop === contentHeight - containerHeight)) ||\n              ((deltaY > 0) && (scrollTop === 0))) {\n            return !settings.swipePropagation;\n          }\n        } else if (magnitudeX > magnitudeY) {\n          // user is perhaps trying to swipe left/right across the page\n\n          if (((deltaX < 0) && (scrollLeft === contentWidth - containerWidth)) ||\n              ((deltaX > 0) && (scrollLeft === 0))) {\n            return !settings.swipePropagation;\n          }\n        }\n\n        return true;\n      }\n\n      function bindMouseWheelHandler() {\n        var shouldPrevent = false;\n\n        function getDeltaFromEvent(e) {\n          var deltaX = e.originalEvent.deltaX;\n          var deltaY = -1 * e.originalEvent.deltaY;\n\n          if (typeof deltaX === \"undefined\" || typeof deltaY === \"undefined\") {\n            // OS X Safari\n            deltaX = -1 * e.originalEvent.wheelDeltaX / 6;\n            deltaY = e.originalEvent.wheelDeltaY / 6;\n          }\n\n          if (e.originalEvent.deltaMode && e.originalEvent.deltaMode === 1) {\n            // Firefox in deltaMode 1: Line scrolling\n            deltaX *= 10;\n            deltaY *= 10;\n          }\n\n          if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {\n            // IE in some mouse drivers\n            deltaX = 0;\n            deltaY = e.originalEvent.wheelDelta;\n          }\n\n          return [deltaX, deltaY];\n        }\n\n        function mousewheelHandler(e) {\n          // FIXME: this is a quick fix for the select problem in FF and IE.\n          // If there comes an effective way to deal with the problem,\n          // this lines should be removed.\n          if (!isWebkit && $this.find('select:focus').length > 0) {\n            return;\n          }\n\n          var delta = getDeltaFromEvent(e);\n\n          var deltaX = delta[0];\n          var deltaY = delta[1];\n\n          shouldPrevent = false;\n          if (!settings.useBothWheelAxes) {\n            // deltaX will only be used for horizontal scrolling and deltaY will\n            // only be used for vertical scrolling - this is the default\n            $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));\n            $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));\n          } else if (scrollbarYActive && !scrollbarXActive) {\n            // only vertical scrollbar is active and useBothWheelAxes option is\n            // active, so let's scroll vertical bar using both mouse wheel axes\n            if (deltaY) {\n              $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));\n            } else {\n              $this.scrollTop($this.scrollTop() + (deltaX * settings.wheelSpeed));\n            }\n            shouldPrevent = true;\n          } else if (scrollbarXActive && !scrollbarYActive) {\n            // useBothWheelAxes and only horizontal bar is active, so use both\n            // wheel axes for horizontal bar\n            if (deltaX) {\n              $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));\n            } else {\n              $this.scrollLeft($this.scrollLeft() - (deltaY * settings.wheelSpeed));\n            }\n            shouldPrevent = true;\n          }\n\n          updateGeometry();\n\n          shouldPrevent = (shouldPrevent || shouldPreventWheel(deltaX, deltaY));\n          if (shouldPrevent) {\n            e.stopPropagation();\n            e.preventDefault();\n          }\n        }\n\n        if (typeof window.onwheel !== \"undefined\") {\n          $this.bind(eventClass('wheel'), mousewheelHandler);\n        } else if (typeof window.onmousewheel !== \"undefined\") {\n          $this.bind(eventClass('mousewheel'), mousewheelHandler);\n        }\n      }\n\n      function bindKeyboardHandler() {\n        var hovered = false;\n        $this.bind(eventClass('mouseenter'), function (e) {\n          hovered = true;\n        });\n        $this.bind(eventClass('mouseleave'), function (e) {\n          hovered = false;\n        });\n\n        var shouldPrevent = false;\n        $(ownerDocument).bind(eventClass('keydown'), function (e) {\n          if (e.isDefaultPrevented && e.isDefaultPrevented()) {\n            return;\n          }\n\n          if (!hovered) {\n            return;\n          }\n\n          var activeElement = document.activeElement ? document.activeElement : ownerDocument.activeElement;\n          // go deeper if element is a webcomponent\n          while (activeElement.shadowRoot) {\n            activeElement = activeElement.shadowRoot.activeElement;\n          }\n          if ($(activeElement).is(\":input,[contenteditable]\")) {\n            return;\n          }\n\n          var deltaX = 0;\n          var deltaY = 0;\n\n          switch (e.which) {\n          case 37: // left\n            deltaX = -30;\n            break;\n          case 38: // up\n            deltaY = 30;\n            break;\n          case 39: // right\n            deltaX = 30;\n            break;\n          case 40: // down\n            deltaY = -30;\n            break;\n          case 33: // page up\n            deltaY = 90;\n            break;\n          case 32: // space bar\n          case 34: // page down\n            deltaY = -90;\n            break;\n          case 35: // end\n            if (e.ctrlKey) {\n              deltaY = -contentHeight;\n            } else {\n              deltaY = -containerHeight;\n            }\n            break;\n          case 36: // home\n            if (e.ctrlKey) {\n              deltaY = $this.scrollTop();\n            } else {\n              deltaY = containerHeight;\n            }\n            break;\n          default:\n            return;\n          }\n\n          $this.scrollTop($this.scrollTop() - deltaY);\n          $this.scrollLeft($this.scrollLeft() + deltaX);\n\n          shouldPrevent = shouldPreventWheel(deltaX, deltaY);\n          if (shouldPrevent) {\n            e.preventDefault();\n          }\n        });\n      }\n\n      function bindRailClickHandler() {\n        function stopPropagation(e) { e.stopPropagation(); }\n\n        $scrollbarY.bind(eventClass('click'), stopPropagation);\n        $scrollbarYRail.bind(eventClass('click'), function (e) {\n          var halfOfScrollbarLength = getInt(scrollbarYHeight / 2);\n          var positionTop = e.pageY - $scrollbarYRail.offset().top - halfOfScrollbarLength;\n          var maxPositionTop = containerHeight - scrollbarYHeight;\n          var positionRatio = positionTop / maxPositionTop;\n\n          if (positionRatio < 0) {\n            positionRatio = 0;\n          } else if (positionRatio > 1) {\n            positionRatio = 1;\n          }\n\n          $this.scrollTop((contentHeight - containerHeight) * positionRatio);\n        });\n\n        $scrollbarX.bind(eventClass('click'), stopPropagation);\n        $scrollbarXRail.bind(eventClass('click'), function (e) {\n          var halfOfScrollbarLength = getInt(scrollbarXWidth / 2);\n          var positionLeft = e.pageX - $scrollbarXRail.offset().left - halfOfScrollbarLength;\n          var maxPositionLeft = containerWidth - scrollbarXWidth;\n          var positionRatio = positionLeft / maxPositionLeft;\n\n          if (positionRatio < 0) {\n            positionRatio = 0;\n          } else if (positionRatio > 1) {\n            positionRatio = 1;\n          }\n\n          $this.scrollLeft((contentWidth - containerWidth) * positionRatio);\n        });\n      }\n\n      function bindSelectionHandler() {\n        function getRangeNode() {\n          var selection = window.getSelection ? window.getSelection() :\n                          document.getSlection ? document.getSlection() : {rangeCount: 0};\n          if (selection.rangeCount === 0) {\n            return null;\n          } else {\n            return selection.getRangeAt(0).commonAncestorContainer;\n          }\n        }\n\n        var scrollingLoop = null;\n        var scrollDiff = {top: 0, left: 0};\n        function startScrolling() {\n          if (!scrollingLoop) {\n            scrollingLoop = setInterval(function () {\n              if (!isPluginAlive()) {\n                clearInterval(scrollingLoop);\n                return;\n              }\n\n              $this.scrollTop($this.scrollTop() + scrollDiff.top);\n              $this.scrollLeft($this.scrollLeft() + scrollDiff.left);\n              updateGeometry();\n            }, 50); // every .1 sec\n          }\n        }\n        function stopScrolling() {\n          if (scrollingLoop) {\n            clearInterval(scrollingLoop);\n            scrollingLoop = null;\n          }\n          $scrollbarXRail.removeClass('in-scrolling');\n          $scrollbarYRail.removeClass('in-scrolling');\n        }\n\n        var isSelected = false;\n        $(ownerDocument).bind(eventClass('selectionchange'), function (e) {\n          if ($.contains($this[0], getRangeNode())) {\n            isSelected = true;\n          } else {\n            isSelected = false;\n            stopScrolling();\n          }\n        });\n        $(window).bind(eventClass('mouseup'), function (e) {\n          if (isSelected) {\n            isSelected = false;\n            stopScrolling();\n          }\n        });\n\n        $(window).bind(eventClass('mousemove'), function (e) {\n          if (isSelected) {\n            var mousePosition = {x: e.pageX, y: e.pageY};\n            var containerOffset = $this.offset();\n            var containerGeometry = {\n              left: containerOffset.left,\n              right: containerOffset.left + $this.outerWidth(),\n              top: containerOffset.top,\n              bottom: containerOffset.top + $this.outerHeight()\n            };\n\n            if (mousePosition.x < containerGeometry.left + 3) {\n              scrollDiff.left = -5;\n              $scrollbarXRail.addClass('in-scrolling');\n            } else if (mousePosition.x > containerGeometry.right - 3) {\n              scrollDiff.left = 5;\n              $scrollbarXRail.addClass('in-scrolling');\n            } else {\n              scrollDiff.left = 0;\n            }\n\n            if (mousePosition.y < containerGeometry.top + 3) {\n              if (containerGeometry.top + 3 - mousePosition.y < 5) {\n                scrollDiff.top = -5;\n              } else {\n                scrollDiff.top = -20;\n              }\n              $scrollbarYRail.addClass('in-scrolling');\n            } else if (mousePosition.y > containerGeometry.bottom - 3) {\n              if (mousePosition.y - containerGeometry.bottom + 3 < 5) {\n                scrollDiff.top = 5;\n              } else {\n                scrollDiff.top = 20;\n              }\n              $scrollbarYRail.addClass('in-scrolling');\n            } else {\n              scrollDiff.top = 0;\n            }\n\n            if (scrollDiff.top === 0 && scrollDiff.left === 0) {\n              stopScrolling();\n            } else {\n              startScrolling();\n            }\n          }\n        });\n      }\n\n      function bindTouchHandler(supportsTouch, supportsIePointer) {\n        function applyTouchMove(differenceX, differenceY) {\n          $this.scrollTop($this.scrollTop() - differenceY);\n          $this.scrollLeft($this.scrollLeft() - differenceX);\n\n          updateGeometry();\n        }\n\n        var startOffset = {};\n        var startTime = 0;\n        var speed = {};\n        var easingLoop = null;\n        var inGlobalTouch = false;\n        var inLocalTouch = false;\n\n        function globalTouchStart(e) {\n          inGlobalTouch = true;\n        }\n        function globalTouchEnd(e) {\n          inGlobalTouch = false;\n        }\n\n        function getTouch(e) {\n          if (e.originalEvent.targetTouches) {\n            return e.originalEvent.targetTouches[0];\n          } else {\n            // Maybe IE pointer\n            return e.originalEvent;\n          }\n        }\n        function shouldHandle(e) {\n          var event = e.originalEvent;\n          if (event.targetTouches && event.targetTouches.length === 1) {\n            return true;\n          }\n          if (event.pointerType && event.pointerType !== 'mouse' && event.pointerType !== event.MSPOINTER_TYPE_MOUSE) {\n            return true;\n          }\n          return false;\n        }\n        function touchStart(e) {\n          if (shouldHandle(e)) {\n            inLocalTouch = true;\n\n            var touch = getTouch(e);\n\n            startOffset.pageX = touch.pageX;\n            startOffset.pageY = touch.pageY;\n\n            startTime = (new Date()).getTime();\n\n            if (easingLoop !== null) {\n              clearInterval(easingLoop);\n            }\n\n            e.stopPropagation();\n          }\n        }\n        function touchMove(e) {\n          if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {\n            var touch = getTouch(e);\n\n            var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};\n\n            var differenceX = currentOffset.pageX - startOffset.pageX;\n            var differenceY = currentOffset.pageY - startOffset.pageY;\n\n            applyTouchMove(differenceX, differenceY);\n            startOffset = currentOffset;\n\n            var currentTime = (new Date()).getTime();\n\n            var timeGap = currentTime - startTime;\n            if (timeGap > 0) {\n              speed.x = differenceX / timeGap;\n              speed.y = differenceY / timeGap;\n              startTime = currentTime;\n            }\n\n            if (shouldPreventSwipe(differenceX, differenceY)) {\n              e.stopPropagation();\n              e.preventDefault();\n            }\n          }\n        }\n        function touchEnd(e) {\n          if (!inGlobalTouch && inLocalTouch) {\n            inLocalTouch = false;\n\n            clearInterval(easingLoop);\n            easingLoop = setInterval(function () {\n              if (!isPluginAlive()) {\n                clearInterval(easingLoop);\n                return;\n              }\n\n              if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {\n                clearInterval(easingLoop);\n                return;\n              }\n\n              applyTouchMove(speed.x * 30, speed.y * 30);\n\n              speed.x *= 0.8;\n              speed.y *= 0.8;\n            }, 10);\n          }\n        }\n\n        if (supportsTouch) {\n          $(window).bind(eventClass(\"touchstart\"), globalTouchStart);\n          $(window).bind(eventClass(\"touchend\"), globalTouchEnd);\n          $this.bind(eventClass(\"touchstart\"), touchStart);\n          $this.bind(eventClass(\"touchmove\"), touchMove);\n          $this.bind(eventClass(\"touchend\"), touchEnd);\n        }\n\n        if (supportsIePointer) {\n          if (window.PointerEvent) {\n            $(window).bind(eventClass(\"pointerdown\"), globalTouchStart);\n            $(window).bind(eventClass(\"pointerup\"), globalTouchEnd);\n            $this.bind(eventClass(\"pointerdown\"), touchStart);\n            $this.bind(eventClass(\"pointermove\"), touchMove);\n            $this.bind(eventClass(\"pointerup\"), touchEnd);\n          } else if (window.MSPointerEvent) {\n            $(window).bind(eventClass(\"MSPointerDown\"), globalTouchStart);\n            $(window).bind(eventClass(\"MSPointerUp\"), globalTouchEnd);\n            $this.bind(eventClass(\"MSPointerDown\"), touchStart);\n            $this.bind(eventClass(\"MSPointerMove\"), touchMove);\n            $this.bind(eventClass(\"MSPointerUp\"), touchEnd);\n          }\n        }\n      }\n\n      function bindScrollHandler() {\n        $this.bind(eventClass('scroll'), function (e) {\n          updateGeometry();\n        });\n      }\n\n      function destroy() {\n        $this.unbind(eventClass());\n        $(window).unbind(eventClass());\n        $(ownerDocument).unbind(eventClass());\n        $this.data('perfect-scrollbar', null);\n        $this.data('perfect-scrollbar-update', null);\n        $this.data('perfect-scrollbar-destroy', null);\n        $scrollbarX.remove();\n        $scrollbarY.remove();\n        $scrollbarXRail.remove();\n        $scrollbarYRail.remove();\n\n        // clean all variables\n        $this =\n        $scrollbarXRail =\n        $scrollbarYRail =\n        $scrollbarX =\n        $scrollbarY =\n        scrollbarXActive =\n        scrollbarYActive =\n        containerWidth =\n        containerHeight =\n        contentWidth =\n        contentHeight =\n        scrollbarXWidth =\n        scrollbarXLeft =\n        scrollbarXBottom =\n        isScrollbarXUsingBottom =\n        scrollbarXTop =\n        scrollbarYHeight =\n        scrollbarYTop =\n        scrollbarYRight =\n        isScrollbarYUsingRight =\n        scrollbarYLeft =\n        isRtl =\n        eventClass = null;\n      }\n\n      var supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);\n      var supportsIePointer = window.navigator.msMaxTouchPoints !== null;\n\n      function initialize() {\n        updateGeometry();\n        bindScrollHandler();\n        bindMouseScrollXHandler();\n        bindMouseScrollYHandler();\n        bindRailClickHandler();\n        bindSelectionHandler();\n        bindMouseWheelHandler();\n\n        if (supportsTouch || supportsIePointer) {\n          bindTouchHandler(supportsTouch, supportsIePointer);\n        }\n        if (settings.useKeyboard) {\n          bindKeyboardHandler();\n        }\n        $this.data('perfect-scrollbar', $this);\n        $this.data('perfect-scrollbar-update', updateGeometry);\n        $this.data('perfect-scrollbar-destroy', destroy);\n      }\n\n      initialize();\n\n      return $this;\n    });\n  };\n});\n\n// SweetAlert\n// 2014 (c) - Tristan Edwards\n// github.com/t4t5/sweetalert\n;(function(window, document) {\n\n  var modalClass   = '.sweet-alert',\n      overlayClass = '.sweet-overlay',\n      alertTypes   = ['error', 'warning', 'info', 'success'],\n      defaultParams = {\n        title: '',\n        text: '',\n        type: null,\n        allowOutsideClick: false,\n        showCancelButton: false,\n        closeOnConfirm: true,\n        closeOnCancel: true,\n        confirmButtonText: 'OK',\n        confirmButtonColor: '#AEDEF4',\n        cancelButtonText: lasso_editor.strings.cancel,\n        imageUrl: null,\n        imageSize: null,\n        timer: null\n      };\n\n\n  /*\n   * Manipulate DOM\n   */\n\n  var getModal = function() {\n      return document.querySelector(modalClass);\n    },\n    getOverlay = function() {\n      return document.querySelector(overlayClass);\n    },\n    hasClass = function(elem, className) {\n      return new RegExp(' ' + className + ' ').test(' ' + elem.className + ' ');\n    },\n    addClass = function(elem, className) {\n      if (!hasClass(elem, className)) {\n        elem.className += ' ' + className;\n      }\n    },\n    removeClass = function(elem, className) {\n      var newClass = ' ' + elem.className.replace(/[\\t\\r\\n]/g, ' ') + ' ';\n      if (hasClass(elem, className)) {\n        while (newClass.indexOf(' ' + className + ' ') >= 0) {\n          newClass = newClass.replace(' ' + className + ' ', ' ');\n        }\n        elem.className = newClass.replace(/^\\s+|\\s+$/g, '');\n      }\n    },\n    escapeHtml = function(str) {\n      var div = document.createElement('div');\n      div.appendChild(document.createTextNode(str));\n      return div.innerHTML;\n    },\n    _show = function(elem) {\n      elem.style.opacity = '';\n      elem.style.display = 'block';\n    },\n    show = function(elems) {\n      if (elems && !elems.length) {\n        return _show(elems);\n      }\n      for (var i = 0; i < elems.length; ++i) {\n        _show(elems[i]);\n      }\n    },\n    _hide = function(elem) {\n      elem.style.opacity = '';\n      elem.style.display = 'none';\n    },\n    hide = function(elems) {\n      if (elems && !elems.length) {\n        return _hide(elems);\n      }\n      for (var i = 0; i < elems.length; ++i) {\n        _hide(elems[i]);\n      }\n    },\n    isDescendant = function(parent, child) {\n      var node = child.parentNode;\n      while (node !== null) {\n        if (node === parent) {\n          return true;\n        }\n        node = node.parentNode;\n      }\n      return false;\n    },\n    getTopMargin = function(elem) {\n      elem.style.left = '-9999px';\n      elem.style.display = 'block';\n\n      var height = elem.clientHeight,\n          padding;\n      if (typeof getComputedStyle !== \"undefined\") { /* IE 8 */\n        padding = parseInt(getComputedStyle(elem).getPropertyValue('padding'), 10);\n      } else{\n        padding = parseInt(elem.currentStyle.padding);\n      }\n\n      elem.style.left = '';\n      elem.style.display = 'none';\n      return ('-' + parseInt(height / 2 + padding) + 'px');\n    },\n    fadeIn = function(elem, interval) {\n      if (+elem.style.opacity < 1) {\n        interval = interval || 16;\n        elem.style.opacity = 0;\n        elem.style.display = 'block';\n        var last = +new Date();\n        var tick = function() {\n          elem.style.opacity = +elem.style.opacity + (new Date() - last) / 100;\n          last = +new Date();\n\n          if (+elem.style.opacity < 1) {\n            setTimeout(tick, interval);\n          }\n        };\n        tick();\n      }\n      elem.style.display = 'block'; //fallback IE8\n    },\n    fadeOut = function(elem, interval) {\n      interval = interval || 16;\n      elem.style.opacity = 1;\n      var last = +new Date();\n      var tick = function() {\n        elem.style.opacity = +elem.style.opacity - (new Date() - last) / 100;\n        last = +new Date();\n\n        if (+elem.style.opacity > 0) {\n          setTimeout(tick, interval);\n        } else {\n          elem.style.display = 'none';\n        }\n      };\n      tick();\n    },\n    fireClick = function(node) {\n      // Taken from http://www.nonobtrusive.com/2011/11/29/programatically-fire-crossbrowser-click-event-with-javascript/\n      // Then fixed for today's Chrome browser.\n      if (MouseEvent) {\n        // Up-to-date approach\n        var mevt = new MouseEvent('click', {\n          view: window,\n          bubbles: false,\n          cancelable: true\n        });\n        node.dispatchEvent(mevt);\n      } else if ( document.createEvent ) {\n        // Fallback\n        var evt = document.createEvent('MouseEvents');\n        evt.initEvent('click', false, false);\n        node.dispatchEvent(evt);\n      } else if( document.createEventObject ) {\n        node.fireEvent('onclick') ;\n      } else if (typeof node.onclick === 'function' ) {\n        node.onclick();\n      }\n    },\n    stopEventPropagation = function(e) {\n      // In particular, make sure the space bar doesn't scroll the main window.\n      if (typeof e.stopPropagation === 'function') {\n        e.stopPropagation();\n        e.preventDefault();\n      } else if (window.event && window.event.hasOwnProperty('cancelBubble')) {\n        window.event.cancelBubble = true;\n      }\n    };\n\n  // Remember state in cases where opening and handling a modal will fiddle with it.\n  var previousActiveElement,\n      previousDocumentClick,\n      previousWindowKeyDown,\n      lastFocusedButton;\n\n  /*\n   * Add modal + overlay to DOM\n   */\n\n  window.sweetAlertInitialize = function() {\n    var sweetHTML = '<div class=\"sweet-overlay\" tabIndex=\"-1\"></div><div class=\"sweet-alert\" tabIndex=\"-1\"><div class=\"icon error\"><span class=\"x-mark\"><span class=\"line left\"></span><span class=\"line right\"></span></span></div><div class=\"icon warning\"> <span class=\"body\"></span> <span class=\"dot\"></span> </div> <div class=\"icon info\"></div> <div class=\"icon success\"> <span class=\"line tip\"></span> <span class=\"line long\"></span> <div class=\"placeholder\"></div> <div class=\"fix\"></div> </div> <div class=\"icon custom\"></div> <h2>Title</h2><p>Text</p><button class=\"cancel\" tabIndex=\"2\">'+lasso_editor.strings.cancel+'</button><button class=\"confirm\" tabIndex=\"1\">OK</button></div>',\n        sweetWrap = document.createElement('div');\n\n    sweetWrap.innerHTML = sweetHTML;\n\n    // For readability: check sweet-alert.html\n    document.body.appendChild(sweetWrap);\n  };\n\n  /*\n   * Global sweetAlert function\n   */\n\n  window.sweetAlert = window.swal = function() {\n    // Copy arguments to the local args variable\n    var args = arguments;\n    if (getModal() !== null) {\n        // If getModal returns values then continue\n        modalDependant.apply(this, args);\n    } else {\n        // If getModal returns null i.e. no matches, then set up a interval event to check the return value until it is not null\t\n        var modalCheckInterval = setInterval(function() {\n          if (getModal() !== null) {\n            clearInterval(modalCheckInterval);\n            modalDependant.apply(this, args);\n          }\n      }, 100);\n    }\n  };\n        \n  function modalDependant() {\n\n    if (arguments[0] === undefined) {\n      window.console.error('sweetAlert expects at least 1 attribute!');\n      return false;\n    }\n\n    var params = extend({}, defaultParams);\n\n    switch (typeof arguments[0]) {\n\n      case 'string':\n        params.title = arguments[0];\n        params.text  = arguments[1] || '';\n        params.type  = arguments[2] || '';\n\n        break;\n\n      case 'object':\n        if (arguments[0].title === undefined) {\n          window.console.error('Missing \"title\" argument!');\n          return false;\n        }\n\n        params.title              = arguments[0].title;\n        params.text               = arguments[0].text || defaultParams.text;\n        params.type               = arguments[0].type || defaultParams.type;\n        params.customClass        = arguments[0].customClass || params.customClass;\n        params.allowOutsideClick  = arguments[0].allowOutsideClick || defaultParams.allowOutsideClick;\n        params.showCancelButton   = arguments[0].showCancelButton !== undefined ? arguments[0].showCancelButton : defaultParams.showCancelButton;\n        params.closeOnConfirm     = arguments[0].closeOnConfirm !== undefined ? arguments[0].closeOnConfirm : defaultParams.closeOnConfirm;\n        params.closeOnCancel      = arguments[0].closeOnCancel !== undefined ? arguments[0].closeOnCancel : defaultParams.closeOnCancel;\n        params.timer              = arguments[0].timer || defaultParams.timer;\n\n        // Show \"Confirm\" instead of \"OK\" if cancel button is visible\n        params.confirmButtonText  = (defaultParams.showCancelButton) ? 'Confirm' : defaultParams.confirmButtonText;\n        params.confirmButtonText  = arguments[0].confirmButtonText || defaultParams.confirmButtonText;\n        params.confirmButtonColor = arguments[0].confirmButtonColor || defaultParams.confirmButtonColor;\n        params.cancelButtonText   = arguments[0].cancelButtonText || defaultParams.cancelButtonText;\n        params.imageUrl           = arguments[0].imageUrl || defaultParams.imageUrl;\n        params.imageSize          = arguments[0].imageSize || defaultParams.imageSize;\n        params.doneFunction       = arguments[1] || null;\n\n        break;\n\n      default:\n        window.console.error('Unexpected type of argument! Expected \"string\" or \"object\", got ' + typeof arguments[0]);\n        return false;\n\n    }\n\n    setParameters(params);\n    fixVerticalPosition();\n    openModal();\n\n\n    // Modal interactions\n    var modal = getModal();\n\n    // Mouse interactions\n    var onButtonEvent = function(event) {\n      var e = event || window.event;\n      var target = e.target || e.srcElement,\n          targetedConfirm    = (target.className === 'confirm'),\n          modalIsVisible     = hasClass(modal, 'visible'),\n          doneFunctionExists = (params.doneFunction && modal.getAttribute('data-has-done-function') === 'true');\n\n      switch (e.type) {\n        case (\"mouseover\"):\n          if (targetedConfirm) {\n            target.style.backgroundColor = colorLuminance(params.confirmButtonColor, -0.04);\n          }\n          break;\n        case (\"mouseout\"):\n          if (targetedConfirm) {\n            target.style.backgroundColor = params.confirmButtonColor;\n          }\n          break;\n        case (\"mousedown\"):\n          if (targetedConfirm) {\n            target.style.backgroundColor = colorLuminance(params.confirmButtonColor, -0.14);\n          }\n          break;\n        case (\"mouseup\"):\n          if (targetedConfirm) {\n            target.style.backgroundColor = colorLuminance(params.confirmButtonColor, -0.04);\n          }\n          break;\n        case (\"focus\"):\n          var $confirmButton = modal.querySelector('button.confirm'),\n              $cancelButton  = modal.querySelector('button.cancel');\n\n          if (targetedConfirm) {\n            $cancelButton.style.boxShadow = 'none';\n          } else {\n            $confirmButton.style.boxShadow = 'none';\n          }\n          break;\n        case (\"click\"):\n          if (targetedConfirm && doneFunctionExists && modalIsVisible) { // Clicked \"confirm\"\n\n            params.doneFunction(true);\n\n            if (params.closeOnConfirm) {\n              closeModal();\n            }\n          } else if (doneFunctionExists && modalIsVisible) { // Clicked \"cancel\"\n\n            // Check if callback function expects a parameter (to track cancel actions)\n            var functionAsStr          = String(params.doneFunction).replace(/\\s/g, '');\n            var functionHandlesCancel  = functionAsStr.substring(0, 9) === \"function(\" && functionAsStr.substring(9, 10) !== \")\";\n\n            if (functionHandlesCancel) {\n              params.doneFunction(false);\n            }\n\n            if (params.closeOnCancel) {\n              closeModal();\n            }\n          } else {\n            closeModal();\n          }\n\n          break;\n      }\n    };\n\n    var $buttons = modal.querySelectorAll('button');\n    for (var i = 0; i < $buttons.length; i++) {\n      $buttons[i].onclick     = onButtonEvent;\n      $buttons[i].onmouseover = onButtonEvent;\n      $buttons[i].onmouseout  = onButtonEvent;\n      $buttons[i].onmousedown = onButtonEvent;\n      //$buttons[i].onmouseup   = onButtonEvent;\n      $buttons[i].onfocus     = onButtonEvent;\n    }\n\n    // Remember the current document.onclick event.\n    previousDocumentClick = document.onclick;\n    document.onclick = function(event) {\n      var e = event || window.event;\n      var target = e.target || e.srcElement;\n\n      var clickedOnModal = (modal === target),\n          clickedOnModalChild = isDescendant(modal, target),\n          modalIsVisible = hasClass(modal, 'visible'),\n          outsideClickIsAllowed = modal.getAttribute('data-allow-ouside-click') === 'true';\n\n      if (!clickedOnModal && !clickedOnModalChild && modalIsVisible && outsideClickIsAllowed) {\n        closeModal();\n      }\n    };\n\n\n    // Keyboard interactions\n    var $okButton = modal.querySelector('button.confirm'),\n        $cancelButton = modal.querySelector('button.cancel'),\n        $modalButtons = modal.querySelectorAll('button:not([type=hidden])');\n\n\n    function handleKeyDown(event) {\n      var e = event || window.event;\n      var keyCode = e.keyCode || e.which;\n\n      if ([9,13,32,27].indexOf(keyCode) === -1) {\n        // Don't do work on keys we don't care about.\n        return;\n      }\n\n      var $targetElement = e.target || e.srcElement;\n\n      var btnIndex = -1; // Find the button - note, this is a nodelist, not an array.\n      for (var i = 0; i < $modalButtons.length; i++) {\n        if ($targetElement === $modalButtons[i]) {\n          btnIndex = i;\n          break;\n        }\n      }\n\n      if (keyCode === 9) {\n        // TAB\n        if (btnIndex === -1) {\n          // No button focused. Jump to the confirm button.\n          $targetElement = $okButton;\n        } else {\n          // Cycle to the next button\n          if (btnIndex === $modalButtons.length - 1) {\n            $targetElement = $modalButtons[0];\n          } else {\n            $targetElement = $modalButtons[btnIndex + 1];\n          }\n        }\n\n        stopEventPropagation(e);\n        $targetElement.focus();\n        setFocusStyle($targetElement, params.confirmButtonColor); // TODO\n\n      } else {\n        if (keyCode === 13 || keyCode === 32) {\n            if (btnIndex === -1) {\n              // ENTER/SPACE clicked outside of a button.\n              $targetElement = $okButton;\n            } else {\n              // Do nothing - let the browser handle it.\n              $targetElement = undefined;\n            }\n        } else if (keyCode === 27 && !($cancelButton.hidden || $cancelButton.style.display === 'none')) {\n          // ESC to cancel only if there's a cancel button displayed (like the alert() window).\n          $targetElement = $cancelButton;\n        } else {\n          // Fallback - let the browser handle it.\n          $targetElement = undefined;\n        }\n\n        if ($targetElement !== undefined) {\n          fireClick($targetElement, e);\n        }\n      }\n    }\n\n    previousWindowKeyDown = window.onkeydown;\n    window.onkeydown = handleKeyDown;\n\n    function handleOnBlur(event) {\n      var e = event || window.event;\n      var $targetElement = e.target || e.srcElement,\n          $focusElement = e.relatedTarget,\n          modalIsVisible = hasClass(modal, 'visible');\n\n      if (modalIsVisible) {\n        var btnIndex = -1; // Find the button - note, this is a nodelist, not an array.\n\n        if ($focusElement !== null) {\n          // If we picked something in the DOM to focus to, let's see if it was a button.\n          for (var i = 0; i < $modalButtons.length; i++) {\n            if ($focusElement === $modalButtons[i]) {\n              btnIndex = i;\n              break;\n            }\n          }\n\n          if (btnIndex === -1) {\n            // Something in the dom, but not a visible button. Focus back on the button.\n            //$targetElement.focus();\n          }\n        } else {\n          // Exiting the DOM (e.g. clicked in the URL bar);\n          lastFocusedButton = $targetElement;\n        }\n      }\n    }\n\n    $okButton.onblur = handleOnBlur;\n    $cancelButton.onblur = handleOnBlur;\n\n    /*window.onfocus = function() {\n      // When the user has focused away and focused back from the whole window.\n      window.setTimeout(function() {\n        // Put in a timeout to jump out of the event sequence. Calling focus() in the event\n        // sequence confuses things.\n        if (lastFocusedButton !== undefined) {\n          lastFocusedButton.focus();\n          lastFocusedButton = undefined;\n        }\n      }, 0);\n    };*/\n  }\n\n  /**\n   * Set default params for each popup\n   * @param {Object} userParams\n   */\n  window.swal.setDefaults = function(userParams) {\n    if (!userParams) {\n      throw new Error('userParams is required');\n    }\n    if (typeof userParams !== 'object') {\n      throw new Error('userParams has to be a object');\n    }\n\n    extend(defaultParams, userParams);\n  };\n\n  /*\n   * Set type, text and actions on modal\n   */\n\n  function setParameters(params) {\n    var modal = getModal();\n\n    var $title = modal.querySelector('h2'),\n        $text = modal.querySelector('p'),\n        $cancelBtn = modal.querySelector('button.cancel'),\n        $confirmBtn = modal.querySelector('button.confirm');\n\n    // Title\n    $title.innerHTML = escapeHtml(params.title).split(\"\\n\").join(\"<br>\");\n\n    // Text\n    $text.innerHTML = params.text;////escapeHtml(params.text || '').split(\"\\n\").join(\"<br>\");\n    if (params.text) {\n      show($text);\n    }\n\n    //Custom Class\n    if (params.customClass) {\n      addClass(modal, params.customClass);\n    }\n\n    // Icon\n    hide(modal.querySelectorAll('.icon'));\n    if (params.type) {\n      var validType = false;\n      for (var i = 0; i < alertTypes.length; i++) {\n        if (params.type === alertTypes[i]) {\n          validType = true;\n          break;\n        }\n      }\n      if (!validType) {\n        window.console.error('Unknown alert type: ' + params.type);\n        return false;\n      }\n      var $icon = modal.querySelector('.icon.' + params.type);\n      show($icon);\n\n      // Animate icon\n      switch (params.type) {\n        case \"success\":\n          addClass($icon, 'animate');\n          addClass($icon.querySelector('.tip'), 'animateSuccessTip');\n          addClass($icon.querySelector('.long'), 'animateSuccessLong');\n          break;\n        case \"error\":\n          addClass($icon, 'animateErrorIcon');\n          addClass($icon.querySelector('.x-mark'), 'animateXMark');\n          break;\n        case \"warning\":\n          addClass($icon, 'pulseWarning');\n          addClass($icon.querySelector('.body'), 'pulseWarningIns');\n          addClass($icon.querySelector('.dot'), 'pulseWarningIns');\n          break;\n      }\n\n    }\n\n    // Custom image\n    if (params.imageUrl) {\n      var $customIcon = modal.querySelector('.icon.custom');\n\n      $customIcon.style.backgroundImage = 'url(' + params.imageUrl + ')';\n      show($customIcon);\n\n      var _imgWidth  = 80,\n          _imgHeight = 80;\n\n      if (params.imageSize) {\n        var imgWidth  = params.imageSize.split('x')[0];\n        var imgHeight = params.imageSize.split('x')[1];\n\n        if (!imgWidth || !imgHeight) {\n          window.console.error(\"Parameter imageSize expects value with format WIDTHxHEIGHT, got \" + params.imageSize);\n        } else {\n          _imgWidth  = imgWidth;\n          _imgHeight = imgHeight;\n\n          $customIcon.css({\n            'width': imgWidth + 'px',\n            'height': imgHeight + 'px'\n          });\n        }\n      }\n      $customIcon.setAttribute('style', $customIcon.getAttribute('style') + 'width:' + _imgWidth + 'px; height:' + _imgHeight + 'px');\n    }\n\n    // Cancel button\n    modal.setAttribute('data-has-cancel-button', params.showCancelButton);\n    if (params.showCancelButton) {\n      $cancelBtn.style.display = 'inline-block';\n    } else {\n      hide($cancelBtn);\n    }\n\n    // Edit text on cancel and confirm buttons\n    if (params.cancelButtonText) {\n      $cancelBtn.innerHTML = escapeHtml(params.cancelButtonText);\n    }\n    if (params.confirmButtonText) {\n      $confirmBtn.innerHTML = escapeHtml(params.confirmButtonText);\n    }\n\n    // Set confirm button to selected background color\n    $confirmBtn.style.backgroundColor = params.confirmButtonColor;\n\n    // Set box-shadow to default focused button\n    setFocusStyle($confirmBtn, params.confirmButtonColor);\n\n    // Allow outside click?\n    modal.setAttribute('data-allow-ouside-click', params.allowOutsideClick);\n\n    // Done-function\n    var hasDoneFunction = (params.doneFunction) ? true : false;\n    modal.setAttribute('data-has-done-function', hasDoneFunction);\n\n    // Close timer\n    modal.setAttribute('data-timer', params.timer);\n  }\n\n\n  /*\n   * Set hover, active and focus-states for buttons (source: http://www.sitepoint.com/javascript-generate-lighter-darker-color)\n   */\n\n  function colorLuminance(hex, lum) {\n    // Validate hex string\n    hex = String(hex).replace(/[^0-9a-f]/gi, '');\n    if (hex.length < 6) {\n      hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];\n    }\n    lum = lum || 0;\n\n    // Convert to decimal and change luminosity\n    var rgb = \"#\", c, i;\n    for (i = 0; i < 3; i++) {\n      c = parseInt(hex.substr(i*2,2), 16);\n      c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);\n      rgb += (\"00\"+c).substr(c.length);\n    }\n\n    return rgb;\n  }\n\n  function extend(a, b){\n    for (var key in b) {\n      if (b.hasOwnProperty(key)) {\n        a[key] = b[key];\n      }\n    }\n\n    return a;\n  }\n\n  function hexToRgb(hex) {\n    var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n    return result ? parseInt(result[1], 16) + ', ' + parseInt(result[2], 16) + ', ' + parseInt(result[3], 16) : null;\n  }\n\n  // Add box-shadow style to button (depending on its chosen bg-color)\n  function setFocusStyle($button, bgColor) {\n    var rgbColor = hexToRgb(bgColor);\n    $button.style.boxShadow = '0 0 2px rgba(' + rgbColor +', 0.8), inset 0 0 0 1px rgba(0, 0, 0, 0.05)';\n  }\n\n\n\n  /*\n   * Animations\n   */\n\n  function openModal() {\n    var modal = getModal();\n    fadeIn(getOverlay(), 10);\n    show(modal);\n    addClass(modal, 'showSweetAlert');\n    removeClass(modal, 'hideSweetAlert');\n\n    previousActiveElement = document.activeElement;\n    var $okButton = modal.querySelector('button.confirm');\n    $okButton.focus();\n\n    setTimeout(function() {\n      addClass(modal, 'visible');\n    }, 500);\n\n    var timer = modal.getAttribute('data-timer');\n\n    if (timer !== \"null\" && timer !== \"\") {\n      modal.timeout = setTimeout(function() {\n        closeModal();\n      }, timer);\n    }\n  }\n\n  function closeModal() {\n    var modal = getModal();\n    fadeOut(getOverlay(), 5);\n    fadeOut(modal, 5);\n    removeClass(modal, 'showSweetAlert');\n    addClass(modal, 'hideSweetAlert');\n    removeClass(modal, 'visible');\n\n\n    // Reset icon animations\n\n    var $successIcon = modal.querySelector('.icon.success');\n    removeClass($successIcon, 'animate');\n    removeClass($successIcon.querySelector('.tip'), 'animateSuccessTip');\n    removeClass($successIcon.querySelector('.long'), 'animateSuccessLong');\n\n    var $errorIcon = modal.querySelector('.icon.error');\n    removeClass($errorIcon, 'animateErrorIcon');\n    removeClass($errorIcon.querySelector('.x-mark'), 'animateXMark');\n\n    var $warningIcon = modal.querySelector('.icon.warning');\n    removeClass($warningIcon, 'pulseWarning');\n    removeClass($warningIcon.querySelector('.body'), 'pulseWarningIns');\n    removeClass($warningIcon.querySelector('.dot'), 'pulseWarningIns');\n\n\n    // Reset the page to its previous state\n    window.onkeydown = previousWindowKeyDown;\n    document.onclick = previousDocumentClick;\n    if (previousActiveElement) {\n      previousActiveElement.focus();\n    }\n    lastFocusedButton = undefined;\n    clearTimeout(modal.timeout);\n  }\n\n\n  /*\n   * Set \"margin-top\"-property on modal based on its computed height\n   */\n\n  function fixVerticalPosition() {\n    var modal = getModal();\n\n    modal.style.marginTop = getTopMargin(getModal());\n  }\n\n\n\n  /*\n   * If library is injected after page has loaded\n   */\n\n  (function () {\n\t  if (document.readyState === \"complete\" || document.readyState === \"interactive\" && document.body) {\n\t\t  window.sweetAlertInitialize();\n\t  } else {\n\t\t  if (document.addEventListener) {\n\t\t\t  document.addEventListener('DOMContentLoaded', function factorial() {\n\t\t\t\t  document.removeEventListener('DOMContentLoaded', arguments.callee, false);\n\t\t\t\t  window.sweetAlertInitialize();\n\t\t\t  }, false);\n\t\t  } else if (document.attachEvent) {\n\t\t\t  document.attachEvent('onreadystatechange', function() {\n\t\t\t\t  if (document.readyState === 'complete') {\n\t\t\t\t\t  document.detachEvent('onreadystatechange', arguments.callee);\n\t\t\t\t\t  window.sweetAlertInitialize();\n\t\t\t\t  }\n\t\t\t  });\n\t\t  }\n\t  }\n  })();\n\n})(window, document);\n\n/**\n * jQuery Geocoding and Places Autocomplete Plugin - V 1.6.4\n *\n * @author Martin Kleppe <kleppe@ubilabs.net>, 2014\n * @author Ubilabs http://ubilabs.net, 2014\n * @license MIT License <http://www.opensource.org/licenses/mit-license.php>\n */\n(function($,window,document,undefined){var defaults={bounds:true,country:null,map:false,details:false,detailsAttribute:\"name\",autoselect:true,location:false,mapOptions:{zoom:14,scrollwheel:false,mapTypeId:\"roadmap\"},markerOptions:{draggable:false},maxZoom:16,types:[\"geocode\"],blur:false};var componentTypes=(\"street_address route intersection political \"+\"country administrative_area_level_1 administrative_area_level_2 \"+\"administrative_area_level_3 colloquial_area locality sublocality \"+\"neighborhood premise subpremise postal_code natural_feature airport \"+\"park point_of_interest post_box street_number floor room \"+\"lat lng viewport location \"+\"formatted_address location_type bounds\").split(\" \");var placesDetails=(\"id place_id url website vicinity reference name rating \"+\"international_phone_number icon formatted_phone_number\").split(\" \");function GeoComplete(input,options){this.options=$.extend(true,{},defaults,options);this.input=input;this.$input=$(input);this._defaults=defaults;this._name=\"geocomplete\";this.init()}$.extend(GeoComplete.prototype,{init:function(){this.initMap();this.initMarker();this.initGeocoder();this.initDetails();this.initLocation()},initMap:function(){if(!this.options.map){return}if(typeof this.options.map.setCenter==\"function\"){this.map=this.options.map;return}this.map=new google.maps.Map($(this.options.map)[0],this.options.mapOptions);google.maps.event.addListener(this.map,\"click\",$.proxy(this.mapClicked,this));google.maps.event.addListener(this.map,\"zoom_changed\",$.proxy(this.mapZoomed,this))},initMarker:function(){if(!this.map){return}var options=$.extend(this.options.markerOptions,{map:this.map});if(options.disabled){return}this.marker=new google.maps.Marker(options);google.maps.event.addListener(this.marker,\"dragend\",$.proxy(this.markerDragged,this))},initGeocoder:function(){var options={types:this.options.types,bounds:this.options.bounds===true?null:this.options.bounds,componentRestrictions:this.options.componentRestrictions};if(this.options.country){options.componentRestrictions={country:this.options.country}}this.autocomplete=new google.maps.places.Autocomplete(this.input,options);this.geocoder=new google.maps.Geocoder;if(this.map&&this.options.bounds===true){this.autocomplete.bindTo(\"bounds\",this.map)}google.maps.event.addListener(this.autocomplete,\"place_changed\",$.proxy(this.placeChanged,this));this.$input.keypress(function(event){if(event.keyCode===13){return false}});this.$input.bind(\"geocode\",$.proxy(function(){this.find()},this));if(this.options.blur===true){this.$input.blur($.proxy(function(){this.find()},this))}},initDetails:function(){if(!this.options.details){return}var $details=$(this.options.details),attribute=this.options.detailsAttribute,details={};function setDetail(value){details[value]=$details.find(\"[\"+attribute+\"=\"+value+\"]\")}$.each(componentTypes,function(index,key){setDetail(key);setDetail(key+\"_short\")});$.each(placesDetails,function(index,key){setDetail(key)});this.$details=$details;this.details=details},initLocation:function(){var location=this.options.location,latLng;if(!location){return}if(typeof location==\"string\"){this.find(location);return}if(location instanceof Array){latLng=new google.maps.LatLng(location[0],location[1])}if(location instanceof google.maps.LatLng){latLng=location}if(latLng){if(this.map){this.map.setCenter(latLng)}if(this.marker){this.marker.setPosition(latLng)}}},find:function(address){this.geocode({address:address||this.$input.val()})},geocode:function(request){if(this.options.bounds&&!request.bounds){if(this.options.bounds===true){request.bounds=this.map&&this.map.getBounds()}else{request.bounds=this.options.bounds}}if(this.options.country){request.region=this.options.country}this.geocoder.geocode(request,$.proxy(this.handleGeocode,this))},selectFirstResult:function(){var selected=\"\";if($(\".pac-item-selected\")[0]){selected=\"-selected\"}var $span1=$(\".pac-container .pac-item\"+selected+\":first span:nth-child(2)\").text();var $span2=$(\".pac-container .pac-item\"+selected+\":first span:nth-child(3)\").text();var firstResult=$span1;if($span2){firstResult+=\" - \"+$span2}this.$input.val(firstResult);return firstResult},handleGeocode:function(results,status){if(status===google.maps.GeocoderStatus.OK){var result=results[0];this.$input.val(result.formatted_address);this.update(result);if(results.length>1){this.trigger(\"geocode:multiple\",results)}}else{this.trigger(\"geocode:error\",status)}},trigger:function(event,argument){this.$input.trigger(event,[argument])},center:function(geometry){if(geometry.viewport){this.map.fitBounds(geometry.viewport);if(this.map.getZoom()>this.options.maxZoom){this.map.setZoom(this.options.maxZoom)}}else{this.map.setZoom(this.options.maxZoom);this.map.setCenter(geometry.location)}if(this.marker){this.marker.setPosition(geometry.location);this.marker.setAnimation(this.options.markerOptions.animation)}},update:function(result){if(this.map){this.center(result.geometry)}if(this.$details){this.fillDetails(result)}this.trigger(\"geocode:result\",result)},fillDetails:function(result){var data={},geometry=result.geometry,viewport=geometry.viewport,bounds=geometry.bounds;$.each(result.address_components,function(index,object){var name=object.types[0];$.each(object.types,function(index,name){data[name]=object.long_name;data[name+\"_short\"]=object.short_name})});$.each(placesDetails,function(index,key){data[key]=result[key]});$.extend(data,{formatted_address:result.formatted_address,location_type:geometry.location_type||\"PLACES\",viewport:viewport,bounds:bounds,location:geometry.location,lat:geometry.location.lat(),lng:geometry.location.lng()});$.each(this.details,$.proxy(function(key,$detail){var value=data[key];this.setDetail($detail,value)},this));this.data=data},setDetail:function($element,value){if(value===undefined){value=\"\"}else if(typeof value.toUrlValue==\"function\"){value=value.toUrlValue()}if($element.is(\":input\")){$element.val(value)}else{$element.text(value)}},markerDragged:function(event){this.trigger(\"geocode:dragged\",event.latLng)},mapClicked:function(event){this.trigger(\"geocode:click\",event.latLng)},mapZoomed:function(event){this.trigger(\"geocode:zoom\",this.map.getZoom())},resetMarker:function(){this.marker.setPosition(this.data.location);this.setDetail(this.details.lat,this.data.location.lat());this.setDetail(this.details.lng,this.data.location.lng())},placeChanged:function(){var place=this.autocomplete.getPlace();if(!place||!place.geometry){if(this.options.autoselect){var autoSelection=this.selectFirstResult();this.find(autoSelection)}}else{this.update(place)}}});$.fn.geocomplete=function(options){var attribute=\"plugin_geocomplete\";if(typeof options==\"string\"){var instance=$(this).data(attribute)||$(this).geocomplete().data(attribute),prop=instance[options];if(typeof prop==\"function\"){prop.apply(instance,Array.prototype.slice.call(arguments,1));return $(this)}else{if(arguments.length==2){prop=arguments[1]}return prop}}else{return this.each(function(){var instance=$.data(this,attribute);if(!instance){instance=new GeoComplete(this,options);$.data(this,attribute,instance)}})}}})(jQuery,window,document);\n// packaged - 3.1.8\n(function () {\n\n\t/**\n\t * Class for managing events.\n\t * Can be extended to provide event functionality in other classes.\n\t *\n\t * @class EventEmitter Manages event registering and emitting.\n\t */\n\tfunction EventEmitter() {}\n\n\t// Shortcuts to improve speed and size\n\tvar proto = EventEmitter.prototype;\n\tvar exports = this;\n\tvar originalGlobalValue = exports.EventEmitter;\n\n\t/**\n\t * Finds the index of the listener for the event in it's storage array.\n\t *\n\t * @param {Function[]} listeners Array of listeners to search through.\n\t * @param {Function} listener Method to look for.\n\t * @return {Number} Index of the specified listener, -1 if not found\n\t * @api private\n\t */\n\tfunction indexOfListener(listeners, listener) {\n\t\tvar i = listeners.length;\n\t\twhile (i--) {\n\t\t\tif (listeners[i].listener === listener) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t}\n\n\t/**\n\t * Alias a method while keeping the context correct, to allow for overwriting of target method.\n\t *\n\t * @param {String} name The name of the target method.\n\t * @return {Function} The aliased method\n\t * @api private\n\t */\n\tfunction alias(name) {\n\t\treturn function aliasClosure() {\n\t\t\treturn this[name].apply(this, arguments);\n\t\t};\n\t}\n\n\t/**\n\t * Returns the listener array for the specified event.\n\t * Will initialise the event object and listener arrays if required.\n\t * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.\n\t * Each property in the object response is an array of listener functions.\n\t *\n\t * @param {String|RegExp} evt Name of the event to return the listeners from.\n\t * @return {Function[]|Object} All listener functions for the event.\n\t */\n\tproto.getListeners = function getListeners(evt) {\n\t\tvar events = this._getEvents();\n\t\tvar response;\n\t\tvar key;\n\n\t\t// Return a concatenated array of all matching events if\n\t\t// the selector is a regular expression.\n\t\tif (typeof evt === 'object') {\n\t\t\tresponse = {};\n\t\t\tfor (key in events) {\n\t\t\t\tif (events.hasOwnProperty(key) && evt.test(key)) {\n\t\t\t\t\tresponse[key] = events[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tresponse = events[evt] || (events[evt] = []);\n\t\t}\n\n\t\treturn response;\n\t};\n\n\t/**\n\t * Takes a list of listener objects and flattens it into a list of listener functions.\n\t *\n\t * @param {Object[]} listeners Raw listener objects.\n\t * @return {Function[]} Just the listener functions.\n\t */\n\tproto.flattenListeners = function flattenListeners(listeners) {\n\t\tvar flatListeners = [];\n\t\tvar i;\n\n\t\tfor (i = 0; i < listeners.length; i += 1) {\n\t\t\tflatListeners.push(listeners[i].listener);\n\t\t}\n\n\t\treturn flatListeners;\n\t};\n\n\t/**\n\t * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.\n\t *\n\t * @param {String|RegExp} evt Name of the event to return the listeners from.\n\t * @return {Object} All listener functions for an event in an object.\n\t */\n\tproto.getListenersAsObject = function getListenersAsObject(evt) {\n\t\tvar listeners = this.getListeners(evt);\n\t\tvar response;\n\n\t\tif (listeners instanceof Array) {\n\t\t\tresponse = {};\n\t\t\tresponse[evt] = listeners;\n\t\t}\n\n\t\treturn response || listeners;\n\t};\n\n\t/**\n\t * Adds a listener function to the specified event.\n\t * The listener will not be added if it is a duplicate.\n\t * If the listener returns true then it will be removed after it is called.\n\t * If you pass a regular expression as the event name then the listener will be added to all events that match it.\n\t *\n\t * @param {String|RegExp} evt Name of the event to attach the listener to.\n\t * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.addListener = function addListener(evt, listener) {\n\t\tvar listeners = this.getListenersAsObject(evt);\n\t\tvar listenerIsWrapped = typeof listener === 'object';\n\t\tvar key;\n\n\t\tfor (key in listeners) {\n\t\t\tif (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {\n\t\t\t\tlisteners[key].push(listenerIsWrapped ? listener : {\n\t\t\t\t\tlistener: listener,\n\t\t\t\t\tonce: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Alias of addListener\n\t */\n\tproto.on = alias('addListener');\n\n\t/**\n\t * Semi-alias of addListener. It will add a listener that will be\n\t * automatically removed after it's first execution.\n\t *\n\t * @param {String|RegExp} evt Name of the event to attach the listener to.\n\t * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.addOnceListener = function addOnceListener(evt, listener) {\n\t\treturn this.addListener(evt, {\n\t\t\tlistener: listener,\n\t\t\tonce: true\n\t\t});\n\t};\n\n\t/**\n\t * Alias of addOnceListener.\n\t */\n\tproto.once = alias('addOnceListener');\n\n\t/**\n\t * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.\n\t * You need to tell it what event names should be matched by a regex.\n\t *\n\t * @param {String} evt Name of the event to create.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.defineEvent = function defineEvent(evt) {\n\t\tthis.getListeners(evt);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Uses defineEvent to define multiple events.\n\t *\n\t * @param {String[]} evts An array of event names to define.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.defineEvents = function defineEvents(evts) {\n\t\tfor (var i = 0; i < evts.length; i += 1) {\n\t\t\tthis.defineEvent(evts[i]);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Removes a listener function from the specified event.\n\t * When passed a regular expression as the event name, it will remove the listener from all events that match it.\n\t *\n\t * @param {String|RegExp} evt Name of the event to remove the listener from.\n\t * @param {Function} listener Method to remove from the event.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.removeListener = function removeListener(evt, listener) {\n\t\tvar listeners = this.getListenersAsObject(evt);\n\t\tvar index;\n\t\tvar key;\n\n\t\tfor (key in listeners) {\n\t\t\tif (listeners.hasOwnProperty(key)) {\n\t\t\t\tindex = indexOfListener(listeners[key], listener);\n\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\tlisteners[key].splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Alias of removeListener\n\t */\n\tproto.off = alias('removeListener');\n\n\t/**\n\t * Adds listeners in bulk using the manipulateListeners method.\n\t * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.\n\t * You can also pass it a regular expression to add the array of listeners to all events that match it.\n\t * Yeah, this function does quite a bit. That's probably a bad thing.\n\t *\n\t * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.\n\t * @param {Function[]} [listeners] An optional array of listener functions to add.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.addListeners = function addListeners(evt, listeners) {\n\t\t// Pass through to manipulateListeners\n\t\treturn this.manipulateListeners(false, evt, listeners);\n\t};\n\n\t/**\n\t * Removes listeners in bulk using the manipulateListeners method.\n\t * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n\t * You can also pass it an event name and an array of listeners to be removed.\n\t * You can also pass it a regular expression to remove the listeners from all events that match it.\n\t *\n\t * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.\n\t * @param {Function[]} [listeners] An optional array of listener functions to remove.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.removeListeners = function removeListeners(evt, listeners) {\n\t\t// Pass through to manipulateListeners\n\t\treturn this.manipulateListeners(true, evt, listeners);\n\t};\n\n\t/**\n\t * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.\n\t * The first argument will determine if the listeners are removed (true) or added (false).\n\t * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n\t * You can also pass it an event name and an array of listeners to be added/removed.\n\t * You can also pass it a regular expression to manipulate the listeners of all events that match it.\n\t *\n\t * @param {Boolean} remove True if you want to remove listeners, false if you want to add.\n\t * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.\n\t * @param {Function[]} [listeners] An optional array of listener functions to add/remove.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {\n\t\tvar i;\n\t\tvar value;\n\t\tvar single = remove ? this.removeListener : this.addListener;\n\t\tvar multiple = remove ? this.removeListeners : this.addListeners;\n\n\t\t// If evt is an object then pass each of it's properties to this method\n\t\tif (typeof evt === 'object' && !(evt instanceof RegExp)) {\n\t\t\tfor (i in evt) {\n\t\t\t\tif (evt.hasOwnProperty(i) && (value = evt[i])) {\n\t\t\t\t\t// Pass the single listener straight through to the singular method\n\t\t\t\t\tif (typeof value === 'function') {\n\t\t\t\t\t\tsingle.call(this, i, value);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t// Otherwise pass back to the multiple function\n\t\t\t\t\t\tmultiple.call(this, i, value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// So evt must be a string\n\t\t\t// And listeners must be an array of listeners\n\t\t\t// Loop over it and pass each one to the multiple method\n\t\t\ti = listeners.length;\n\t\t\twhile (i--) {\n\t\t\t\tsingle.call(this, evt, listeners[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Removes all listeners from a specified event.\n\t * If you do not specify an event then all listeners will be removed.\n\t * That means every event will be emptied.\n\t * You can also pass a regex to remove all events that match it.\n\t *\n\t * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.removeEvent = function removeEvent(evt) {\n\t\tvar type = typeof evt;\n\t\tvar events = this._getEvents();\n\t\tvar key;\n\n\t\t// Remove different things depending on the state of evt\n\t\tif (type === 'string') {\n\t\t\t// Remove all listeners for the specified event\n\t\t\tdelete events[evt];\n\t\t}\n\t\telse if (type === 'object') {\n\t\t\t// Remove all events matching the regex.\n\t\t\tfor (key in events) {\n\t\t\t\tif (events.hasOwnProperty(key) && evt.test(key)) {\n\t\t\t\t\tdelete events[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// Remove all listeners in all events\n\t\t\tdelete this._events;\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Alias of removeEvent.\n\t *\n\t * Added to mirror the node API.\n\t */\n\tproto.removeAllListeners = alias('removeEvent');\n\n\t/**\n\t * Emits an event of your choice.\n\t * When emitted, every listener attached to that event will be executed.\n\t * If you pass the optional argument array then those arguments will be passed to every listener upon execution.\n\t * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.\n\t * So they will not arrive within the array on the other side, they will be separate.\n\t * You can also pass a regular expression to emit to all events that match it.\n\t *\n\t * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n\t * @param {Array} [args] Optional array of arguments to be passed to each listener.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.emitEvent = function emitEvent(evt, args) {\n\t\tvar listeners = this.getListenersAsObject(evt);\n\t\tvar listener;\n\t\tvar i;\n\t\tvar key;\n\t\tvar response;\n\n\t\tfor (key in listeners) {\n\t\t\tif (listeners.hasOwnProperty(key)) {\n\t\t\t\ti = listeners[key].length;\n\n\t\t\t\twhile (i--) {\n\t\t\t\t\t// If the listener returns true then it shall be removed from the event\n\t\t\t\t\t// The function is executed either with a basic call or an apply if there is an args array\n\t\t\t\t\tlistener = listeners[key][i];\n\n\t\t\t\t\tif (listener.once === true) {\n\t\t\t\t\t\tthis.removeListener(evt, listener.listener);\n\t\t\t\t\t}\n\n\t\t\t\t\tresponse = listener.listener.apply(this, args || []);\n\n\t\t\t\t\tif (response === this._getOnceReturnValue()) {\n\t\t\t\t\t\tthis.removeListener(evt, listener.listener);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Alias of emitEvent\n\t */\n\tproto.trigger = alias('emitEvent');\n\n\t/**\n\t * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.\n\t * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.\n\t *\n\t * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n\t * @param {...*} Optional additional arguments to be passed to each listener.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.emit = function emit(evt) {\n\t\tvar args = Array.prototype.slice.call(arguments, 1);\n\t\treturn this.emitEvent(evt, args);\n\t};\n\n\t/**\n\t * Sets the current value to check against when executing listeners. If a\n\t * listeners return value matches the one set here then it will be removed\n\t * after execution. This value defaults to true.\n\t *\n\t * @param {*} value The new value to check for when executing listeners.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.setOnceReturnValue = function setOnceReturnValue(value) {\n\t\tthis._onceReturnValue = value;\n\t\treturn this;\n\t};\n\n\t/**\n\t * Fetches the current value to check against when executing listeners. If\n\t * the listeners return value matches this one then it should be removed\n\t * automatically. It will return true by default.\n\t *\n\t * @return {*|Boolean} The current value to check for or the default, true.\n\t * @api private\n\t */\n\tproto._getOnceReturnValue = function _getOnceReturnValue() {\n\t\tif (this.hasOwnProperty('_onceReturnValue')) {\n\t\t\treturn this._onceReturnValue;\n\t\t}\n\t\telse {\n\t\t\treturn true;\n\t\t}\n\t};\n\n\t/**\n\t * Fetches the events object and creates one if required.\n\t *\n\t * @return {Object} The events storage object.\n\t * @api private\n\t */\n\tproto._getEvents = function _getEvents() {\n\t\treturn this._events || (this._events = {});\n\t};\n\n\t/**\n\t * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.\n\t *\n\t * @return {Function} Non conflicting EventEmitter class.\n\t */\n\tEventEmitter.noConflict = function noConflict() {\n\t\texports.EventEmitter = originalGlobalValue;\n\t\treturn EventEmitter;\n\t};\n\n\t// Expose the class either via AMD, CommonJS or the global object\n\tif (typeof define === 'function' && define.amd) {\n\t\tdefine('eventEmitter/EventEmitter',[],function () {\n\t\t\treturn EventEmitter;\n\t\t});\n\t}\n\telse if (typeof module === 'object' && module.exports){\n\t\tmodule.exports = EventEmitter;\n\t}\n\telse {\n\t\tthis.EventEmitter = EventEmitter;\n\t}\n}.call(this));\n\n/*!\n * eventie v1.0.4\n * event binding helper\n *   eventie.bind( elem, 'click', myFn )\n *   eventie.unbind( elem, 'click', myFn )\n */\n\n/*jshint browser: true, undef: true, unused: true */\n/*global define: false */\n\n( function( window ) {\n\n\n\nvar docElem = document.documentElement;\n\nvar bind = function() {};\n\nfunction getIEEvent( obj ) {\n  var event = window.event;\n  // add event.target\n  event.target = event.target || event.srcElement || obj;\n  return event;\n}\n\nif ( docElem.addEventListener ) {\n  bind = function( obj, type, fn ) {\n    obj.addEventListener( type, fn, false );\n  };\n} else if ( docElem.attachEvent ) {\n  bind = function( obj, type, fn ) {\n    obj[ type + fn ] = fn.handleEvent ?\n      function() {\n        var event = getIEEvent( obj );\n        fn.handleEvent.call( fn, event );\n      } :\n      function() {\n        var event = getIEEvent( obj );\n        fn.call( obj, event );\n      };\n    obj.attachEvent( \"on\" + type, obj[ type + fn ] );\n  };\n}\n\nvar unbind = function() {};\n\nif ( docElem.removeEventListener ) {\n  unbind = function( obj, type, fn ) {\n    obj.removeEventListener( type, fn, false );\n  };\n} else if ( docElem.detachEvent ) {\n  unbind = function( obj, type, fn ) {\n    obj.detachEvent( \"on\" + type, obj[ type + fn ] );\n    try {\n      delete obj[ type + fn ];\n    } catch ( err ) {\n      // can't delete window object properties\n      obj[ type + fn ] = undefined;\n    }\n  };\n}\n\nvar eventie = {\n  bind: bind,\n  unbind: unbind\n};\n\n// transport\nif ( typeof define === 'function' && define.amd ) {\n  // AMD\n  define( 'eventie/eventie',eventie );\n} else {\n  // browser global\n  window.eventie = eventie;\n}\n\n})( this );\n\n/*!\n * imagesLoaded v3.1.8\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n\n( function( window, factory ) { \n  // universal module definition\n\n  /*global define: false, module: false, require: false */\n\n  if ( typeof define === 'function' && define.amd ) {\n    // AMD\n    define( [\n      'eventEmitter/EventEmitter',\n      'eventie/eventie'\n    ], function( EventEmitter, eventie ) {\n      return factory( window, EventEmitter, eventie );\n    });\n  } else if ( typeof exports === 'object' ) {\n    // CommonJS\n    module.exports = factory(\n      window,\n      require('wolfy87-eventemitter'),\n      require('eventie')\n    );\n  } else {\n    // browser global\n    window.imagesLoaded = factory(\n      window,\n      window.EventEmitter,\n      window.eventie\n    );\n  }\n\n})( window,\n\n// --------------------------  factory -------------------------- //\n\nfunction factory( window, EventEmitter, eventie ) {\n\n\n\nvar $ = window.jQuery;\nvar console = window.console;\nvar hasConsole = typeof console !== 'undefined';\n\n// -------------------------- helpers -------------------------- //\n\n// extend objects\nfunction extend( a, b ) {\n  for ( var prop in b ) {\n    a[ prop ] = b[ prop ];\n  }\n  return a;\n}\n\nvar objToString = Object.prototype.toString;\nfunction isArray( obj ) {\n  return objToString.call( obj ) === '[object Array]';\n}\n\n// turn element or nodeList into an array\nfunction makeArray( obj ) {\n  var ary = [];\n  if ( isArray( obj ) ) {\n    // use object if already an array\n    ary = obj;\n  } else if ( typeof obj.length === 'number' ) {\n    // convert nodeList to array\n    for ( var i=0, len = obj.length; i < len; i++ ) {\n      ary.push( obj[i] );\n    }\n  } else {\n    // array of single index\n    ary.push( obj );\n  }\n  return ary;\n}\n\n  // -------------------------- imagesLoaded -------------------------- //\n\n  /**\n   * @param {Array, Element, NodeList, String} elem\n   * @param {Object or Function} options - if function, use as callback\n   * @param {Function} onAlways - callback function\n   */\n  function ImagesLoaded( elem, options, onAlways ) {\n    // coerce ImagesLoaded() without new, to be new ImagesLoaded()\n    if ( !( this instanceof ImagesLoaded ) ) {\n      return new ImagesLoaded( elem, options );\n    }\n    // use elem as selector string\n    if ( typeof elem === 'string' ) {\n      elem = document.querySelectorAll( elem );\n    }\n\n    this.elements = makeArray( elem );\n    this.options = extend( {}, this.options );\n\n    if ( typeof options === 'function' ) {\n      onAlways = options;\n    } else {\n      extend( this.options, options );\n    }\n\n    if ( onAlways ) {\n      this.on( 'always', onAlways );\n    }\n\n    this.getImages();\n\n    if ( $ ) {\n      // add jQuery Deferred object\n      this.jqDeferred = new $.Deferred();\n    }\n\n    // HACK check async to allow time to bind listeners\n    var _this = this;\n    setTimeout( function() {\n      _this.check();\n    });\n  }\n\n  ImagesLoaded.prototype = new EventEmitter();\n\n  ImagesLoaded.prototype.options = {};\n\n  ImagesLoaded.prototype.getImages = function() {\n    this.images = [];\n\n    // filter & find items if we have an item selector\n    for ( var i=0, len = this.elements.length; i < len; i++ ) {\n      var elem = this.elements[i];\n      // filter siblings\n      if ( elem.nodeName === 'IMG' ) {\n        this.addImage( elem );\n      }\n      // find children\n      // no non-element nodes, #143\n      var nodeType = elem.nodeType;\n      if ( !nodeType || !( nodeType === 1 || nodeType === 9 || nodeType === 11 ) ) {\n        continue;\n      }\n      var childElems = elem.querySelectorAll('img');\n      // concat childElems to filterFound array\n      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {\n        var img = childElems[j];\n        this.addImage( img );\n      }\n    }\n  };\n\n  /**\n   * @param {Image} img\n   */\n  ImagesLoaded.prototype.addImage = function( img ) {\n    var loadingImage = new LoadingImage( img );\n    this.images.push( loadingImage );\n  };\n\n  ImagesLoaded.prototype.check = function() {\n    var _this = this;\n    var checkedCount = 0;\n    var length = this.images.length;\n    this.hasAnyBroken = false;\n    // complete if no images\n    if ( !length ) {\n      this.complete();\n      return;\n    }\n\n    function onConfirm( image, message ) {\n      if ( _this.options.debug && hasConsole ) {\n        console.log( 'confirm', image, message );\n      }\n\n      _this.progress( image );\n      checkedCount++;\n      if ( checkedCount === length ) {\n        _this.complete();\n      }\n      return true; // bind once\n    }\n\n    for ( var i=0; i < length; i++ ) {\n      var loadingImage = this.images[i];\n      loadingImage.on( 'confirm', onConfirm );\n      loadingImage.check();\n    }\n  };\n\n  ImagesLoaded.prototype.progress = function( image ) {\n    this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;\n    // HACK - Chrome triggers event before object properties have changed. #83\n    var _this = this;\n    setTimeout( function() {\n      _this.emit( 'progress', _this, image );\n      if ( _this.jqDeferred && _this.jqDeferred.notify ) {\n        _this.jqDeferred.notify( _this, image );\n      }\n    });\n  };\n\n  ImagesLoaded.prototype.complete = function() {\n    var eventName = this.hasAnyBroken ? 'fail' : 'done';\n    this.isComplete = true;\n    var _this = this;\n    // HACK - another setTimeout so that confirm happens after progress\n    setTimeout( function() {\n      _this.emit( eventName, _this );\n      _this.emit( 'always', _this );\n      if ( _this.jqDeferred ) {\n        var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve';\n        _this.jqDeferred[ jqMethod ]( _this );\n      }\n    });\n  };\n\n  // -------------------------- jquery -------------------------- //\n\n  if ( $ ) {\n    $.fn.imagesLoaded = function( options, callback ) {\n      var instance = new ImagesLoaded( this, options, callback );\n      return instance.jqDeferred.promise( $(this) );\n    };\n  }\n\n\n  // --------------------------  -------------------------- //\n\n  function LoadingImage( img ) {\n    this.img = img;\n  }\n\n  LoadingImage.prototype = new EventEmitter();\n\n  LoadingImage.prototype.check = function() {\n    // first check cached any previous images that have same src\n    var resource = cache[ this.img.src ] || new Resource( this.img.src );\n    if ( resource.isConfirmed ) {\n      this.confirm( resource.isLoaded, 'cached was confirmed' );\n      return;\n    }\n\n    // If complete is true and browser supports natural sizes,\n    // try to check for image status manually.\n    if ( this.img.complete && this.img.naturalWidth !== undefined ) {\n      // report based on naturalWidth\n      this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );\n      return;\n    }\n\n    // If none of the checks above matched, simulate loading on detached element.\n    var _this = this;\n    resource.on( 'confirm', function( resrc, message ) {\n      _this.confirm( resrc.isLoaded, message );\n      return true;\n    });\n\n    resource.check();\n  };\n\n  LoadingImage.prototype.confirm = function( isLoaded, message ) {\n    this.isLoaded = isLoaded;\n    this.emit( 'confirm', this, message );\n  };\n\n  // -------------------------- Resource -------------------------- //\n\n  // Resource checks each src, only once\n  // separate class from LoadingImage to prevent memory leaks. See #115\n\n  var cache = {};\n\n  function Resource( src ) {\n    this.src = src;\n    // add to cache\n    cache[ src ] = this;\n  }\n\n  Resource.prototype = new EventEmitter();\n\n  Resource.prototype.check = function() {\n    // only trigger checking once\n    if ( this.isChecked ) {\n      return;\n    }\n    // simulate loading on detached element\n    var proxyImage = new Image();\n    eventie.bind( proxyImage, 'load', this );\n    eventie.bind( proxyImage, 'error', this );\n    proxyImage.src = this.src;\n    // set flag\n    this.isChecked = true;\n  };\n\n  // ----- events ----- //\n\n  // trigger specified handler for event type\n  Resource.prototype.handleEvent = function( event ) {\n    var method = 'on' + event.type;\n    if ( this[ method ] ) {\n      this[ method ]( event );\n    }\n  };\n\n  Resource.prototype.onload = function( event ) {\n    this.confirm( true, 'onload' );\n    this.unbindProxyEvents( event );\n  };\n\n  Resource.prototype.onerror = function( event ) {\n    this.confirm( false, 'onerror' );\n    this.unbindProxyEvents( event );\n  };\n\n  // ----- confirm ----- //\n\n  Resource.prototype.confirm = function( isLoaded, message ) {\n    this.isConfirmed = true;\n    this.isLoaded = isLoaded;\n    this.emit( 'confirm', this, message );\n  };\n\n  Resource.prototype.unbindProxyEvents = function( event ) {\n    eventie.unbind( event.target, 'load', this );\n    eventie.unbind( event.target, 'error', this );\n  };\n\n  // -----  ----- //\n\n  return ImagesLoaded;\n\n});\n/**\n *   Unslider by @idiot\n */\n\n(function($, f) {\n\t//  If there's no jQuery, Unslider can't work, so kill the operation.\n\tif(!$) return f;\n\n\tvar Unslider = function() {\n\t\t//  Set up our elements\n\t\tthis.el = f;\n\t\tthis.items = f;\n\n\t\t//  Dimensions\n\t\tthis.sizes = [];\n\t\tthis.max = [0,0];\n\n\t\t//  Current inded\n\t\tthis.current = 0;\n\n\t\t//  Start/stop timer\n\t\tthis.interval = f;\n\n\t\t//  Set some options\n\t\tthis.opts = {\n\t\t\tspeed: 500,\n\t\t\tdelay: 3000, // f for no autoplay\n\t\t\tcomplete: f, // when a slide's finished\n\t\t\tkeys: !f, // keyboard shortcuts - disable if it breaks things\n\t\t\tdots: f, // display â€¢â€¢â€¢â€¢oâ€¢ pagination\n\t\t\tfluid: f // is it a percentage width?,\n\t\t};\n\n\t\t//  Create a deep clone for methods where context changes\n\t\tvar _ = this;\n\n\t\tthis.init = function(el, opts) {\n\t\t\tthis.el = el;\n\t\t\tthis.ul = el.children('ul');\n\t\t\tthis.max = [el.outerWidth(), el.outerHeight()];\n\t\t\tthis.items = this.ul.children('li').each(this.calculate);\n\n\t\t\t//  Check whether we're passing any options in to Unslider\n\t\t\tthis.opts = $.extend(this.opts, opts);\n\n\t\t\t//  Set up the Unslider\n\t\t\tthis.setup();\n\n\t\t\treturn this;\n\t\t};\n\n\t\t//  Get the width for an element\n\t\t//  Pass a jQuery element as the context with .call(), and the index as a parameter: Unslider.calculate.call($('li:first'), 0)\n\t\tthis.calculate = function(index) {\n\t\t\tvar me = $(this),\n\t\t\t\twidth = me.outerWidth(), height = me.outerHeight();\n\n\t\t\t//  Add it to the sizes list\n\t\t\t_.sizes[index] = [width, height];\n\n\t\t\t//  Set the max values\n\t\t\tif(width > _.max[0]) _.max[0] = width;\n\t\t\tif(height > _.max[1]) _.max[1] = height;\n\t\t};\n\n\t\t//  Work out what methods need calling\n\t\tthis.setup = function() {\n\t\t\t//  Set the main element\n\t\t\tthis.el.css({\n\t\t\t\toverflow: 'hidden',\n\t\t\t\twidth: _.max[0],\n\t\t\t\theight: this.items.first().outerHeight()\n\t\t\t});\n\n\t\t\t//  Set the relative widths\n\t\t\tthis.ul.css({width: (this.items.length * 100) + '%', position: 'relative'});\n\t\t\tthis.items.css('width', (100 / this.items.length) + '%');\n\n\t\t\tif(this.opts.delay !== f) {\n\t\t\t\tthis.start();\n\t\t\t\tthis.el.hover(this.stop, this.start);\n\t\t\t}\n\n\t\t\t//  Custom keyboard support\n\t\t\tthis.opts.keys && $(document).keydown(this.keys);\n\n\t\t\t//  Dot pagination\n\t\t\tthis.opts.dots && this.dots();\n\n\t\t\t//  Little patch for fluid-width sliders. Screw those guys.\n\t\t\tif(this.opts.fluid) {\n\t\t\t\tvar resize = function() {\n\t\t\t\t\t_.el.css('width', Math.min(Math.round((_.el.outerWidth() / _.el.parent().outerWidth()) * 100), 100) + '%');\n\t\t\t\t};\n\n\t\t\t\tresize();\n\t\t\t\t$(window).resize(resize);\n\t\t\t}\n\n\t\t\tif(this.opts.arrows) {\n\t\t\t\tthis.el.parent().append('<p class=\"arrows\"><span class=\"prev\">â†</span><span class=\"next\">â†’</span></p>')\n\t\t\t\t\t.find('.arrows span').click(function() {\n\t\t\t\t\t\t$.isFunction(_[this.className]) && _[this.className]();\n\t\t\t\t\t});\n\t\t\t};\n\n\t\t\t//  Swipe support\n\t\t\tif($.event.swipe) {\n\t\t\t\tthis.el.on('swipeleft', _.prev).on('swiperight', _.next);\n\t\t\t}\n\t\t};\n\n\t\t//  Move Unslider to a slide index\n\t\tthis.move = function(index, cb) {\n\t\t\t//  If it's out of bounds, go to the first slide\n\t\t\tif(!this.items.eq(index).length) index = 0;\n\t\t\tif(index < 0) index = (this.items.length - 1);\n\n\t\t\tvar target = this.items.eq(index);\n\t\t\tvar obj = {height: target.outerHeight()};\n\t\t\tvar speed = cb ? 5 : this.opts.speed;\n\n\t\t\tif(!this.ul.is(':animated')) {\n\t\t\t\t//  Handle those pesky dots\n\t\t\t\t_.el.find('.dot:eq(' + index + ')').addClass('active').siblings().removeClass('active');\n\n\t\t\t\tthis.el.animate(obj, speed) && this.ul.animate($.extend({left: '-' + index + '00%'}, obj), speed, function(data) {\n\t\t\t\t\t_.current = index;\n\t\t\t\t\t$.isFunction(_.opts.complete) && !cb && _.opts.complete(_.el);\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\t//  Autoplay functionality\n\t\tthis.start = function() {\n\t\t\t_.interval = setInterval(function() {\n\t\t\t\t_.move(_.current + 1);\n\t\t\t}, _.opts.delay);\n\t\t};\n\n\t\t//  Stop autoplay\n\t\tthis.stop = function() {\n\t\t\t_.interval = clearInterval(_.interval);\n\t\t\treturn _;\n\t\t};\n\n\t\t//  Keypresses\n\t\tthis.keys = function(e) {\n\t\t\tvar key = e.which;\n\t\t\tvar map = {\n\t\t\t\t//  Prev/next\n\t\t\t\t37: _.prev,\n\t\t\t\t39: _.next,\n\n\t\t\t\t//  Esc\n\t\t\t\t27: _.stop\n\t\t\t};\n\n\t\t\tif($.isFunction(map[key])) {\n\t\t\t\tmap[key]();\n\t\t\t}\n\t\t};\n\n\t\t//  Arrow navigation\n\t\tthis.next = function() { return _.stop().move(_.current + 1) };\n\t\tthis.prev = function() { return _.stop().move(_.current - 1) };\n\n\t\tthis.dots = function() {\n\t\t\t//  Create the HTML\n\t\t\tvar html = '<ol class=\"dots\">';\n\t\t\t\t$.each(this.items, function(index) { html += '<li class=\"dot' + (index < 1 ? ' active' : '') + '\">' + (index + 1) + '</li>'; });\n\t\t\t\thtml += '</ol>';\n\n\t\t\t//  Add it to the Unslider\n\t\t\tthis.el.addClass('has-dots').append(html).find('.dot').click(function() {\n\t\t\t\t_.move($(this).index());\n\t\t\t});\n\t\t};\n\t};\n\n\t//  Create a jQuery plugin\n\t$.fn.unslider = function(o) {\n\t\tvar len = this.length;\n\n\t\t//  Enable multiple-slider support\n\t\treturn this.each(function(index) {\n\t\t\t//  Cache a copy of $(this), so it\n\t\t\tvar me = $(this);\n\t\t\tvar instance = (new Unslider).init(me, o);\n\n\t\t\t//  Invoke an Unslider instance\n\t\t\tme.data('unslider' + (len > 1 ? '-' + (index + 1) : ''), instance);\n\t\t});\n\t};\n})(window.jQuery, false);\n/*!\n * jQuery UI Touch Punch 0.2.3\n *\n * Copyright 2011–2014, Dave Furfero\n * Dual licensed under the MIT or GPL Version 2 licenses.\n *\n * Depends:\n *  jquery.ui.widget.js\n *  jquery.ui.mouse.js\n */\n(function ($) {\n\n  // Detect touch support\n  $.support.touch = 'ontouchend' in document;\n\n  // Ignore browsers without touch support\n  if (!$.support.touch) {\n    return;\n  }\n\n  var mouseProto = $.ui.mouse.prototype,\n      _mouseInit = mouseProto._mouseInit,\n      _mouseDestroy = mouseProto._mouseDestroy,\n      touchHandled;\n\n  /**\n   * Simulate a mouse event based on a corresponding touch event\n   * @param {Object} event A touch event\n   * @param {String} simulatedType The corresponding mouse event\n   */\n  function simulateMouseEvent (event, simulatedType) {\n\n    // Ignore multi-touch events\n    if (event.originalEvent.touches.length > 1) {\n      return;\n    }\n\n    event.preventDefault();\n\n    var touch = event.originalEvent.changedTouches[0],\n        simulatedEvent = document.createEvent('MouseEvents');\n    \n    // Initialize the simulated mouse event using the touch event's coordinates\n    simulatedEvent.initMouseEvent(\n      simulatedType,    // type\n      true,             // bubbles                    \n      true,             // cancelable                 \n      window,           // view                       \n      1,                // detail                     \n      touch.screenX,    // screenX                    \n      touch.screenY,    // screenY                    \n      touch.clientX,    // clientX                    \n      touch.clientY,    // clientY                    \n      false,            // ctrlKey                    \n      false,            // altKey                     \n      false,            // shiftKey                   \n      false,            // metaKey                    \n      0,                // button                     \n      null              // relatedTarget              \n    );\n\n    // Dispatch the simulated event to the target element\n    event.target.dispatchEvent(simulatedEvent);\n  }\n\n  /**\n   * Handle the jQuery UI widget's touchstart events\n   * @param {Object} event The widget element's touchstart event\n   */\n  mouseProto._touchStart = function (event) {\n\n    var self = this;\n\n    // Ignore the event if another widget is already being handled\n    if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {\n      return;\n    }\n\n    // Set the flag to prevent other widgets from inheriting the touch event\n    touchHandled = true;\n\n    // Track movement to determine if interaction was a click\n    self._touchMoved = false;\n\n    // Simulate the mouseover event\n    simulateMouseEvent(event, 'mouseover');\n\n    // Simulate the mousemove event\n    simulateMouseEvent(event, 'mousemove');\n\n    // Simulate the mousedown event\n    simulateMouseEvent(event, 'mousedown');\n  };\n\n  /**\n   * Handle the jQuery UI widget's touchmove events\n   * @param {Object} event The document's touchmove event\n   */\n  mouseProto._touchMove = function (event) {\n\n    // Ignore event if not handled\n    if (!touchHandled) {\n      return;\n    }\n\n    // Interaction was not a click\n    this._touchMoved = true;\n\n    // Simulate the mousemove event\n    simulateMouseEvent(event, 'mousemove');\n  };\n\n  /**\n   * Handle the jQuery UI widget's touchend events\n   * @param {Object} event The document's touchend event\n   */\n  mouseProto._touchEnd = function (event) {\n\n    // Ignore event if not handled\n    if (!touchHandled) {\n      return;\n    }\n\n    // Simulate the mouseup event\n    simulateMouseEvent(event, 'mouseup');\n\n    // Simulate the mouseout event\n    simulateMouseEvent(event, 'mouseout');\n\n    // If the touch interaction did not move, it should trigger a click\n    if (!this._touchMoved) {\n\n      // Simulate the click event\n      simulateMouseEvent(event, 'click');\n    }\n\n    // Unset the flag to allow other widgets to inherit the touch event\n    touchHandled = false;\n  };\n\n  /**\n   * A duck punch of the $.ui.mouse _mouseInit method to support touch events.\n   * This method extends the widget with bound touch event handlers that\n   * translate touch events to mouse events and pass them to the widget's\n   * original mouse event handling methods.\n   */\n  mouseProto._mouseInit = function () {\n    \n    var self = this;\n\n    // Delegate the touch handlers to the widget's element\n    self.element.bind({\n      touchstart: $.proxy(self, '_touchStart'),\n      touchmove: $.proxy(self, '_touchMove'),\n      touchend: $.proxy(self, '_touchEnd')\n    });\n\n    // Call the original $.ui.mouse init method\n    _mouseInit.call(self);\n  };\n\n  /**\n   * Remove the touch event handlers\n   */\n  mouseProto._mouseDestroy = function () {\n    \n    var self = this;\n\n    // Delegate the touch handlers to the widget's element\n    self.element.unbind({\n      touchstart: $.proxy(self, '_touchStart'),\n      touchmove: $.proxy(self, '_touchMove'),\n      touchend: $.proxy(self, '_touchEnd')\n    });\n\n    // Call the original $.ui.mouse destroy method\n    _mouseDestroy.call(self);\n  };\n\n})(jQuery);\n/*\n* jQuery UI Tag-it!\n*\n* @version v2.0 (06/2011)\n*\n* Copyright 2011, Levy Carneiro Jr.\n* Released under the MIT license.\n* http://aehlke.github.com/tag-it/LICENSE\n*\n* Homepage:\n*   http://aehlke.github.com/tag-it/\n*\n* Authors:\n*   Levy Carneiro Jr.\n*   Martin Rehfeld\n*   Tobias Schmidt\n*   Skylar Challand\n*   Alex Ehlke\n*\n* Maintainer:\n*   Alex Ehlke - Twitter: @aehlke\n*\n* Dependencies:\n*   jQuery v1.4+\n*   jQuery UI v1.8+\n*/\n(function($) {\n\n    $.widget('ui.tagit', {\n        options: {\n            allowDuplicates   : false,\n            caseSensitive     : true,\n            fieldName         : 'tags',\n            placeholderText   : null,   // Sets `placeholder` attr on input field.\n            readOnly          : false,  // Disables editing.\n            removeConfirmation: false,  // Require confirmation to remove tags.\n            tagLimit          : null,   // Max number of tags allowed (null for unlimited).\n\n            // Used for autocomplete, unless you override `autocomplete.source`.\n            availableTags     : [],\n\n            // Use to override or add any options to the autocomplete widget.\n            //\n            // By default, autocomplete.source will map to availableTags,\n            // unless overridden.\n            autocomplete: {},\n\n            // Shows autocomplete before the user even types anything.\n            showAutocompleteOnFocus: true,\n\n            // When enabled, quotes are unneccesary for inputting multi-word tags.\n            allowSpaces: false,\n\n            // The below options are for using a single field instead of several\n            // for our form values.\n            //\n            // When enabled, will use a single hidden field for the form,\n            // rather than one per tag. It will delimit tags in the field\n            // with singleFieldDelimiter.\n            //\n            // The easiest way to use singleField is to just instantiate tag-it\n            // on an INPUT element, in which case singleField is automatically\n            // set to true, and singleFieldNode is set to that element. This\n            // way, you don't need to fiddle with these options.\n            singleField: false,\n\n            // This is just used when preloading data from the field, and for\n            // populating the field with delimited tags as the user adds them.\n            singleFieldDelimiter: ',',\n\n            // Set this to an input DOM node to use an existing form field.\n            // Any text in it will be erased on init. But it will be\n            // populated with the text of tags as they are created,\n            // delimited by singleFieldDelimiter.\n            //\n            // If this is not set, we create an input node for it,\n            // with the name given in settings.fieldName.\n            singleFieldNode: null,\n\n            // Whether to animate tag removals or not.\n            animate: true,\n\n            // Optionally set a tabindex attribute on the input that gets\n            // created for tag-it.\n            tabIndex: null,\n\n            // Event callbacks.\n            beforeTagAdded      : null,\n            afterTagAdded       : null,\n\n            beforeTagRemoved    : null,\n            afterTagRemoved     : null,\n\n            onTagClicked        : null,\n            onTagLimitExceeded  : null,\n\n\n            // DEPRECATED:\n            //\n            // /!\\ These event callbacks are deprecated and WILL BE REMOVED at some\n            // point in the future. They're here for backwards-compatibility.\n            // Use the above before/after event callbacks instead.\n            onTagAdded  : null,\n            onTagRemoved: null,\n            // `autocomplete.source` is the replacement for tagSource.\n            tagSource: null\n            // Do not use the above deprecated options.\n        },\n\n        _create: function() {\n            // for handling static scoping inside callbacks\n            var that = this;\n\n            // There are 2 kinds of DOM nodes this widget can be instantiated on:\n            //     1. UL, OL, or some element containing either of these.\n            //     2. INPUT, in which case 'singleField' is overridden to true,\n            //        a UL is created and the INPUT is hidden.\n            if (this.element.is('input')) {\n                this.tagList = $('<ul></ul>').insertAfter(this.element);\n                this.options.singleField = true;\n                this.options.singleFieldNode = this.element;\n                this.element.addClass('tagit-hidden-field');\n            } else {\n                this.tagList = this.element.find('ul, ol').andSelf().last();\n            }\n\n            this.tagInput = $('<input type=\"text\" />').addClass('ui-widget-content');\n\n            if (this.options.readOnly) this.tagInput.attr('disabled', 'disabled');\n\n            if (this.options.tabIndex) {\n                this.tagInput.attr('tabindex', this.options.tabIndex);\n            }\n\n            if (this.options.placeholderText) {\n                this.tagInput.attr('placeholder', this.options.placeholderText);\n            }\n\n            if (!this.options.autocomplete.source) {\n                this.options.autocomplete.source = function(search, showChoices) {\n                    var filter = search.term.toLowerCase();\n\t\t\t\t\tif (this.options.availableTags) {\n\t\t\t\t\t\tvar choices = $.grep(this.options.availableTags.split(\",\"), function(element) {\n\t\t\t\t\t\t\t// Only match autocomplete options that begin with the search term.\n\t\t\t\t\t\t\t// (Case insensitive.)\n\t\t\t\t\t\t\treturn (element.toLowerCase().indexOf(filter) === 0);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (!this.options.allowDuplicates) {\n\t\t\t\t\t\t\tchoices = this._subtractArray(choices, this.assignedTags());\n\t\t\t\t\t\t}\n\t\t\t\t\t\tshowChoices(choices);\n\t\t\t\t\t}\n                };\n            }\n\n            if (this.options.showAutocompleteOnFocus) {\n                this.tagInput.focus(function(event, ui) {\n                    that._showAutocomplete();\n                });\n\n                if (typeof this.options.autocomplete.minLength === 'undefined') {\n                    this.options.autocomplete.minLength = 0;\n                }\n            }\n\n            // Bind autocomplete.source callback functions to this context.\n            if ($.isFunction(this.options.autocomplete.source)) {\n                this.options.autocomplete.source = $.proxy(this.options.autocomplete.source, this);\n            }\n\n            // DEPRECATED.\n            if ($.isFunction(this.options.tagSource)) {\n                this.options.tagSource = $.proxy(this.options.tagSource, this);\n            }\n\n            this.tagList\n                .addClass('tagit')\n                .addClass('ui-widget ui-widget-content ui-corner-all')\n                // Create the input field.\n                .append($('<li class=\"tagit-new\"></li>').append(this.tagInput))\n                .click(function(e) {\n                    var target = $(e.target);\n                    if (target.hasClass('tagit-label')) {\n                        var tag = target.closest('.tagit-choice');\n                        if (!tag.hasClass('removed')) {\n                            that._trigger('onTagClicked', e, {tag: tag, tagLabel: that.tagLabel(tag)});\n                        }\n                    } else {\n                        // Sets the focus() to the input field, if the user\n                        // clicks anywhere inside the UL. This is needed\n                        // because the input field needs to be of a small size.\n                        that.tagInput.focus();\n                    }\n                });\n\n            // Single field support.\n            var addedExistingFromSingleFieldNode = false;\n            if (this.options.singleField) {\n                if (this.options.singleFieldNode) {\n                    // Add existing tags from the input field.\n                    var node = $(this.options.singleFieldNode);\n                    var tags = node.val().split(this.options.singleFieldDelimiter);\n                    node.val('');\n                    $.each(tags, function(index, tag) {\n                        that.createTag(tag, null, true);\n                        addedExistingFromSingleFieldNode = true;\n                    });\n                } else {\n                    // Create our single field input after our list.\n                    this.options.singleFieldNode = $('<input type=\"hidden\" style=\"display:none;\" value=\"\" name=\"' + this.options.fieldName + '\" />');\n                    this.tagList.after(this.options.singleFieldNode);\n                }\n            }\n\n            // Add existing tags from the list, if any.\n            if (!addedExistingFromSingleFieldNode) {\n                this.tagList.children('li').each(function() {\n                    if (!$(this).hasClass('tagit-new')) {\n                        that.createTag($(this).text(), $(this).attr('class'), true);\n                        $(this).remove();\n                    }\n                });\n            }\n\n            // Events.\n            this.tagInput\n                .keydown(function(event) {\n                    // Backspace is not detected within a keypress, so it must use keydown.\n                    if (event.which == $.ui.keyCode.BACKSPACE && that.tagInput.val() === '') {\n                        var tag = that._lastTag();\n                        if (!that.options.removeConfirmation || tag.hasClass('remove')) {\n                            // When backspace is pressed, the last tag is deleted.\n                            that.removeTag(tag);\n                        } else if (that.options.removeConfirmation) {\n                            tag.addClass('remove ui-state-highlight');\n                        }\n                    } else if (that.options.removeConfirmation) {\n                        that._lastTag().removeClass('remove ui-state-highlight');\n                    }\n\n                    // Comma/Space/Enter are all valid delimiters for new tags,\n                    // except when there is an open quote or if setting allowSpaces = true.\n                    // Tab will also create a tag, unless the tag input is empty,\n                    // in which case it isn't caught.\n                    if (\n                        (event.which === $.ui.keyCode.COMMA && event.shiftKey === false) ||\n                        event.which === $.ui.keyCode.ENTER ||\n                        (\n                            event.which == $.ui.keyCode.TAB &&\n                            that.tagInput.val() !== ''\n                        ) ||\n                        (\n                            event.which == $.ui.keyCode.SPACE &&\n                            that.options.allowSpaces !== true &&\n                            (\n                                $.trim(that.tagInput.val()).replace( /^s*/, '' ).charAt(0) != '\"' ||\n                                (\n                                    $.trim(that.tagInput.val()).charAt(0) == '\"' &&\n                                    $.trim(that.tagInput.val()).charAt($.trim(that.tagInput.val()).length - 1) == '\"' &&\n                                    $.trim(that.tagInput.val()).length - 1 !== 0\n                                )\n                            )\n                        )\n                    ) {\n                        // Enter submits the form if there's no text in the input.\n                        if (!(event.which === $.ui.keyCode.ENTER && that.tagInput.val() === '')) {\n                            event.preventDefault();\n                        }\n\n                        // Autocomplete will create its own tag from a selection and close automatically.\n                        if (!(that.options.autocomplete.autoFocus && that.tagInput.data('autocomplete-open'))) {\n                            that.tagInput.autocomplete('close');\n                            that.createTag(that._cleanedInput());\n                        }\n                    }\n                }).blur(function(e){\n                    // Create a tag when the element loses focus.\n                    // If autocomplete is enabled and suggestion was clicked, don't add it.\n                    if (!that.tagInput.data('autocomplete-open')) {\n                        that.createTag(that._cleanedInput());\n                    }\n                });\n\n            // Autocomplete.\n            if (this.options.availableTags || this.options.tagSource || this.options.autocomplete.source) {\n                var autocompleteOptions = {\n                    select: function(event, ui) {\n                        that.createTag(ui.item.value);\n                        // Preventing the tag input to be updated with the chosen value.\n                        return false;\n                    }\n                };\n                $.extend(autocompleteOptions, this.options.autocomplete);\n\n                // tagSource is deprecated, but takes precedence here since autocomplete.source is set by default,\n                // while tagSource is left null by default.\n                autocompleteOptions.source = this.options.tagSource || autocompleteOptions.source;\n\n                this.tagInput.autocomplete(autocompleteOptions).bind('autocompleteopen.tagit', function(event, ui) {\n                    that.tagInput.data('autocomplete-open', true);\n                }).bind('autocompleteclose.tagit', function(event, ui) {\n                    that.tagInput.data('autocomplete-open', false);\n                });\n\n                this.tagInput.autocomplete('widget').addClass('tagit-autocomplete');\n            }\n        },\n\n        destroy: function() {\n            $.Widget.prototype.destroy.call(this);\n\n            this.element.unbind('.tagit');\n            this.tagList.unbind('.tagit');\n\n            this.tagInput.removeData('autocomplete-open');\n\n            this.tagList.removeClass([\n                'tagit',\n                'ui-widget',\n                'ui-widget-content',\n                'ui-corner-all',\n                'tagit-hidden-field'\n            ].join(' '));\n\n            if (this.element.is('input')) {\n                this.element.removeClass('tagit-hidden-field');\n                this.tagList.remove();\n            } else {\n                this.element.children('li').each(function() {\n                    if ($(this).hasClass('tagit-new')) {\n                        $(this).remove();\n                    } else {\n                        $(this).removeClass([\n                            'tagit-choice',\n                            'ui-widget-content',\n                            'ui-state-default',\n                            'ui-state-highlight',\n                            'ui-corner-all',\n                            'remove',\n                            'tagit-choice-editable',\n                            'tagit-choice-read-only'\n                        ].join(' '));\n\n                        $(this).text($(this).children('.tagit-label').text());\n                    }\n                });\n\n                if (this.singleFieldNode) {\n                    this.singleFieldNode.remove();\n                }\n            }\n\n            return this;\n        },\n\n        _cleanedInput: function() {\n            // Returns the contents of the tag input, cleaned and ready to be passed to createTag\n            return $.trim(this.tagInput.val().replace(/^\"(.*)\"$/, '$1'));\n        },\n\n        _lastTag: function() {\n            return this.tagList.find('.tagit-choice:last:not(.removed)');\n        },\n\n        _tags: function() {\n            return this.tagList.find('.tagit-choice:not(.removed)');\n        },\n\n        assignedTags: function() {\n            // Returns an array of tag string values\n            var that = this;\n            var tags = [];\n            if (this.options.singleField) {\n                tags = $(this.options.singleFieldNode).val().split(this.options.singleFieldDelimiter);\n                if (tags[0] === '') {\n                    tags = [];\n                }\n            } else {\n                this._tags().each(function() {\n                    tags.push(that.tagLabel(this));\n                });\n            }\n            return tags;\n        },\n\n        _updateSingleTagsField: function(tags) {\n            // Takes a list of tag string values, updates this.options.singleFieldNode.val to the tags delimited by this.options.singleFieldDelimiter\n            $(this.options.singleFieldNode).val(tags.join(this.options.singleFieldDelimiter)).trigger('change');\n        },\n\n        _subtractArray: function(a1, a2) {\n            var result = [];\n            for (var i = 0; i < a1.length; i++) {\n                if ($.inArray(a1[i], a2) == -1) {\n                    result.push(a1[i]);\n                }\n            }\n            return result;\n        },\n\n        tagLabel: function(tag) {\n            // Returns the tag's string label.\n            if (this.options.singleField) {\n                return $(tag).find('.tagit-label:first').text();\n            } else {\n                return $(tag).find('input:first').val();\n            }\n        },\n\n        _showAutocomplete: function() {\n            this.tagInput.autocomplete('search', '');\n        },\n\n        _findTagByLabel: function(name) {\n            var that = this;\n            var tag = null;\n            this._tags().each(function(i) {\n                if (that._formatStr(name) == that._formatStr(that.tagLabel(this))) {\n                    tag = $(this);\n                    return false;\n                }\n            });\n            return tag;\n        },\n\n        _isNew: function(name) {\n            return !this._findTagByLabel(name);\n        },\n\n        _formatStr: function(str) {\n            if (this.options.caseSensitive) {\n                return str;\n            }\n            return $.trim(str.toLowerCase());\n        },\n\n        _effectExists: function(name) {\n            return Boolean($.effects && ($.effects[name] || ($.effects.effect && $.effects.effect[name])));\n        },\n\n        createTag: function(value, additionalClass, duringInitialization) {\n            var that = this;\n\n            value = $.trim(value);\n\n            if(this.options.preprocessTag) {\n                value = this.options.preprocessTag(value);\n            }\n\n            if (value === '') {\n                return false;\n            }\n\n            if (!this.options.allowDuplicates && !this._isNew(value)) {\n                var existingTag = this._findTagByLabel(value);\n                if (this._trigger('onTagExists', null, {\n                    existingTag: existingTag,\n                    duringInitialization: duringInitialization\n                }) !== false) {\n                    if (this._effectExists('highlight')) {\n                        existingTag.effect('highlight');\n                    }\n                }\n                return false;\n            }\n\n            if (this.options.tagLimit && this._tags().length >= this.options.tagLimit) {\n                this._trigger('onTagLimitExceeded', null, {duringInitialization: duringInitialization});\n                return false;\n            }\n\n            var label = $(this.options.onTagClicked ? '<a class=\"tagit-label\"></a>' : '<span class=\"tagit-label\"></span>').text(value);\n\n            // Create tag.\n            var tag = $('<li></li>')\n                .addClass('tagit-choice ui-widget-content ui-state-default ui-corner-all')\n                .addClass(additionalClass)\n                .append(label);\n\n            if (this.options.readOnly){\n                tag.addClass('tagit-choice-read-only');\n            } else {\n                tag.addClass('tagit-choice-editable');\n                // Button for removing the tag.\n                var removeTagIcon = $('<span></span>')\n                    .addClass('ui-icon ui-icon-close');\n                var removeTag = $('<a><span class=\"text-icon\">\\xd7</span></a>') // \\xd7 is an X\n                    .addClass('tagit-close')\n                    .append(removeTagIcon)\n                    .click(function(e) {\n                        // Removes a tag when the little 'x' is clicked.\n                        that.removeTag(tag);\n                    });\n                tag.append(removeTag);\n            }\n\n            // Unless options.singleField is set, each tag has a hidden input field inline.\n            if (!this.options.singleField) {\n                var escapedValue = label.html();\n                tag.append('<input type=\"hidden\" value=\"' + escapedValue + '\" name=\"' + this.options.fieldName + '\" class=\"tagit-hidden-field\" />');\n            }\n\n            if (this._trigger('beforeTagAdded', null, {\n                tag: tag,\n                tagLabel: this.tagLabel(tag),\n                duringInitialization: duringInitialization\n            }) === false) {\n                return;\n            }\n\n            if (this.options.singleField) {\n                var tags = this.assignedTags();\n                tags.push(value);\n                this._updateSingleTagsField(tags);\n            }\n\n            // DEPRECATED.\n            this._trigger('onTagAdded', null, tag);\n\n            this.tagInput.val('');\n\n            // Insert tag.\n            this.tagInput.parent().before(tag);\n\n            this._trigger('afterTagAdded', null, {\n                tag: tag,\n                tagLabel: this.tagLabel(tag),\n                duringInitialization: duringInitialization\n            });\n\n            if (this.options.showAutocompleteOnFocus && !duringInitialization) {\n                setTimeout(function () { that._showAutocomplete(); }, 0);\n            }\n        },\n\n        removeTag: function(tag, animate) {\n            animate = typeof animate === 'undefined' ? this.options.animate : animate;\n\n            tag = $(tag);\n\n            // DEPRECATED.\n            this._trigger('onTagRemoved', null, tag);\n\n            if (this._trigger('beforeTagRemoved', null, {tag: tag, tagLabel: this.tagLabel(tag)}) === false) {\n                return;\n            }\n\n            if (this.options.singleField) {\n                var tags = this.assignedTags();\n                var removedTagLabel = this.tagLabel(tag);\n                tags = $.grep(tags, function(el){\n                    return el != removedTagLabel;\n                });\n                this._updateSingleTagsField(tags);\n            }\n\n            if (animate) {\n                tag.addClass('removed'); // Excludes this tag from _tags.\n                var hide_args = this._effectExists('blind') ? ['blind', {direction: 'horizontal'}, 'fast'] : ['fast'];\n\n                var thisTag = this;\n                hide_args.push(function() {\n                    tag.remove();\n                    thisTag._trigger('afterTagRemoved', null, {tag: tag, tagLabel: thisTag.tagLabel(tag)});\n                });\n\n                tag.fadeOut('fast').hide.apply(tag, hide_args).dequeue();\n            } else {\n                tag.remove();\n                this._trigger('afterTagRemoved', null, {tag: tag, tagLabel: this.tagLabel(tag)});\n            }\n\n        },\n\n        removeTagByLabel: function(tagLabel, animate) {\n            var toRemove = this._findTagByLabel(tagLabel);\n            if (!toRemove) {\n                throw \"No such tag exists with the name '\" + tagLabel + \"'\";\n            }\n            this.removeTag(toRemove, animate);\n        },\n\n        removeAll: function() {\n            // Removes all tags.\n            var that = this;\n            this._tags().each(function(index, tag) {\n                that.removeTag(tag, false);\n            });\n        }\n\n    });\n})(jQuery);\njQuery(document).ready(function($){\n\n\tvar editor \t\t\t= lasso_editor.editor,\n\t\tstrings \t\t= lasso_editor.strings,\n\t\tsettingsLink\t= lasso_editor.settingsLink,\n\t\tpost_container  = lasso_editor.article_object,\n\t\ttoolbar \t\t= lasso_editor.toolbar,\n        toolbarPopup \t\t= lasso_editor.toolbarPopup,\n\t\ttoolbarHeading \t= lasso_editor.toolbarHeadings,\n\t\tpanel           = lasso_editor.component_sidebar,\n\t\tpostid          = lasso_editor.postid,\n\t\tmodal \t\t\t= lasso_editor.component_modal,\n\t\tcomponents \t\t= lasso_editor.components,\n\t\tfeatImgClass   \t= lasso_editor.featImgClass,\n\t\tfeatImgNonce    = lasso_editor.featImgNonce,\n\t\ttitleClass      = lasso_editor.titleClass,\n\t\tuploadControls  = lasso_editor.featImgControls,\n\t\twpImgEdit \t\t= lasso_editor.wpImgEdit,\n\t\tlassoDragHandle = lasso_editor.handle,\n\t\tlassoMapForm \t= lasso_editor.mapFormFooter,\n\t\tmapLocations    = lasso_editor.mapLocations,\n\t\tmapZoom    \t\t= lasso_editor.mapZoom,\n\t\tmapStart        = lasso_editor.mapStart,\n\t\tobjectsNoSave   = lasso_editor.objectsNoSave,\n\t\tobjectsNonEditable = lasso_editor.objectsNonEditable,\n\t\tsupportedNoSave = lasso_editor.supportedNoSave\n\n\tfunction restoreSelection(range) {\n\t    if (range) {\n\t        if (window.getSelection) {\n\t            var sel = window.getSelection();\n\t            sel.removeAllRanges();\n\t            sel.addRange(range);\n\t        } else if (document.selection && range.select) {\n\t            range.select();\n\t        }\n\t    }\n\t}\n    \n    function saveSelection() {\n        if (window.getSelection) {\n            article.highlight();\n            sel = window.getSelection();\n            if (sel.getRangeAt && sel.rangeCount) {\n                return sel.getRangeAt(0);\n            }\n        } else if (document.selection && document.selection.createRange) {\n            return document.selection.createRange();\n        }\n        return null;\n    }\n\n\t/*\n\tfunction to disable selection. Not used for now\n\tjQuery.fn.extend({\n\t\tdisableSelection : function() {\n\t\t\treturn this.each(function() {\n\t\t\t\tthis.onselectstart = function() { return false; };\n\t\t\t\tthis.unselectable = \"on\";\n\t\t\t\tjQuery(this).css('user-select', 'none');\n\t\t\t\tjQuery(this).css('-o-user-select', 'none');\n\t\t\t\tjQuery(this).css('-moz-user-select', 'none');\n\t\t\t\tjQuery(this).css('-khtml-user-select', 'none');\n\t\t\t\tjQuery(this).css('-webkit-user-select', 'none');\n\t\t\t});\n\t\t}\n\t});*/\n\t\n\n\t$('#lasso--edit').click(function(e){\n\t\n\t\tif ($(post_container).length ==0 ){\n\t\t\t// try one more time, support for shapely theme\n\t\t\tvar contClasses = [\".shapely-content\",\".entry-content\",\".aesop-entry-content\",\".novella-entry-content\",\".post-content\", \".entry-content-wrapper\",\".post_content\",\".gp-entry-content\"];\n\t\t\tfor (var i = 0; i < contClasses.length; i++) {\t\t\n\t\t\t\tif ($(contClasses[i]).length >0 ){\n\t\t\t\t\tpost_container = contClasses[i];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tif ($(post_container).length ==0 ){\n\t\t\t\t// if we can't find the article class, warn them and exit\n\t\t\t\tswal({\n\t\t\t\t\ttitle: strings.warning,\n\t\t\t\t\ttype: 'info',\n\t\t\t\t\ttext: strings.missingClass,\n\t\t\t\t\tshowCancelButton: true,\n\t\t\t\t\tcancelButtonText: strings.cancelText,\n\t\t\t\t\tconfirmButtonColor: '#007aab',\n\t\t\t\t\tconfirmButtonText: strings.missingConfirm,\n\t\t\t\t\tcloseOnConfirm: false\n\t\t\t\t},\n\t\t\t\tfunction(){\n\t\t\t\t\tlocation.replace(settingsLink);\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t\n\t\tlasso_editor.article_object = post_container;\n\t\t\n\t\t// ways to inject codes into the enterEditor\n\t\tif (lasso_editor.enterEditorHookArray) {\n\t\t\t$(lasso_editor.enterEditorHookArray).each(function(key, val){\n\t\t\t\tval();\n\t\t\t});\n\t\t}\n\t\t\n\t\t// lock the post for editing\n\t\tvar data = {\n\t\t\t\taction: 'editus_lock_post',\n\t\t\t\tpostid: lasso_editor.postid\n\t\t};\n\t\tlasso_editor.dontlock = false;\n\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\tif( response ){\n\t\t\t\tif (response.trim()==\"true\") {\n\t\t\t\t\tlasso_editor.dontlock = true;\n\t\t\t\t} else {\n                    swal({\n                            title:\"Lock Post Fail\",\n                            text: response,\n                            closeOnConfirm: true\n                    });\n                    exitEditor();\n                }\n\t\t\t\t\n\t\t\t} else {\n\t\t\t\talert(\"Error locking the post for editing\");\n\t\t\t\texitEditor();\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t//keep locking periodically\n\t\tif (!lasso_editor.dontlock) {\n\t\t\tlasso_editor.lockIntervalID = window.setInterval(lockPost, 120000);\n\t\t}\n\t\t\n\t\t\n\t\tfunction lockPost() {\n\t\t\tvar data = {\n\t\t\t\taction: 'editus_lock_post',\n\t\t\t\tpostid: lasso_editor.postid\n\t\t\t};\n\t\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\t/*if( response ){\n\t\t\t\t\tif (response!=\"true\") {\n\t\t\t\t\t\talert(response);\n\t\t\t\t\t\texitEditor();\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t} else {\n\t\t\t\t\talert(\"Error locking the post for edit\");\n\t\t\t\t\texitEditor();\n\t\t\t\t}*/\n\t\t\t\t\n\t\t\t});\n\t\t}\n\t\n\t\te.preventDefault();\n\n\t\t// add body class editing\n\t\t$('body').toggleClass('lasso-editing');\n\n\t\t//append editor id to post container\n\t\t$(post_container).prop('id', editor);\n\n\t\t// append toolbar\n\t\t$(toolbar).hide().appendTo('body').fadeIn(300);\n\n\t\t// fade in controls if previous exacped\n\t\t$('.lasso--controls__right').css('opacity',1);\n\n\t    // set edtior to editable\n\t    $('#'+editor).attr('contenteditable',true);\n\n\t    // add settings panel\n\t\t$('body').append(panel);\n\n\t\t// append upload bar to featured image if present\n\t\tif ( $( featImgClass ).length > 0 ) {\n\t\t\tif ( $(lasso_editor.featImgClass).is( \"img\" ) ) {\n\t\t\t\t$(featImgClass).parent().append( uploadControls );\n\t\t\t} else {\n\t\t\t\t$(featImgClass).append( uploadControls );\n\t\t\t}\n\t\t}\n\n\t\t// append contenteditable to title if set\n\t\tif ( $(titleClass).length > 0 ) {\n\t\t\t$(titleClass).attr('contenteditable', true);\n\t\t} else {\n\t\t\t// try one more time with .entry-title\n\t\t\tvar titleClasses = [\".entry-title-primary\",\".entry-title\",\".novella-entry-title\"];\n\t\t\tfor (var i = 0; i < titleClasses.length; i++) {\n\t\t\t\tif ( $(titleClasses[i]).length > 0 ) {\n\t\t\t\t\tlasso_editor.titleClass = titleClass = titleClasses[i];\n\t\t\t\t\t$(titleClass).attr('contenteditable', true);\n\t\t\t\t\tbreak;\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\t\n\t\tlasso_editor.subtitleClass=\"\";\n\t\tvar subtitleClasses = [\".entry-subtitle\",\".novella-entry-subtitle\"];\n\t\tfor (var i = 0; i < subtitleClasses.length; i++) {\n\t\t\tif ( $(subtitleClasses[i]).length > 0 ) {\n\t\t\t\tlasso_editor.subtitleClass = subtitleClasses[i];\n\t\t\t\t$(subtitleClasses[i]).attr('contenteditable', true);\n\t\t\t\tbreak;\n\t\t\t};\n\t\t}\n\n\t\t// if tehre are any scrollnav sections we need to break them open so that we can drag compnents around in them\n\t\t$('.scroll-nav__section').each(function(){\n\t\t\t$(this).children().unwrap();\n\t\t})\n\n\t\t// add an exit editor button\n\t\t$('.lasso--controls__right ').prepend('<a title=\"'+lasso_editor.strings.exiteditor+'\" id=\"lasso--exit\" href=\"#\"></a>');\n\n\t\t// append the toolbar to any components that dont have them\n\t\t// @todo - this likely needs to be changed to a lasso- namespaced item which then needs to be updated in Aesop Story Engine\n\t\t$('.aesop-component').each(function(){\n\n\t\t\t// if there's no toolbar present\n\t\t\tif ( !$('.lasso-component--toolbar').length > 0 ) {\n\n\t\t\t\t// if this is a map then we need to first wrap it so that we can drag the  map around\n\t\t\t\tif ( $(this).hasClass('aesop-map-component') ) {\n\n\t\t\t\t\tvar $this = $(this)\n\n\t\t\t\t\t// so wrap it with a aesop-compoentn aesop-map-component div\n\t\t\t\t\t// @todo - note once a map is inserted it can't be edited after saving again. a user has to delete the existin map and add a new map\n\t\t\t\t\t// to\n\t\t\t\t\t//$this.wrap('<form id=\"lasso--map-form\" class=\"aesop-component aesop-map-component lasso--map-drag-holder\" data-component-type=\"map\" >').before( lassoDragHandle ).after( lassoMapForm );\n\t\t\t\t\t$this.wrap('<div id=\"lasso--map-form\" class=\"aesop-component aesop-map-component lasso--map-drag-holder\" data-component-type=\"map\" >').before( lassoDragHandle );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t$(this).append( lassoDragHandle );\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n        lasso_editor.wrapImg = function () {\n            // find images inserted from within the wordpress backend post editor and\n            // wrap them in a div, then append an edit button for editing the image\n            /*$(\"[class*='wp-image-']\").each(function(){\n                var $this = $(this)\n                if ( !$('.lasso--wpimg-edit').length > 0 ) {\n                    if ( $this.parent().hasClass('wp-caption') ) {\n                        $this.parent().addClass('lasso--wpimg__wrap')\n                    } else {\n                        $this.wrap('<figure data-component-type=\"wpimg\" class=\"lasso--wpimg__wrap lasso-component\">')\n                    }\n                    \n                    \n                    $this.parent().data( $this.data() );\n                    var s =$this.attr('src');\n                    if (s) {\n                       $this.parent().data({componentType:\"wpimg\", img: $this.attr('src')});  \n                    }\n                }\n            });*/\n            \n            //$('.lasso-component:not(.lasso--wpimg__wrap)').each(function(){\n            $('.lasso-component').each(function(){\n\n                var $this = $(this)\n                if ( $(this).find('.lasso-component--controls').length == 0 ) {\n                    if (!lasso_editor.oldWPimg) {\n                        $(this).prepend( lassoDragHandle );\n                        var img = $(this).find('img')[0];\n                        var ctrl = $this.find('.lasso-component--controls')[0];\n                        if ($(img).hasClass('alignnone') || $(img).hasClass('alignleft')) {\n                            $(ctrl).removeClass('editus-center');\n                        }\n                        if ($(img).hasClass('alignright')) {\n                            $(ctrl).removeClass('editus-center');\n                            $(ctrl).addClass('editus-right');\n                        }\n                    } else { \n                        if ( $this.parent().hasClass('wp-caption') ) {\n                            $this.parent().addClass('lasso--wpimg__wrap')\n                        }/* else if ( !$this.parent().hasClass('lasso--wpimg__wrap') ) {\n                            $this.wrap('<figure data-component-type=\"wpimg\" class=\"lasso--wpimg__wrap lasso-component\">')\n                        }*/\n                        $this.parent().prepend(lasso_editor.wpImgEdit);\n                    }\n\n                }\n\n            })\n            \n            //wp image block\n\t\t\t$('.wp-block-image').each(function(){\n                var $this = $(this)\n                if ( $(this).find('.lasso-component--controls').length == 0 ) {\n                    $this.prepend(lasso_editor.wpImgBlockEdit);\n\t\t\t\t\t$this.attr('data-component-type','wpimg-block');\n                }\n\n            })\n            \n            //wp cover block\n            $('.wp-block-cover').each(function(){\n                var $this = $(this)\n                if ( $(this).find('.lasso-component--controls').length == 0 ) {\n                    $this.prepend(lasso_editor.wpImgBlockEdit);\n                    $this.find(\".lasso-clone,.lasso-delete\").remove();\n                    $this.find(\".lasso-component--controls\").width('61px');\n\t\t\t\t\t$this.attr('data-component-type','wpcover-block');\n                }\n\n            })\n        }\n        \n        lasso_editor.wrapImg();\n\n\t\t\n\t\t\n\n\t\t/////////////////\n\t\t///\n\t\t///   CONTENT EDITABLE / TOOLBAR\n\t\t///\n\t\t/// - attributes and tags are set to null to allow any markup and block level items to be passed through\n\t\t///   this means that medium.js is only providing us with a helper API to invoke certain markup and to \n\t\t///   insert HTML. It's important to realize that the_content filter together with wpautop is responsible\n\t\t///   for automatically making new paragraph elements on enter\n\t\t///\n\t\t///////////////////\n\t\tarticle = document.getElementById(editor),\n\t    articleMedium = new Medium({\n\t        element: article,\n\t        mode: Medium.richMode,\n\t        attributes: null,\n\t        tags: null,\n\t        placeholder:lasso_editor.strings.justWrite,\n\t\t    pasteAsText: true,\n\t    \tcssClasses: {\n\t\t\t\teditor: 'lasso-editor',\n\t\t\t\tpasteHook: 'lasso-editor-paste-hook',\n\t\t\t\tplaceholder: 'lasso-editor-placeholder',\n\t\t\t\tclear: 'lasso-editor-clear'\n\t\t\t}\n\t    });\n\t\t\n\t\t$(objectsNonEditable).attr('contenteditable',false);\n\t\t$(objectsNonEditable).attr('readonly',true);\n        \n        // set some figures uneditable\n        $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\n\t\t\n\t\t// remove any additional markup so we dont save it as HTML\n\t\tif (objectsNoSave.length) {\n\t\t    objectsNoSave = objectsNoSave+\",\"+supportedNoSave;\n\t\t} else {\n\t\t\tobjectsNoSave = supportedNoSave;\n\t\t}\n\t\t\n\t\tlasso_editor.objectsNoSave = objectsNoSave;\n\t\t\n\t\tif ($(objectsNonEditable).length || (lasso_editor.showIgnoredItems && ($(objectsNoSave).length)|| $(supportedNoSave).length )) {\n\t\t\tlasso_editor.readOnlyExists = true;\n\t\t} else {\n\t\t\tlasso_editor.readOnlyExists = false;\n\t\t}\n\t\tif (!lasso_editor.showIgnoredItems) {\n\t\t    $(objectsNoSave).remove();\n\t\t    $(supportedNoSave).remove();\n\t\t} else {\n\t\t\t$(objectsNoSave).attr('contenteditable',false);\n\t\t    $(objectsNoSave).attr('readonly',true);\n\t\t}\n\t\t\n\t\t// detect avia editor\n\t\tlasso_editor.aviaEditor = ($('.av_toggle_section,.av_textblock_section').length>0);\n\t\t\n\t\t// set links clickable\n\t\tif (!lasso_editor.linksEditable) {\n\t\t\t$(\"a\").attr('contenteditable',false);\n\t\t}\n\t\t\n\t\tif (lasso_editor.disableEditPost) {\n\t\t\t//set everything uneditable\n\t\t\t$( \"[contenteditable]\" ).attr('contenteditable',false);\n\t\t}\n\t\t\n\t\t// custom fields\n\t\tif (lasso_editor.customFields) {\n\t\t\tvar joined = [];\n\t\t\tfor (var key in lasso_editor.customFields) {\n\t\t\t\tvar imgControls = '<a title=\"Replace Image\" href=\"\" class=\"editus-custom-image-control\" style=\"position:absolute;right:0px;\"><i class=\"lasso-icon-image\" style=\"color: black;font-size: 20px\"></i></a>';\n\t\t\t\tif (typeof(lasso_editor.customFields[key]) == 'object') {\n\t\t\t\t\tvar selector = lasso_editor.customFields[key]['selector'];\n\t\t\t\t\tjoined.push(selector);\n\t\t\t\t\tif (lasso_editor.customFields[key]['imgurl']) {\n\t\t\t\t\t\tif ($(selector).find('.editus-custosm-image-control').length == 0) {\n\t\t\t\t\t\t\t$(selector).parent().parent().append( imgControls );\n\t\t\t\t\t\t\t$(selector).parent().parent().css(\"position\", \"relative\");\n\t\t\t\t\t\t\t$(selector).parent().parent().find('.editus-custom-image-control').mousedown(imgDialog);\n\t\t\t\t\t\t}\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t   joined.push(lasso_editor.customFields[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlasso_editor.cfselector = joined.join(',');\n\t\t\t$(lasso_editor.cfselector).attr('contenteditable',true);\n\t\t\tif (lasso_editor.undeletableExists = ($(lasso_editor.cfselector).length>0)) {\n\t\t\t\t$(lasso_editor.cfselector).addClass('lasso-undeletable');\n\t\t\t}\n\t\t}\n\t\t\n\t\t//$(objectsNonEditable).disableSelection();\n\n\t    // this forces the default new element in content editable to be a paragraph element if\n\t    // it has no previous element to depart from \n\t    // ref http://stackoverflow.com/a/15482748\n\t    document.execCommand('defaultParagraphSeparator', false, 'p');\n\n\t\t// cursor to the beginning\n        if (articleMedium.element.firstChild == null) {\n\t\t\tvar node = document.createElement(\"p\");\n\t\t\tvar textnode = document.createTextNode(\" \");         // Create a text node\n\t\t\tnode.appendChild(textnode);   \n\t\t\tarticleMedium.element.appendChild(node);\n\t\t}\n\t\tarticleMedium.cursor.caretToBeginning(articleMedium.element.firstChild);\n\n\t\tarticle.highlight = function() {\n\t\t\tif (document.activeElement !== article) {\n\n\t\t\t\t//articleMedium.select();\n\t\t\t\tarticle.focus();\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\n\t\t\n\t\tif (lasso_editor.toolbarPopup) {\n            $(lasso_editor.toolbarPopup).hide().appendTo('body');\n        }\n\t\t\n\t\t\n\t\t//color\n\t\tif (lasso_editor.showColor) {\n            var cv = \"#ff0000\";\n\t\t\t// red is the default color\n\t\t\t$( '#lasso-toolbar--color-pick' ).iris();\n\t\t\t$( '#lasso-toolbar--color-pick' ).iris('color', '#f00');\n            $('head').append('<style id=\"editus-colorpick\">#lasso-toolbar--color-pick:before, #lasso-toolbar--color-set:before{color:#ff0000 !important;}</style>');\n\t\t\t\n\t\t\t$(window).mousedown(function() {\n\t\t\t    //Hide the color picker if visible\n\t\t\t\t$(\"#lasso-toolbar--color-pick\").iris('hide');\n\t\t\t});\n\t\t\t\n\t\t\tfunction rgb2hex(rgb) {\n\t\t\t\trgb = rgb.match(/^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$/);\n\t\t\t\tfunction hex(x) {\n\t\t\t\t\treturn (\"0\" + parseInt(x).toString(16)).slice(-2);\n\t\t\t\t}\n\t\t\t\treturn \"#\" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);\n\t\t\t}\n\t\t\tif (!lasso_editor.isMobile) {\n\t\t\t    $(\".iris-picker\").css({position:'absolute', top:-180});\n\t\t\t}\n\t\t\t$(\"#lasso-toolbar--color-pick\").iris({\n\t\t\t\tpalettes: true,\n\t\t\t\tchange: function(event, ui) {\n\t\t\t\t\t// event = standard jQuery event, produced by whichever control was changed.\n\t\t\t\t\t// ui = standard jQuery UI object, with a color member containing a Color.js object\n\n\t\t\t\t\t// change the color\n                    $('style#editus-colorpick').remove();\n                    cv = ui.color.toString();\n                    $('head').append('<style id=\"editus-colorpick\">#lasso-toolbar--color-pick:before, #lasso-toolbar--color-set:before{color:'+cv+' !important;}</style>');\n\n\t\t\t\t}\n\t\t\t});\n            \n\t\t\t$('#lasso-toolbar--color-pick').on('mousedown', function(event) {\t\n\t\t\t\tif (event.target.id == 'lasso-toolbar--color-pick') {\n\t\t\t\t   $(\"#lasso-toolbar--color-pick\").iris('toggle');\n\t\t\t\t}\n                event.stopPropagation();\t\t\t\t\n\t\t\t});\n\t\t\t\n\t\t\t$('#lasso-toolbar--color-set').on('mousedown', function() {\n\t\t\t\t$(\"#lasso-toolbar--color-pick\").iris('hide');\n\t\t\t\tarticleMedium.element.contentEditable = true;\n\t\t\t\t// exit if nothing is selected\n\t\t\t\tif (!lasso_editor.checkSelection(true)) return false;\n\t\t\t\t\n\t\t\t\t//var colorVar = rgb2hex($('#lasso-toolbar--color-pick').css(\"color\"));\n\t\t\t\tarticleMedium.invokeElement('span', { style: 'color:' + cv + ';'});\n\t\t\t\t//unselect\n\t\t\t\tif (window.getSelection) {\n\t\t\t\t  if (window.getSelection().empty) {  // Chrome\n\t\t\t\t\twindow.getSelection().empty();\n\t\t\t\t  } else if (window.getSelection().removeAllRanges) {  // Firefox\n\t\t\t\t\twindow.getSelection().removeAllRanges();\n\t\t\t\t  }\n\t\t\t\t} else if (document.selection) {  // IE?\n\t\t\t\t  document.selection.empty();\n\t\t\t\t}\n                $(\".lasso--text-popup\").hide();\n\t\t\t\tarticleMedium.makeUndoable();\n\t\t\t\treturn false;\n\t\t\t});\n\t\t}\n\n\t\t\n\t\t\n\t\t// color end\n\t\t\n\t\t//alignement\n\t\tif (lasso_editor.showAlignment) {\n\t\t\tfunction alignHelper(align) {\n\t\t\t\tvar focusedElements = articleMedium.html.textElementsAtCaret();\n\t\t\t\tif (focusedElements) {\n\t\t\t\t\tfor (i = 0; i < focusedElements.length; i++) {\n\t\t\t\t\t  focusedElements[i].style.textAlign = align;\n\t\t\t\t\t}\t\t\t\n\t\t\t\t}\n\t\t\t\tarticleMedium.makeUndoable();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$('#lasso-toolbar--right-align').mousedown(function() {\n\t\t\t\treturn alignHelper(\"right\");\n\t\t\t});\n\t\t\t\n\t\t\t$('#lasso-toolbar--left-align').mousedown(function() {\n\t\t\t\treturn alignHelper(\"left\");\n\t\t\t});\n\t\t\t\n\t\t\t$('#lasso-toolbar--center-align').mousedown(function() {\n\t\t\t\treturn alignHelper(\"center\");\n\t\t\t});\n\t\t}\n\t\t\n\t\t//end alignment\n\t\t\n\t\t$('#lasso-toolbar--ul').mousedown(function() {\n\t\t\t\tmakeList(\"ul\");\n\t\t});\n\t\t$('#lasso-toolbar--ol').mousedown(function() {\n\t\t\t\tmakeList(\"ol\");\n\t\t});\n\t\t\n\t\tfunction makeList(list_type) {\n\t\t\tvar list = $(\"<\"+list_type+\"/>\");\n\t\t\tvar focusedElements = articleMedium.html.textElementsAtCaret();\n\t\t\tif (focusedElements) {\n\t\t\t\t\tfor (i = 0; i < focusedElements.length; i++) {\n\t\t\t\t\t  list.append(\"<li>\" + focusedElements[i].innerHTML + \"</li>\");\n\t\t\t\t\t  if (i>0) {\n\t\t\t\t\t\t  focusedElements[i].parentNode.removeChild(focusedElements[i]); \n\t\t\t\t\t  }\n\t\t\t\t\t}\t\n\t\t\t\t\t$(focusedElements[0]).replaceWith(list[0]);\t\t\t\t\n\t\t\t}\n\t\t\t\t\n\t\t\tarticleMedium.makeUndoable();\n\t\t\tarticle.highlight();\n\t\t\t//setCursor($(focusedElements[0]));\n\t\t\t//articleMedium.cursor.caretToBeginning(articleMedium.element.firstChild);\n\t\t}\n\t\t\n\t\t\t\tif (!lasso_editor.disableEditSC) {\n\t\t\tprocessShortcodes();\n\t\t}\n\t\t\n\t\tfunction processShortcodes()\n\t\t{\n\t\t\t$(article).children().filter(function(){\n\t\t\t\treturn this.innerHTML.includes(\"EDITUS_OTHER_SHORTCODE_START\");\n\t\t\t}).each(function(i, e){\n\t\t\t\tvar re = /<!--EDITUS_OTHER_SHORTCODE_START\\|\\[(.*)\\]-->/g ;\n\t\t\t    var cont = re.exec(this.innerHTML);\n\t\t\t\t\t\t\t\n\t\t\t\t$(this).next().append( '<div class=\"editus_shortcode\" contenteditable=\"false\">'+lasso_editor.strings.editShortcode+'</div>' );\n\t\t\t\t\n\t\t\t\t$(this).next().addClass(\"editus_shortcode_p\");\n\t\t\t\t\n\t\t\t\tif (cont) $(this).next().find('.editus_shortcode')[0].dataset.shortcode = cont[1];\n\t\t\t});\n\t\t}\n\t\t\n\t\t$(document).on('click','.editus_shortcode', function(e){\n\t\t\tvar $this = $(this);\n\t\t\n\t\t\tvar s = $(window).scrollTop();\n\t\t\tswal({\n\t\t\t\ttitle: lasso_editor.strings.editShortcode,\n\t\t\t\ttext: \"<textarea id='shortcode_edit' name='shortcode'>\"+ this.dataset.shortcode +\"</textarea>\",\n\t\t\t\tshowCancelButton: true,\n\t\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\t\tconfirmButtonText: \"Modify\",\n\t\t\t\tcloseOnConfirm: true,\n\t\t\t\tobj: this\n\t\t\t},\n\t\t\tfunction(){\n\t\t\t\tvar val = $('textarea#shortcode_edit').val();\n\t\t\t\tvar data = {\n\t\t\t\t\taction: 'editus_do_shortcode',\n\t\t\t\t\tcode: val,\n\t\t\t\t\tID: lasso_editor.postid\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\t\t\trestoreSelection(window.selRange);\n\t\t\t\t\t\tif( response && response.includes(\"EDITUS_OTHER_SHORTCODE_END\")){\n\t\t\t\t\t\t\t$this.parent().prev().remove();\n\t\t\t\t\t\t\t//$this.next().remove();\n\t\t\t\t\t\t\t$this.parent().replaceWith( response.replace(\"<!--EDITUS_OTHER_SHORTCODE_END-->\",\"\") );\n\t\t\t\t\t\t\tprocessShortcodes();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\talert(\"Shortcode processing failed\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$(window).scrollTop(s);\n\t\t\t\t});\t\t\t\t\n\t\t\t});\n\t\t})\n\t\t\n\t\tfunction taghelper(tag) {\n\t\t\tarticleMedium.element.contentEditable = true;\n\t\t\tarticle.highlight();\n\t\t    articleMedium.invokeElement(tag);\n\t\t\tarticleMedium.makeUndoable();\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\t$('[id=\"lasso-toolbar--bold\"]').on('mousedown', function(e) {\n\t\t\treturn taghelper(lasso_editor.boldTag);\n\t\t});\n\t\t\n        $('[id=\"lasso-toolbar--underline\"]').on('mousedown', function(e) {\n\t\t\treturn taghelper('u');\n\t\t});\n\n        $('[id=\"lasso-toolbar--italic\"]').on('mousedown', function(e) {\n\t\t\treturn taghelper(lasso_editor.iTag);\n\t\t});\n        $('[id=\"lasso-toolbar--strike\"]').on('mousedown', function(e) {\n\t\t\treturn taghelper('strike');\n\t\t});\n        \n        $(document).on('keydown', function ( e ) {\n            // remove formatting when the use pushes ctrl+space\n            if ((e.metaKey || e.ctrlKey) && ( e.which == 32) ) {\n                document.execCommand('removeFormat');\n                document.execCommand('formatBlock', false, 'p')\n            }\n        });\n\n\t\tfunction heading_helper(heading) {\n\t\t\tarticleMedium.element.contentEditable = true;\n\t\t\tarticle.highlight();\n\n\t\t\tarticleMedium.invokeElement(heading);\n\t\t\t//reg = '/<h2 class=\"lasso-h2\">([^<>]*)<\\/h2>/i';\n\t\t\treg = new RegExp('<'+heading+' class=\"lasso-'+heading+'\">([^<>]*)<\\\\/'+heading+'>', 'i');;\n\t\t\t\t// the following code breaks the paragraphs before and after heading\n\t\t\t$(articleMedium.element).html(function(index,html){\n\t\t\t\t//return html.replace(/<h2 class=\"lasso-h2\">([^<>]*)<\\/h2>/i,'</p><'+heading+'>$1</'+heading+'><p>');\n\t\t\t\treturn html.replace(reg,'</p><'+heading+'>$1</'+heading+'><p>');\n\t\t\t});\n\n\t\t\tarticleMedium.makeUndoable();\n\t\t\treturn false;\n\t\t}\n\n\t\t\n\t\tdocument.getElementById('lasso-toolbar--link').onmousedown = function() {\n\t\t\t\t var article = document.getElementById(lasso_editor.editor);\n    \t\t\tarticle.highlight();\n    \t\t\twindow.selRange = saveSelection();\n\t\t\t};\n\t\tdocument.getElementById('lasso-toolbar--html').onmousedown = function() {\n\t\t\t\t var article = document.getElementById(lasso_editor.editor);\n    \t\t\tarticle.highlight();\n    \t\t\twindow.selRange = saveSelection();\n    \t\t\tif( typeof window.selRange === 'undefined' || null == window.selRange ) {\n    \t\t\t\twindow.selRange = saveSelection();\n    \t\t\t}\n\t\t\t};\n\n\t\tif ( toolbarHeading ) {\n\t\t\tdocument.getElementById('lasso-toolbar--h2').onmousedown = function() {\n\t\t\t\treturn heading_helper('h2');\n\t\t\t};\n\n\t\t\tdocument.getElementById('lasso-toolbar--h3').onmousedown = function() {\n\t\t\t\treturn heading_helper('h3');\n\t\t\t};\n\t\t}\n\t\tif ( lasso_editor.toolbarHeadingsH4 ) {\n\t\t\tdocument.getElementById('lasso-toolbar--h4').onmousedown = function() {\n\t\t\t\treturn heading_helper('h4');\n\t\t\t};\n\t\t\tdocument.getElementById('lasso-toolbar--h5').onmousedown = function() {\n\t\t\t\treturn heading_helper('h5');\n\t\t\t};\n\t\t\tdocument.getElementById('lasso-toolbar--h6').onmousedown = function() {\n\t\t\t\treturn heading_helper('h6');\n\t\t\t};\n\t\t}\n\n\t\t\n\t\tdocument.getElementById('lasso-toolbar--link__create').onmousedown = function() {\n\t\t\tarticleMedium.element.contentEditable = true;\n\t\t    article.highlight();\n\t\t    restoreSelection(window.selRange);\n\t\t\tvar html = '<a class=\"lasso-link\" contenteditable=\"false\" ';\n\t\t\t\n\t\t\tif (!lasso_editor.linkEditable) { \n\t\t\t\thtml = '<a class=\"lasso-link\" ';\n\t\t\t}\n\n\t\t\tvar target = $('#lasso-toolbar--link__inner').text();\n            \n            if (target==\"\") {\n                html = window.selRange.toString();\n            } else {\n                if (lasso_editor.prefixHTTP && !target.match(/http/i)){\n                    target = 'http://'+target;\n                }\n                if ($('#aesop-toolbar--link_newtab').is(':checked')) {\n                    html = html+' target=\"_blank\" href=\"'+ target +'\">'+window.selRange+'</a>';\n                } else {\n                    html = html+' href=\"'+ target +'\">'+window.selRange+'</a>';\n                }\n            }\n            articleMedium.insertHtml(html);\n            var container = window.selRange.startContainer.parentNode,\n                containerTag = container.localName;\n\n            if ( containerTag == 'a' ) {\n                var containerObject = $(window.selRange.startContainer.parentNode);\n                containerObject.replaceWith(containerObject[0].innerHTML);\n            }\n            \n\t\t    window.selRange = null;\n\n\t\t    // close modal drag\n        \t$('#lasso-toolbar--link').removeClass('link--drop-up link--drop-down');\n\t\t\t\n\t\t\tarticleMedium.makeUndoable();\n\n\t\t    return false;\n\t\t};\n\t\t\n\t\t// process shortcode using AJAX service and insert the result\n\t\tfunction do_shortcode_ajax(content)\n\t\t{\n\t\t\tvar data = {\n\t\t\t\t\taction: 'editus_do_shortcode',\n\t\t\t\t\tcode: content,\n\t\t\t\t\tID: lasso_editor.postid\n\t\t\t};\n\t\t\t\n\t\t\t\t\t\t\t\n\t\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n                    restoreSelection(window.selRange);\n\t\t\t\t\tif( response ){\n\t\t\t\t\t\treturn insert_html(response);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn insert_html(content);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t\n\t\t\n\t\tfunction insert_html(htmlContent, contentishtml) {\t\t\n\t\t\tvar html = contentishtml; \n\t\t\tif (contentishtml == undefined) {\n\t\t\t\thtml = true;\n\t\t\t}\n\t\t\ttry  {\n\t\t\t\tvar container = window.selRange.startContainer;\n\t\t\t\tvar containerTag = container.localName;\n\t\t\t\tvar containerObject = $(container);\n\t\t\t\tvar htmlCopy = htmlContent;\n\t\t\t\tif (html) {\n                    //htmlContent is html, not an object\n\t\t\t\t\thtmlContent = $(htmlContent);\n\t\t\t\t\thtmlContent.attr('contenteditable','true');\n\t\t\t\t} else {\n\t\t\t\t\thtmlCopy = htmlContent[0].outerHTML;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// handle 3 specific scenarios dealing with <p>'s\n\t\t\t\t// note: might need climb up dom tree depending on nesting use case\n\t\t\t\tif (containerTag == 'p') {\n\t\t\t\t\tvar innerText = container.innerText.replace(/(\\r\\n|\\n|\\r)/gm,\"\");\n\t\t\t\t\tif (!html) {\t\n\t\t\t\t\t\t// currently we come here only if when inserting components\n                        \t\t\t\t\t\n\t\t\t\t\t\t/*htmlContent.insertAfter( containerObject );\n\t\t\t\t\t\tif (innerText ==\"\") {\n\t\t\t\t\t\t\t// empty p tag\n\t\t\t\t\t\t\tcontainerObject.remove();\n\t\t\t\t\t\t}*/\n\t\t\t\t\t\t// decided to change the behavior Now the component is inserted before the empty paragraph\t\n\t\t\t\t\t\thtmlContent.insertBefore( containerObject );\n\t\t\t\t\t\tif (innerText ==\"\") {\n\t\t\t\t\t\t\tarticleMedium.cursor.caretToBeginning(container);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tarticleMedium.insertHtml( htmlCopy );\n\t\t\t\t\t}\n\t\t\t\t\t\n\n\t\t\t\t} else {\n\t\t\t\t\t// within a p tag\n\t\t\t\t\tcontainer = container.parentNode;\n\t\t\t\t\tcontainerTag = container.localName;\n\n\t\t\t\t\tif( containerTag == 'p') {\n\t\t\t\t\t\t//if (string.indexOf(<) !== -1;\n\t\t\t\t\t\t//htmlContent.insertAfter( containerObject );\n\t\t\t\t\t\tarticleMedium.insertHtml( htmlCopy );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// let's just go ahead and paste it on location\n\t\t\t\t\t\tarticleMedium.insertHtml( '<p>'+htmlCopy+'</p>' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t//window.selRange = null;\n\n\t\t\t\t// close modal drag\n\t\t\t\t$('#lasso-toolbar--html').removeClass('html--drop-up');\n\t\t\t\t\n\t\t\t\tarticleMedium.makeUndoable();\n\t\t\t\tlasso_editor.addComponentButton();\n\n\t\t\t\treturn htmlContent;\n\t\t\t} catch (e) {\n\t\t\t\talert(e.message);\n\t\t\t\t\n\t\t\t}\n\t\t}\n\t\t\n\t\tfunction isURL(str) {\n\t\t\tvar pattern = new RegExp('^(https?:\\\\/\\\\/)?'+ // protocol\n\t\t\t  '((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|'+ // domain name and extension\n\t\t\t  '((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))'+ // OR ip (v4) address\n\t\t\t  '(\\\\:\\\\d+)?'+ // port\n\t\t\t  '(\\\\/[-a-z\\\\d%@_.~+&:]*)*'+ // path\n\t\t\t  '(\\\\?[;&a-z\\\\d%@_.,~+&:=-]*)?'+ // query string\n\t\t\t  '(\\\\#[-a-z\\\\d_]*)?$','i'); // fragment locator\n\t\t\t  return pattern.test(str);\n\t\t}\n\t\t\n\t\tdocument.getElementById('lasso-toolbar--html__insert').onmousedown = function() {\n\t\t    articleMedium.element.contentEditable = true;\n\t\t    restoreSelection(window.selRange);\n\n\n\t\t\tvar htmlContent = $('#lasso-toolbar--html__inner').text();\n\t\t\tif (htmlContent.indexOf(\"]\") != -1) {\n\t\t\t\tdo_shortcode_ajax(htmlContent);\n\t\t\t\treturn false;\n\t\t\t} else if (isURL(htmlContent)) {\n\t\t\t\tdo_shortcode_ajax(\"[embed]\"+htmlContent+\"[/embed]\");\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\treturn insert_html(htmlContent);\n\t\t\t}\n\t\t};\n\n\t\tif (lasso_editor.enableAutoSave) {\n\t\t\tlasso_editor.intervalID = window.setInterval(autoSave, 60000);\n\t\t}\n\t\t\n\t\tfunction autoSave() {\n\t\t\tif (localStorage.getItem( 'lasso_backup_'+postid ) || lasso_editor.dirtyByComponent) \n\t\t\t{\n\t\t\t\t$('.lasso--controls__right #lasso--save').trigger('click');\n\t\t\t}\n\t\t}\n\t\t\n\t\tfunction clearTimer()\n\t\t{\n\t\t\tif (lasso_editor.intervalID) {\n\t\t\t     window.clearInterval(lasso_editor.intervalID);\n\t\t\t\t lasso_editor.intervalID = 0;\n\t\t\t}\n\t\t\tif (lasso_editor.lockIntervalID) {\n\t\t\t     window.clearInterval(lasso_editor.lockIntervalID);\n\t\t\t\t lasso_editor.lockIntervalID = 0;\n\t\t\t\t //unlock post\n\t\t\t\t var data = {\n\t\t\t\t\taction: 'editus_unlock_post',\n\t\t\t\t\tpostid: lasso_editor.postid\n\t\t\t\t};\n\t\t\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\t\t\t\t\t\n\t\t\t\t});\t\t\t \n\t\t\t}\n\t\t}\n\t\t\n\t\t/////////////////\n\t\t/// EXIT EDITOR\n\t\t///////////////////\n\t\tfunction exitEditor(){\n\t\t\tclearTimer();\n\n\t\t\tif ($('body').hasClass('lasso-sidebar-open')) {\n\t\t\t\t//e.preventDefault();\n\t\t\t\t$('body').removeClass('lasso-sidebar-open');\n\t\t\t\t$('#lasso--component__settings').perfectScrollbar('destroy');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t$('body').removeClass('lasso-sidebar-open lasso-editing');\n\n\t\t\t$('.lasso--toolbar_wrap,#lasso--sidebar,#lasso--featImgControls,.lasso-component--controls,#lasso--exit,#lasso-side-comp-button,.lasso--text-popup,.editus_shortcode').fadeOut().remove();\n\n\n\t\t\t$('#lasso--edit').css('opacity',1);\n\t\t\t$('.lasso--controls__right').css('opacity',0);\n\t\t\t$(post_container).attr('id','');\n\n\t\t\t// unwrap wp images\n\t\t\t/*$('.lasso--wpimg__wrap').each(function(){\n\t\t\t\t$(this).children().unwrap()\n\t\t\t});*/\n\n\t\t\t// unwrap map from hits drag holder\n\t\t\t$('#lasso--map-form').each(function(){\n\n\t\t\t\tvar $this = $(this)\n\n\t\t\t\t$this.find('.lasso-component--controls, .lasso--map-form__footer ').remove()\n\n\t\t\t\t$this.children().unwrap()\n\t\t\t});\n\n\t\t\t$(titleClass).attr('contenteditable', false);\n\n\t\t\t$(articleMedium.element).find(\"*\").removeAttr('contenteditable');\n\t\t\tarticleMedium.destroy();\n\t\t\t\n\t\t\t// ways to inject codes into the exitEditor\n\t\t\tif (lasso_editor.exitEditorHookArray) {\n\t\t\t\t$(lasso_editor.exitEditorHookArray).each(function(key, val){\n\t\t\t\t\tval();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tlasso_editor.exitEditor = exitEditor;\n\t\t\n\t\t// on escape key exit\n\t\t$(document).keyup(function(e) {\n\n\t\t\tif ( 27 == e.keyCode ) {\n\t\t\t\tif ($('#lasso-toolbar--link').hasClass('link--drop-up')) {\n\t\t\t\t\t$('#lasso-toolbar--link').removeClass('link--drop-up');\n                } else if ($('#lasso-toolbar--html').hasClass('html--drop-up')) {\n\t\t\t\t\t$('#lasso-toolbar--html').removeClass('html--drop-up');\n\t\t\t\t} else {\n\t\t\t\t   exitEditor()\n\t\t\t\t}\n\t\t\t}\n\n\t\t});\n\t\t// on utility class exit\n\t\t//$('#lasso--exit').live('click',function(e){\n\t\tjQuery(document).on('click','#lasso--exit', function(e){\n\t\t\te.preventDefault();\n\t\t\t//previously we just called exitEditor(), now the following reloads the page if there is an unsaved change\n\t\t\tif (articleMedium.dirty) {\n\t\t\t\tclearTimer();\n\t\t\t   location.reload();\n\t\t\t} else {\n\t\t\t  exitEditor();\n\t\t\t}\n\t\t})\n\n\t\t// on control s save\n\t\t$(document).keydown(function(e) {\n\t\t    if ((e.which == '115' || e.which == '83' ) && (e.ctrlKey || e.metaKey)){\n\t\t        e.preventDefault();\n\t\t        \t\n\t\t        $('.lasso-editing #lasso--save').trigger('click')\n\n\t\t        return false;\n\t\t    }\n\t\t    return true;\n\t\t});\n\n\t\t///////////\n\t\t// INITIALIZE TIMELINE\n\t\t//////////\n        lasso_editor.timelineGoTime = function(){\n\t\t\t// if there's no toolbar present\n\t\t\tif ( !$('.aesop-timeline').length > 0 ) {\n\t\t\t\t$('body').append('<div class=\"aesop-timeline\"></div>').addClass('has-timeline');\n\t\t\t}\n\n\n\t\t\tif ( !$('.aesop-timeline .scroll-nav').length > 0 ) {\n\n\t\t\t\t$('.aesop-entry-content').scrollNav({\n\t\t\t\t    sections: '.aesop-timeline-stop',\n\t\t\t\t    arrowKeys: true,\n\t\t\t\t    insertTarget: '.aesop-timeline',\n\t\t\t\t    insertLocation: 'appendTo',\n\t\t\t\t    showTopLink: false,\n\t\t\t\t    showHeadline: false,\n\t\t\t\t    scrollOffset: 0,\n\t\t\t\t});\n\n\t\t\t\t$('.aesop-timeline-stop').each(function(){\n\t\t\t\t\t$(this).append( lassoDragHandle );\n\t\t\t\t});\n\n\t\t\t}\n\n\t\t\t$('.aesop-timeline-stop').each(function(){\n\t\t\t\t\tvar label = $(this).attr('data-title');\n\t\t\t\t\t$(this).text(label);\n                if ( $(this).find('.lasso-component--controls').length == 0 ) {\n                    $(this).append( lassoDragHandle );\n                }\n\n\t\t\t});\n\t\t}\n\n\t\t///////////\n\t\t// INITIALIZE VIDEO\n\t\t///////////\n\t\tvar videoGoTime = function(){\n\t\t\t$('.aesop-video-component').fitVids()\n\t\t}\n\n\t\tvar start_point \t= mapStart ? mapStart : [29.76, -95.38]\n\t\t, \tstart_zoom \t\t= mapZoom ? mapZoom : 12\n\t\t, \tmapTileProvider = lasso_editor.mapTileProvider;\n\n\t\t///////////\n\t\t// INITIALIZE MAPS\n\t\t///////////\n\t\tvar mapsGoTime = function(){\n\n\t\t\tvar lat = start_point.lat ? start_point.lat : 29.76\n\t\t\t,\tlng = start_point.lng ? start_point.lng : -95.38;\n\n\t\t\tvar map = L.map('aesop-map-component',{\n\t\t\t\tscrollWheelZoom: false,\n\t\t\t\tzoom: start_zoom,\n\t\t\t\tcenter: [lat, lng]\n\t\t\t});\n\n\t\t\tsetMapCenter(start_point[0],start_point[1]);\n\n\t\t\tjQuery('#lasso-map-address').geocomplete().bind('geocode:result', function(event, result){\n\t\t\t\tvar lat = result.geometry.location.k;\n\t\t\t\tvar lng = result.geometry.location.B;\n\t\t\t\tmap.panTo(new L.LatLng(lat,lng));\n\t\t\t\tsetMapCenter(lat,lng);\n\t\t\t});\n\n\t\t\tL.tileLayer(mapTileProvider, {\n\t\t\t\tmaxZoom: 20//start_zoom\n\t\t\t}).addTo(map);\n\n\t\t\tmapLocations.forEach(function(location) {\n\t\t\t\tcreateMapMarker([location['lat'],location['lng']],location['title']).addTo(map);\n\t\t\t\tcreateMarkerField( marker._leaflet_id, encodeMarkerData(location['lat'], location['lng'], location['title']) );\n\t\t\t});\n\n\t\t\t// adding a new marker\n\t\t\tmap.on('click', onMapClick);\n\t\t\tmap.on('dragend', onMapDrag);\n\t\t\tmap.on('zoomend', onMapZoom);\n\n\t\t\tfunction setMapCenter(k, B) {\n\t\t\t\tvar ldata = encodeLocationData(k,B);\n\t\t\t\tjQuery('input[name=\"ase-map-component-start-point\"]').remove();\n\t\t\t\tjQuery('.lasso--map-form__footer').append('<input type=\"hidden\" name=\"ase-map-component-start-point\" data-ase=\"map\" value=\"' + ldata + '\">');\n\t\t\t\tjQuery('#lasso-map-address').val(k + ', ' + B);\n\t\t\t}\n\n\t\t\tfunction setMapZoom(z) {\n\t\t\t\tjQuery('input[name=\"ase-map-component-zoom\"]').remove();\n\t\t\t\tjQuery('.lasso--map-form__footer').append('<input type=\"hidden\" name=\"ase-map-component-zoom\" data-ase=\"map\" value=\"' + z + '\">');\n\t\t\t}\n\n\t\t\tfunction onMarkerDrag(e) {\n\t\t\t\tupdateMarkerField(e.target);\n\t\t\t}\n\n\t\t\tfunction onMapDrag(e) {\n\t\t\t\tvar mapCenter = e.target.getCenter()\n\t\t\t\tsetMapCenter(rnd(mapCenter.lat),rnd(mapCenter.lng));\n\t\t\t}\n\n\t\t\tfunction onMapZoom(e) {\n\t\t\t\tsetMapZoom(e.target.getZoom());\n\t\t\t}\n\n\t\t\tfunction rnd(n) {\n\t\t\t\treturn Math.round(n * 100) / 100\n\t\t\t}\n\n\t\t\tfunction onMapClick(e) {\n\n\t\t\t    var geojsonFeature = {\n\n\t\t\t        \"type\": \"Feature\",\n\t\t\t        \"properties\": {},\n\t\t\t        \"geometry\": {\n\t\t\t                \"type\": \"Point\",\n\t\t\t                \"coordinates\": [e.latlng.lat, e.latlng.lng]\n\t\t\t        }\n\t\t\t    }\n\n\t\t\t    var marker;\n\n\t\t\t    L.geoJson(geojsonFeature, {\n\n\t\t\t        pointToLayer: function(feature, latlng){\n\n\t\t\t            marker = L.marker(e.latlng, {\n\n\t\t\t                title: 'Resource Location',\n\t\t\t                alt: 'Resource Location',\n\t\t\t                riseOnHover: true,\n\t\t\t                draggable: true,\n\n\t\t\t            }).bindPopup(\"\\\n\t\t\t            \t<input type='text' name='ase_marker_text[]' value='Location Title'>\\\n\t\t\t            \t<a class='marker-update-button dashicons dashicons-yes'/></a>\\\n\t\t\t            \t<a class='marker-delete-button dashicons dashicons-trash'/></a>\\\n\t\t\t            \t\");\n\n\t\t\t            marker.on('popupopen', onPopupOpen);\n\t\t\t            marker.on('dragend', onMarkerDrag);\n\n\t\t\t            return marker;\n\t\t\t        }\n\t\t\t    }).addTo(map);\n\n\t\t\t   \tcreateMarkerField( marker._leaflet_id, encodeMarkerData(e.latlng.lat, e.latlng.lng, 'Location Title') );\n\n\t\t\t}\n\n\t\t\t// open popup\n\t\t\tfunction onPopupOpen() {\n\n\t\t\t    var tempMarker = this;\n\n\t\t\t    // To remove marker on click of delete button in the popup of marker\n\t\t\t    jQuery('.marker-delete-button:visible').click(function () {\n\t\t\t    \tjQuery('input[data-marker=\"' + tempMarker._leaflet_id + '\"]').remove();\n\t\t\t      \tmap.removeLayer(tempMarker);\n\t\t\t    });\n\n\t\t\t    // Update the title of the location\n\t\t\t    jQuery('.marker-update-button:visible').click(function (t) {\n\t\t\t    \tvar title = t.target.previousElementSibling.value;\n\t\t\t    \tvar tdata = encodeMarkerData(tempMarker._latlng.lat, tempMarker._latlng.lng, title);\n\t\t\t    \tjQuery('input[data-marker=\"' + tempMarker._leaflet_id + '\"]').val(tdata);\n\t\t\t    \ttempMarker.options.title = title;\n\t\t\t    \ttempMarker.closePopup();\n\t\t\t    \ttempMarker.bindPopup(\"\\\n\t\t\t\t            \t<input type='text' name='ase_marker_text[]' value='\" + title + \"'>\\\n\t\t\t\t            \t<a class='marker-update-button dashicons dashicons-yes'/></a>\\\n\t\t\t\t            \t<a class='marker-delete-button dashicons dashicons-trash'/></a>\\\n\t\t\t\t            \t\");\n\t\t\t    });\n\t\t\t}\n\n\t\t\t// create map marker\n\t\t\tfunction createMapMarker(latlng, title) {\n\t            marker = L.marker(latlng, {\n\t              \ttitle: title,\n\t              \talt: title,\n\t              \triseOnHover: true,\n\t              \tdraggable: true,\n\t            }).bindPopup(\"\\\n\t            \t<input type='text' name='ase_marker_text[]' value='\" + title + \"'>\\\n\t            \t<a class='marker-update-button dashicons dashicons-yes'/></a>\\\n\t            \t<a class='marker-delete-button dashicons dashicons-trash'/></a>\\\n\t            \t\");\n\t            marker.on('popupopen', onPopupOpen);\n\t            marker.on('dragend', onMarkerDrag);\n\t            return marker;\n\t\t\t}\n\n\t\t\tfunction getAllMarkers() {\n\t\t\t    var allMarkersObjArray = []; // for marker objects\n\t\t\t    var allMarkersGeoJsonArray = []; // for readable geoJson markers\n\t\t\t    jQuery.each(map._layers, function (ml) {\n\t\t\t        if (map._layers[ml].feature) {\n\t\t\t          \tallMarkersObjArray.push(this)\n\t\t\t          \tallMarkersGeoJsonArray.push(JSON.stringify(this.toGeoJSON()))\n\t\t\t        }\n\t\t\t    })\n\t\t\t}\n\n\t\t\t// let's create a hidden form element for the marker\n\t\t\tfunction createMarkerField(mid, mdata) {\n\t\t\t  \tjQuery('.lasso--map-form__footer').append('<input type=\"hidden\" name=\"ase-map-component-locations[]\" data-ase=\"map\" data-marker=\"' + mid + '\" value=\"' + mdata + '\">');\n\t\t\t}\n\n\t\t\tfunction updateMarkerField(m) {\n\t\t\t\tvar tdata = encodeMarkerData(m._latlng.lat, m._latlng.lng, m.options.title);\n\t\t\t\tjQuery('input[data-marker=\"' + m._leaflet_id + '\"]').val(tdata);\n\t\t\t}\n\n\t\t\t// encode the information into a string\n\t\t\tfunction encodeMarkerData(mlat, mlng, mtitle) {\n\t\t\t\treturn encodeURIComponent(JSON.stringify({lat: mlat, lng: mlng, title: mtitle}));\n\t\t\t}\n\n\t\t\t// encode location into a string\n\t\t\tfunction encodeLocationData(mlat, mlng) {\n\t\t\t\treturn encodeURIComponent(JSON.stringify({lat: mlat, lng: mlng}));\n\t\t\t}\n\n\t\t\t// decode the information\n\t\t\tfunction decodeMarkerData(mdata) {\n\t\t\t\treturn decodeURIComponent(JSON.parse(mdata));\n\t\t\t}\n\t\t}\n        \n        // the code to enable map editing after reload.\n        if ($( \".aesop-map-component\" ).length) {\n            $( \".aesop-map-component\" ).replaceWith(setComponent(\"map\"));\n            mapsGoTime();\n        }\n\n\t\tfunction setComponent(type) {\n\t\t\t// if an image is dragged in\n\t\t\tvar comp =\"\";\n            if (!components[type] || !components[type]['content']) return null;\n\n\t\t\tif ( 'wpimg' == type && lasso_editor.oldWPimg) {\n\t\t\t\tcomp = $(components[type]['content']).prepend( wpImgEdit );\n\t\t\t// else it's likely an aesop component\n\t\t\t} else if ( 'htmlparagraph' != type && 'htmltable' != type) {\n\t\t\t\tcomp = $(components[type]['content'])\n\t\t\t\t\t\t\t.prepend( lassoDragHandle )\n\t\t\t\t\t\t\t.attr({\n\t\t\t\t\t\t\t\t'data-component-type': type\n\t\t\t\t\t\t\t});\n\t\t\t} else {\n                comp = $(components[type]['content']);\n            }\n\t\t\treturn comp;\n\t\t}\n\t\t\n\t\tfunction postComponent(comp,type) {\n            // set some figures to uneditable\n            $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\t\t\t// TODO: if a stock wordpress image is dragged in\t\t\t\n\n\t\t\tif ('timeline_stop' == type ) { lasso_editor.timelineGoTime() }\n\n\t\t\tif ('video' == type ) { videoGoTime() }\n\t\t\t$('#lasso-side-comp-button').remove();\n            if ( 'map' == type ) { \n                mapsGoTime(); \n            } else {\n                $(comp).find('.lasso-settings').trigger('click');\n            }\n\t\t}\n\t\t\n\t\t\t\t\n\t\tfunction  imgDialog( ){\n\t\t\tvar that = this;\n\t\t    // Create the media frame.\n\t\t    var lasso_file_frame = wp.media.frames.file_frame = wp.media({\n\t\t      \ttitle: 'Select Image',\n\t\t      \tbutton: {\n\t\t        \ttext: 'Insert Image',\n\t\t      \t},\n\t\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t\t    });\n\n\t\t    // When an image is selected, run a callback.\n\t\t    lasso_file_frame.on( 'select', function() {\n\t\t      \tvar attachment = lasso_file_frame.state().get('selection').first().toJSON();\n\t\t\t\t$(that).parent().data('imgid',''+attachment.id);\n\t\t\t\tif ($(that).parent().find('img').length > 0) {\n\t\t\t\t\t$(that).parent().find('img').attr('src', attachment.url );\n\t\t\t\t} else {i\n\t\t\t\t\t$(that).parent().css({\n\t\t\t\t  \t\t'background-image': 'url('+ attachment.url +')'\n\t\t\t\t  \t});\n\t\t\t\t}\n                // set some figures to uneditable\n                $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\n\t\t    });\n\n\t\t    // Finally, open the modal\n\t\t\tlasso_file_frame.open();\n\t\t};\n\n\t\t/////////////////\n\t\t/// DRAG DROP\n\t\t///////////////////\n\t\t// recent change: when a new component is dropped, the setting window is opened automatically\n\t\t$('#'+editor).sortable({\n\t\t\topacity: 0.65,\n\t\t\tplaceholder:'lasso-drop-zone',\n\t\t\thandle: '.lasso-drag',\n            cursor:'move',\n            tolerance:'pointer',\n            refreshPositions: true,\n            helper: function( e, ui ) {\n\n\t\t    \t// get the curent target and add the type class to the drag event\n\t\t\t\tvar item = ui['context'],\n\t\t\t\t\ttype = $(item).attr('data-component-type');\n\n            \treturn $('<div class=\"lasso-drag-holder lasso-toolbar--component__'+type+'\"></div>');\n            },\n        \tbeforeStop: function (event, ui) { draggedItem = ui.item },\n            receive: function (event,ui) {\n\n            \t// close modal drag\n            \t$('#lasso-toolbar--components').removeClass('toolbar--drop-up');\n\n\t\t\t\tarticleMedium.makeUndoable();\n            \t// get the item and type\n\t\t\t\tvar item = draggedItem['context'];\n                if (!item) item = draggedItem;\n\t\t\t\tvar type = $(item).attr('data-type');\n\t\t\t\t// item2 will be the content tthat gets inserted. It also has edit controls\n                \n\n\t\t\t\t// if coming from draggable replace with our content and prepend toolbar\n\t\t\t\tif ( origin == 'draggable' ) {\n\t\t\t\t\t// check if it's inserted at the end\n\t\t\t\t\tvar newIndex = $(this).data(\"ui-sortable\").currentItem.index();\n\t\t\t\t    var sortable_len = $(this).data(\"ui-sortable\").items.length;\n\t\t\t\t\tvar last = false;\n\t\t\t\t\tif (newIndex>= (sortable_len-1)) {\n\t\t\t\t\t\tlast = true;\n\t\t\t\t\t\t\n\t\t\t\t\t}\n\n\t\t\t\t\t\n\t\t\t\t\tvar item2 = setComponent(type);\n\t\t\t\t\t\n\t\t\t\t\tif (last) {\n\t\t\t\t\t\titem2.append('<p><br></p>');\n\t\t\t\t\t}\n\t\t\t\t\t$(item).replaceWith( item2);\n\t\t\t\t\t\n\n\t\t\t\t\tpostComponent(item2,type);\n\t\t\t\t\t\n\t\t\t\t}\n\n\t\t    }\n\t\t});\n        \n        \n        lasso_editor.addComponentButton = function()\n        {\n\t\t\t// this function checks the current selected element and adds the component button if appropriate\n\t\t\tif (!lasso_editor.buttonOnEmptyP) {\n\t\t\t\t// if this feature is not turned on, return\n\t\t\t\treturn;\n\t\t\t}\n\t\t\twindow.selRange = saveSelection();\n            if (!window.selRange) return;\n\t\t\tvar container = window.selRange.startContainer,\n\t\t\tcontainerTag;\n            if ($(container).attr('id') == \"lasso--content\") {\n                container = $(container).children()[0];\n            }\n\t\t\t$('#lasso-side-comp-button').remove();\n\t\t\tcontainerTag = container.localName;\n\t\t\tparentTag = $(container).parent().prop(\"tagName\");\n            \n            if ($(container).parent().attr('id') != \"lasso--content\") {\n\t\t\t\tif (parentTag == 'figure' || parentTag == 'div' || $(container).parent().parent().attr('id') != \"lasso--content\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\t\t\t\n            \n\t\t\tif ( containerTag == 'p' || ((containerTag=='b' || containerTag=='em' || containerTag=='i' || containerTag=='strike' || containerTag=='span') && $(container).parent().text() == \"\")) \n\t\t\t{\t\n\t\t\t\tvar innerText = container.innerText.replace(/(\\r\\n|\\n|\\r)/gm,\"\");\n\t\t\t\tif (innerText != \"\") {\n\t\t\t\t\t//this paragraph is not empty, return\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar top_ = container.offsetTop-10;\n\t\t\t\tvar left_ = container.offsetLeft-30;\n\t\t\t\t\n\t\t\t\tif ($(container).parent().attr('id') != \"lasso--content\") {\n\t\t\t\t\t$(container).parent().empty();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar button = $('<div id=\"lasso-side-comp-button\" style=\"width:30px;height:30px;position:absolute;\" contenteditable=\"false\"></div>');\n\t\t\t\tbutton.css({top:top_,left:left_});\n    \n\t\t\t\t$(\"#lasso--content\").append(button);\n\t\t\t\tif (button.offset().left<0) {\n\t\t\t\t\tbutton.offset({left:0});\n\t\t\t\t}\n\t\t\t}\n        }\n\n\n        // the following codes decide which UI triggers drag-drop and which UI triggers click-insert\n        // If we are only using drag-drop then clickToInsertElement would be empty\n\t\tvar clickToInsertElement = '#lasso-side-comp-button #lasso-toolbar--components__list li';\n\t\tif (lasso_editor.clickToInsert) {\n\t\t\tclickToInsertElement = '#lasso-toolbar--components__list li'\n\t\t} \t\t\n\t\t\t\n\t\telse \n\t\t{\n\t\t\t$('#lasso-toolbar--components #lasso-toolbar--components__list li').draggable({\n\t\t\t\taxis:'y',\n\t\t\t\thelper:'clone',\n\t\t\t\tcursor: 'move',\n\t\t\t\tconnectToSortable: '#'+editor,\n\t\t\t\tstart: function(ui) {\n\n\t\t\t\t\t// add an origin so sortable can detect where comign from\n\t\t\t\t\torigin = 'draggable';\n\n\t\t\t\t\t// get the curent target and add the type class to the drag event\n\t\t\t\t\tvar item = ui.currentTarget,\n\t\t\t\t\t\ttype = $(item).attr('data-type');\n\n\t\t\t\t\t$(this).addClass(type);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tjQuery(document).on('mousedown', clickToInsertElement, function(){\n\t\t\t\tvar type = $(this).attr('data-type');\n\t\t\t\tvar item = setComponent(type);\n\t\t\t\trestoreSelection(window.selRange);\n                $('#lasso-side-comp-button').remove();\n                if ($('#'+editor).children().length==1 && $('#'+editor).find('.editus-firstp').length ==1) {\n                    $('.editus-firstp').replaceWith(item);\n                } else {\n                    var t = insert_html(item, false);\n                }\n\t\t\t\t\n\t\t\t\tpostComponent(item,type);\n\t\t\t\tlasso_editor.addComponentButton();\n\t\t});\n            \n                    \n        // replace the content if the content is empty\n        if ( $('#'+editor).children().length && $('#'+editor).children().prop(\"tagName\") == \"P\" && $('#'+editor).children().text() == \"\") {\n            $('#'+editor).html(lasso_editor.newObjectContent);\n            $('#'+editor).children().focus();\n            lasso_editor.addComponentButton();\n        }\n        \n        lasso_editor.hidePopup = function(){\n            $(\".lasso--text-popup\").hide();\n\t\t}\n        \n        lasso_editor.checkForPopup = function()\n        {\n            if (!lasso_editor.toolbarPopup) return;\n            \n            s = window.getSelection();\n            oRange = s.getRangeAt(0); //get the text range\n            if (!oRange.collapsed ) {\n                oRect = oRange.getBoundingClientRect();\n                ;\n                oRect2 = document.getElementById(editor).getBoundingClientRect();\n                oRect3 = document.body.getBoundingClientRect();\n                var t2 = $('body').offset().top;\n                //var t2 = document.body.offsetTop.getBoundingClientRect().top;\n                var left = ((oRect.right+oRect.left) - $(\".lasso--text-popup\").width())/2;\n                if (left <= 0) left = 0;\n                var t = oRect.bottom-document.body.getBoundingClientRect().top;\n                $(\".lasso--text-popup\").css(\"left\",left);\n                $(\".lasso--text-popup\").css(\"top\",t+t2);\n                $(\".lasso--text-popup\").css(\"display\",\"table\");\n                $(\".lasso--text-popup\").css(\"position\",\"absolute\");\n            } else {\n                lasso_editor.hidePopup();\n            }\n        };\n\t\t\n\t\t$('#'+editor).on('mouseup',function() {\n            lasso_editor.checkForPopup();\n        });\n        \n        $('#'+editor).focusout(function() {\n            lasso_editor.hidePopup();\n        });\n\t\t\n            \n        // ways to inject codes into the enterEditor\n\t\tif (lasso_editor.enterEditorHookArray2) {\n\t\t\t$(lasso_editor.enterEditorHookArray2).each(function(key, val){\n\t\t\t\tval();\n\t\t\t});\n\t\t}   \n\n\t});\n\tif (lasso_editor.skipToEdit)\n\t{\n\t\t$('#lasso--edit').trigger('click');\n\t\tlasso_editor.skipToEdit = false;\n\t}\n\t\n\tif (lasso_editor.setupHookArray) {\n\t\t$(lasso_editor.setupHookArray).each(function(key, val){\n\t\t\tval();\n\t\t});\n\t}\n});\n\n\n\n\n\n\n(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t/////////////////\n\t\t/// MODAL LOGIC\n\t\t///////////////////\n\n\t\t// method to destroy the modal\n\t\tvar destroyModal = function(){\n\t\t\t$('body').removeClass('lasso-modal-open');\n\t\t\t$('#lasso--post-settings__modal, #lasso--modal__overlay').remove();\n\t\t}\n\t\t\n\t\tjQuery(document).on('click', '.lasso--postsettings__option', function(e){\n\t\t\tif ($(e.target).hasClass('tagit')) {\n\t\t\t\t// close the modal window if the user clicks on empty spaces\n\t\t\t\t// destroy posts modal\n\t\t\t\t\n\t\t\t\tdestroyModal();\n\t\t\t}\t\t\t\n\t\t});\n\n\t\t// modal click\n\t\t//$('#lasso--post-settings').live('click',function(e){\n\t\tjQuery(document).on('click','#lasso--post-settings, #lasso--post-settings2',function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\t// add a body class\n\t\t\t$('body').toggleClass('lasso-modal-open');\n\n\t\t\t// append teh modal markup ( lasso_editor_component_modal() )\n\t\t\t$('body').append(lasso_editor.component_modal);\n\n\t\t\t/////////////////\n\t\t\t/// UI SLIDER INIT AND METHODS\n\t\t\t///////////////////\n\n\t\t\tvar statusReturn = function( value ) {\n\n\t\t\t\tvar out;\n\t\t\t\tif ( 100 == value ) {\n\t\t\t\t\tout = 'draft';\n\t\t\t\t} else if ( 150 == value ) {\n\t\t\t\t\tout = 'pending';\n\t\t\t\t} else if ( 200 == value ) {\n\t\t\t\t\tout = 'publish';\n\t\t\t\t} else if ( 'draft' == value ) {\n\t\t\t\t\tout = 100;\n\t\t\t\t} else if ( 'pending' == value ) {\n\t\t\t\t\tout = 150;\n\t\t\t\t} else if ( 'publish' == value ) {\n\t\t\t\t\tout = 200;\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t}\n\n\t\t\t// init slider\n\t\t    $('#lasso--slider').slider({\n\t\t      \tvalue:statusReturn(lasso_editor.post_status),\n\t\t      \tmin: 100,\n\t\t      \tmax: 200,\n\t\t      \tstep: lasso_editor.supportPendingStatus ? 50 : 100,\n\t\t      \tanimate:'fast',\n\t\t      \tslide: function( event, ui ) {\n\t\t        \t$('input[name=\"status\"]').val( statusReturn(ui.value) );\n\n\t\t        \t$('.lasso--postsettings__footer').slideDown()\n\n\t\t        \tif ( 100 == ui.value ) {\n\t\t        \t\t$('.story-status').removeClass('story-status-publish').addClass('story-status-draft')\n\t\t        \t} else if ( 200 == ui.value ) {\n\t\t        \t\t$('.story-status').removeClass('story-status-draft').addClass('story-status-publish')\n\t\t        \t}\n\t\t      \t}\n\t\t    });\n\t\t    $('input[name=\"status\"]').val( statusReturn( $( \"#lasso--slider\" ).slider('value') ) );\n\n\t\t    /*// if any changes happen then show the footer\n\t\t    $('.lasso--modal__trigger-footer').on('keyup',function(){\n\t\t\t  \t$('.lasso--postsettings__footer').slideDown()\n\t\t\t});*/\n\n\t\t    // categories\n\t\t    var cats = $('#lasso--cat-select')\n\t\t    ,\ttags = $('#lasso--tag-select')\n            ,   custom = $('#lasso--custom-taxo-input')\n\n\t\t\tcats.tagit({\n\t\t\t\t//fieldName:'itemName[fieldName][]',\n\t\t\t\tplaceholderText: lasso_editor.strings.catsPlaceholder, //'add categories...',\n\t\t\t\tavailableTags: lasso_editor.postCategories,\n                allowSpaces: true\n\t\t\t});\n\n\t\t\tcats.on('change',function(event){\n\t\t\t\t$('.lasso--postsettings__footer').slideDown()\n\t\t\t})\n\n\t\t\ttags.tagit({\n\t\t\t\t//fieldName:'itemName[fieldName][]',\n\t\t\t\tplaceholderText: lasso_editor.strings.tagsPlaceholder,//'add tags...',\n\t\t\t\tavailableTags: lasso_editor.postTags,\n                allowSpaces: true\n\t\t\t});\n\n\t\t\ttags.on('change',function(event){\n\t\t\t\t$('.lasso--postsettings__footer').slideDown()\n\t\t\t})\n\t\t\t\n\t\t\tif( $('.editus_custom_date').length ) {\n\t\t\t\t$('.editus_custom_date').datepicker({});\n\t\t\t}\n            \n            if (lasso_editor.supCustTaxo) {           \n                var selTaxo = $('#lasso--custom-taxo-select').val();\n                custom.val(lasso_editor.postCusTaxonomies[selTaxo]);\n                custom.tagit({\n                    placeholderText: lasso_editor.strings.catsPlaceholder,//'add tags...',\n                    availableTags: lasso_editor.extCusTaxonomies[selTaxo],\n                    allowSpaces: true\n                });\n                              \n                $('#lasso--custom-taxo-select').on('change', function() {\n                    lasso_editor.postCusTaxonomies[selTaxo] = custom.val();\n                    \n                    custom.tagit(\"destroy\");\n                    custom.val(lasso_editor.postCusTaxonomies[$(this).val()]);\n                    custom.tagit({\n                        placeholderText: lasso_editor.strings.taxoPlaceholder, //'add categories...',\n                        availableTags: lasso_editor.extCusTaxonomies[$(this).val()],\n                        allowSpaces: true\n                    });\n                                   \n                    selTaxo = $(this).val();\n                });\n            }\n\n\t\t\tmodalResizer()\n\n\t\t});\n\n\t\t// destroy modal if clicking close or overlay\n\t\t//$('#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel').live('click',function(e){\n\t\tjQuery(document).on('click', '#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel', function(e){\n\t\t\te.preventDefault();\n\t\t\tdestroyModal();\n\t\t});\n\n\t\t/////////////////\n\t\t/// EXIT SETTINGS\n\t\t///////////////////\n\t\t$(document).keyup(function(e) {\n\n\t\t\tif ( 27 == e.keyCode ) {\n\n\t\t\t\tdestroyModal();\n\t\t\t}\n\n\t\t});\n\n\t\t/////////////\n\t\t// SAVE SETTINGS\n\t\t//////////////\n\t\tvar form;\n\n\t\t//$('#lasso--postsettings__form').live('submit', function(e) {\n\t\t\t\t//$('#lasso--postsettings__form').live('submit', function(e) {\n\t\tjQuery(document).on('submit','#lasso--postsettings__form',function(e) {\n\n\t\t\te.preventDefault();\n\t\t\tif ($('#lasso--custom-field-form').length ==0 || $('#lasso--custom-field-form').children().length == 0 ) {\n                $('#lasso--save').removeClass('lasso-publish-post');\n\t\t\t\t$('#lasso--save').trigger('click');\n\t\t\t}\n\n\t\t\tvar $this = $(this);\n\t\t\t\n\t\t\t/*\n\t\t\t//alternate way of setting categories, disabled for now\n\t\t\tvar cats = [];\n\t\t\t\n\t\t\t$('input[name=\"categories\"]').each(function () {\n\t\t\t\tif (this.checked) { cats.push(this.id);}\n\t\t\t});\n\t\t\tif (cats.length>0) {\n\t\t\t\t$('input[name=\"story_cats\"]').val(cats.join(','));\n\t\t\t}*/\n            \n            if (lasso_editor.supCustTaxo) {          \n                var selTaxo = $('#lasso--custom-taxo-select').val();\n                lasso_editor.postCusTaxonomies[selTaxo] = $('#lasso--custom-taxo-input').val();\n                $(this).find(\"input[name=story_custom_taxonomies]\" ).val(JSON.stringify(lasso_editor.postCusTaxonomies));\n            }\n\n\t\t\t$(this).find('input[type=\"submit\"]').val(lasso_editor.strings.saving);\n\n\t\t\t\n\t\t\tvar data2 = $this.serialize();\n\n\t\t\t/////////////\n\t\t\t//\tDO THE SAVE\n\t\t\t/////////////\n\t\t\t\t\n\t\t\tvar data = {\n\t\t\t\taction: 'editus_set_post_setting',\n\t\t\t    postid: lasso_editor.postid,\n\t\t\t\tdata: data2\n\t\t\t};\n\t\t\t\t\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n\t\t\t\tif( true == response.success ) {\n\t\t\t\t\t$('input[type=\"submit\"]').addClass('saved');\n\t\t\t\t\t$('input[type=\"submit\"]').val(lasso_editor.strings.saved);\n                    window.onbeforeunload = null;\n\t\t\t\t\t\n\t\t\t\t\tif ($('#lasso--custom-field-form').length && $('#lasso--custom-field-form').children().length) {\n\t\t\t\t\t\t$('#lasso--custom-field-form').trigger('submit');\n\t\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t  window.location.replace(response.data['link']);\n\t\t\t\t\t\t}, 1000);\n\t\t\t\t\t} else {\n                        // changing the setting can potentially change the URL of the post. In that case we need to\n                         // reload the post\n\t\t\t\t\t    window.location.replace(response.data['link']);\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\talert('error:'+response);\n\t\t\t\t\tconsole.log(response)\n\n\t\t\t\t}\n\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\t\t});\n\n\t\t/////////////\n\t\t// ADDON TABS\n\t\t//////////////\n\t\t$(document).on('click', '.lasso--modal__tabs li', function(e){\n\n\t\t\te.preventDefault()\n\n\t\t\tvar $this\t= $(this)\n\t\t\t,\tname  \t= $this.data('addon-name')\n\t\t\t,\trem \t= 'not-visible'\n\t\t\t,\tadd    \t= 'visible'\n\n\t\t\t$('.lasso--modal__tabs li').removeClass('active-tab')\n\n\t\t\t$this.addClass('active-tab')\n\n\t\t\t$('.lasso--modal__content').removeClass( add ).addClass( rem )\n\n\t\t\t$this.closest('.lasso--modal__inner').find('div[data-addon-content=\"'+name+'\"]').removeClass( rem ).addClass( add )\n\n\t\t\tmodalResizer()\n\t\t})\n\n\t});\n\n})( jQuery );\n(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t// helper to dstry the sidebar\n\t\tvar destroySidebar = function(){\n\t\t\t$('body').removeClass('lasso-sidebar-open');\n\t\t}\n\n\t\t// close the sidebar when clicking outside of it\n\t\t$('body').on('click', '#'+lasso_editor.editor, function(){\n             //lets not for now\n\t\t\t//destroySidebar()\n\t\t});\n\n\t\t// helper to set the height of the settings panel\n\t\tvar settingsHeight = function(){\n\n\t\t\tvar settings = $('#lasso--component__settings');\n\n\t\t\tsettings.height( $(window).height() );\n\n\t\t\t$(window).resize(function(){\n\t\t\t\tsettings.height( $(window).height() );\n\t\t\t\t//$('#lasso--component__settings').perfectScrollbar('update');\n\t\t\t});\n\t\t}\n\n\t\tvar component, data;\n\n\t\t/////////////\n\t\t// OPEN COMPONENT SETTINGS\n\t\t////////////\n\t\t$(document).on('click','.lasso-component--settings__trigger',function(){\n\n\t\t\tvar settings \t= $('#lasso--component__settings')\n\t\t\tvar click       = $(this)\n\n\t\t\t// let's set our globals\n\t\t\tif ( $(this).parent().parent().hasClass('aesop-map-component') ) {\n\t\t\t\tcomponent = $(this).parent().parent().find('.aesop-component');\n\t\t\t} else {\n\t\t\t\tcomponent = $(this).closest('.aesop-component,.lasso-component,.wp-block-image,.wp-block-cover');\n\t\t\t}\n            \n            data = component.data();\n            if (!data) { return;}\n\n\t\t\t// let's force globalize this until we refactor the js\n\t\t\twindow.component = component;\n\t\t\twindow.componentClone = component.clone();\n\t\t\t\n            if (data['componentType'] == 'wpimg') {\n                if ($(component).find('figure.lasso-component').length) {\n                    data = $(component).find('figure.lasso-component').data();//'.wp-image.lasso-component').data();\n                } else if ($(component).find('img').length) {\n                    data['img'] =$(component).find('img').attr('src');\n                }\n            }\n            \n            if (data['componentType'] == 'wpimg-block') {\n\t\t\t\tif ($(component).find('img').length) {\n\t\t\t\t\tvar $img = $(component).find('img');\n                    data['img'] =$img.attr('src');\n\t\t\t\t\tdata['alt'] =$img.attr('alt');\n\t\t\t\t\tvar c = $img.attr('class');\n                    \n                    var $fig = $(component).find('figure');\n                    if ($fig.hasClass('alignright')) {\n                        data['align']='right';\n                    } else if ($fig.hasClass('aligncenter')) {\n                        data['align']='center';\n                    } else if ($fig.hasClass('alignleft')) {\n                        data['align']='left';\n                    }\n\t\t\t\t\n\t\t\t\t\tif (c && c.indexOf('wp-image-') == 0) {\n\t\t\t\t\t\tdata['id'] = c.substr(9);\n\t\t\t\t\t}\n                    if ($(component).find('figcaption').length) {\n                        data['caption'] = $(component).find('figcaption').text();\n                    }\n                    if ($(component).find('a').length) {\n                        data['link'] = $(component).find('a').attr(\"href\");\n                    }\n                }\n\t\t\t}\n            \n            if (data['componentType'] == 'wpcover-block') {\n\t\t\t\tif ($(component).find('img').length) {\n\t\t\t\t\tvar $img = $(component).find('img');\n                    data['img'] =$img.attr('src');\n                }\n\t\t\t}\n            \n            if (data['componentType'] =='wpquote') { return;}\n            \n            if (!lasso_editor.component_options) return;\n\t\t\t// special case for hero gallery\n\t\t\tif ( $(this).parent().parent().hasClass('aesop-hero-gallery-wrapper') ) {\n\t\t\t    jQuery.extend(data, $(component).find(\".fotorama\").data());\n\t\t\t}\n\n\t\t\t// add a body class\n\t\t\t$('body').toggleClass('lasso-sidebar-open');\n\n\t\t\tsettings.find('input[name=\"unique\"]').val( data['unique'] );\n\n\t\t\t// set up settings panel\n\t\t\tsettingsHeight();\n\t\t\tsettings.html( lasso_editor.component_options[data.componentType] );\n\n\t\t\t// add the type as a value in a hidden field in settings\n\t\t\tsettings.find('.component_type').val( data.componentType );\n\n\t\t\t// fade in save controls\n\t\t\t$('.lasso-buttoninsert-wrap').fadeIn(600);\n\n\t\t\t// initialize scrolbar\n\t\t\tsettings.perfectScrollbar('destroy');\n\t\t\tsettings.perfectScrollbar();\n\n\t\t\t// map the settings from the data attributes on components into appropriate settings in settings panel\n\t\t\tsettings.find('.lasso-option').each(function(){\n\n\t\t\t\tvar option = $(this).data('option');\n\t\t\t\tvar field = $(this).find('.lasso-generator-attr');\n\n\t\t\t\t// if it's a gallery data attribute map the cehcekd attribute to the right place\n\t\t\t\t// @todo - account for map stuff\n\t\t\t\tif ( 'gallery-type' == option ) {\n\n\t\t\t\t\t// this function is repeated on process-gallery-opts line 4\n\t\t\t\t\tvar value_check = function( value ){\n\n\t\t\t\t\t\tif ( 'grid' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeIn();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( 'thumbnail' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeIn();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( 'photoset' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeIn();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tif ( 'hero' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeIn();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$(field).each(function(){\n\n\t\t\t\t\t\tif ( $(this).val() == data.galleryType ) {\n\n\t\t\t\t\t\t\t$(this).parent().addClass('selected')\n\t\t\t\t\t\t\t$(this).prop('checked',true);\n\n\t\t\t\t\t\t\tvalue_check( $(this).val() );\n\n\t\t\t\t\t\t\t// add the type to a hidden field\n\t\t\t\t\t\t\t$('#ase_gallery_type').val( $(this).val() )\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t});\n\n\t\t\t\t} else {\n\n\t\t\t\t\t$( field[0] ).val(data[option]);\n\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t\t////////////\n\t\t\t// SMOOTH SLIDE TO COMPONENT - @since 0.9.5\n\t\t\t///////////\n\n\t\t\t// if its a content component\n\t\t\tif ( component.hasClass('aesop-content-component') ) {\n\n\t\t\t\tvar target = component.find('.aesop-content-comp-wrap').attr('id')\n\t\t\t\t, \titem = $('#'+target)\n\n\t\t\t} else {\n\n\t\t\t\tvar item = $('#'+component.attr('id') )\n\t\t\t}\n\n            if (item.length) {\n                //$('html, body').animate({ scrollTop: item.offset().top - 50  }, 400);\n            }\n\n\t\t\t/////////////\n\t\t\t// GET GALLERY IMAGES IF ITS A GALLERY\n\t\t\t/////////////\n\n\t\t\t//if ( $(this).parent().parent().hasClass('empty-gallery') ) {\n\t\t\t\t//settings.addClass('gallery-no-images')\n\t\t\t//}\n\n\t\t\tif ( $(this).parent().parent().hasClass('aesop-gallery-component') ) {\n\n\t\t\t\tvar $this \t\t= $(this)\n\t\t\t\t,\tajaxurl \t= lasso_editor.ajaxurl\n\t\t\t\t,\tform \t\t= $('#lasso--component-settings-form.gallery')\n\t\t\t\t,\tnonce \t\t= lasso_editor.getGallImgNonce\n\t\t\t\t,\tgall_id \t= data['id']\n\n\t\t\t\tvar data      = {\n\t\t\t\t\taction:    \t'process_gallery_get-images',\n\t\t\t\t\tpost_id:   \tgall_id,\n\t\t\t\t\tnonce: \t\tnonce\n\t\t\t\t};\n\n\t\t\t\t// post ajax response with data\n\t\t\t\t$.post( ajaxurl, data, function(response) {\n\n\t\t\t\t\t$('#lasso--gallery__images').html( response.data.html );\n\n\t\t\t\t\t/////////////\n\t\t\t\t\t// CALL SORTABLE ON RECIEVED IMAGES\n\t\t\t\t\t/////////////\n\t\t\t\t\tvar\tgallery = $('#ase-gallery-images');\n\n\t\t\t\t\tgallery.ready(function(){\n\n\t\t\t\t\t\tgallery.sortable({\n\t\t\t\t\t\t\tcontainment: 'parent',\n\t\t\t\t\t\t\tcursor: 'move',\n\t\t\t\t\t\t\topacity: 0.8,\n\t\t\t\t\t\t\tplaceholder: 'ase-gallery-drop-zone',\n\t\t\t\t\t\t\tforcePlaceholderSize:true,\n\t\t\t\t\t\t\tupdate: function(){\n\t\t\t\t\t\t\t\tvar imageArray = $(this).sortable('toArray');\n\t\t\t\t\t\t  \t\t$('#ase_gallery_ids').val( imageArray );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcreate: function(){\n\t\t\t\t\t\t\t\tvar imageArray = $(this).sortable('toArray');\n\t\t\t\t\t\t  \t\t$('#ase_gallery_ids').val( imageArray );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}).fail(function(xhr, err) { \n\t\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t\t});;\n\n\t\t\t}\n\n\t\t}).on('click', '#lasso-upload-img', function( e ){\n\n\t\t    e.preventDefault();\n\n\t\t    className = e.currentTarget.parentElement.className;\n\n\t\t    var type   = $('input[name=\"component_type\"]').val()\n\n\t\t    // If the media frame already exists, reopen it.\n\t\t\tif ( typeof lasso_file_frame != 'undefined' ) {\n\t\t\t\tlasso_file_frame.close();\n\t\t\t}\n\n\t\t    // Create the media frame.\n\t\t    lasso_file_frame = wp.media.frames.file_frame = wp.media({\n\t\t      \ttitle: 'Select Image',\n\t\t      \tbutton: {\n\t\t        \ttext: 'Insert Image',\n\t\t      \t},\n\t\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t\t    });\n\n\t\t    // When an image is selected, run a callback.\n\t\t    lasso_file_frame.on( 'select', function() {\n\n\t\t      \tvar attachment = lasso_file_frame.state().get('selection').first().toJSON();\n\n\t\t      \t$('.aesop-generator-attr-media_upload').prop('value',attachment.url);\n\n\t\t\t\t/////////////\n\t\t\t\t// START LIVE IMAGE EDITING COMPONENTS\n\t\t\t\t// @todo - this was going to be taken care of in above but it seems we have to bind this to the file upload here?\n\t\t\t\t////////////\n\t\t      \tif ( 'parallax' == type ) {\n\n\t\t\t\t  \tcomponent.find('.aesop-parallax-sc-img').prop('src', attachment.url )\n\n\t\t      \t} else if ( 'quote' == type ) {\n\n\t\t\t\t  \tcomponent.css({\n\t\t\t\t  \t\t'background-image': 'url('+ attachment.url +')'\n\t\t\t\t  \t});\n\n\t\t      \t} else if ( 'image' == type ) {\n                    $(\"#aesop-generator-attr-img\").val(attachment.url);\n\t\t\t\t  \tcomponent.find('.aesop-image-component-image > img').prop('src', attachment.url);\n\t\t\t\t\t// new addition for panorama images\n\t\t\t\t\tcomponent.find('.paver__pano').css({'background-image': 'url('+ attachment.url +')'});\n\n\t\t      \t} else if ( 'character' == type ) {\n\n\t\t\t\t  \tcomponent.find('.aesop-character-avatar').prop('src', attachment.url)\n\n\t\t      \t} else if ( 'chapter' == type ) {\n\n\t\t      \t\tcomponent.find('.aesop-article-chapter').css({\n\t\t\t\t  \t\t'background-image': 'url('+ attachment.url +')'\n\t\t\t\t  \t});\n\n\t\t      \t}else if ( 'wpimg' == type ) {\n                    var img = window.component.find('img');\n                    if (img.length>0) {\n\t\t      \t\t   img.prop('src', attachment.url );\n                       img.prop(\"srcset\",\"\");\n                    }\n\t\t      \t}\n                else if ( 'wpimg-block' == type ) {\n                    var img = window.component.find('img');\n                    if (img.length >0) {\n\t\t      \t\t   img.prop('src', attachment.url );\n                       img.prop(\"srcset\",\"\");\n\t\t\t\t\t   if (attachment.id) {\n                           img.removeClass();\n\t\t\t\t\t\t   img.addClass(\"wp-image-\"+attachment.id);\n                           window.component.data( 'id', \"\"+attachment.id);\n\t\t\t\t\t   }\n                    }\n\t\t      \t}\n                else if ( 'wpcover-block' == type ) {\n                    var img = window.component.find('img');\n                    if (img.length >0) {\n\t\t      \t\t   img.prop('src', attachment.url );\n                       img.prop(\"srcset\",\"\");\n                       img.removeClass();\n                       img.addClass(\"wp-block-cover__image-background\");\n\t\t\t\t\t   if (attachment.id) {\n\t\t\t\t\t\t   img.addClass(\"wp-image-\"+attachment.id);\n\t\t\t\t\t   }\n                    } else {\n                       window.component.css('background-image', \"url(\"+attachment.url+\")\");\n                    }\n\n\t\t      \t}\n\t\t\t\t/////////////\n\t\t\t\t// EDN LIVE IMAGE EDITING COMPONENTS\n\t\t\t\t////////////\n\n\t\t    });\n\n\t\t    // Finally, open the modal\n\t\t\tlasso_file_frame.open();\n\t\t});\n\n\t\t// destroy panel if clicking close or overlay\n\t\t//$('#lasso--sidebar__close').live('click',function(e){\n\t\t// cancel \n\t\tjQuery(document).on('click','#lasso--sidebar__close',function(e){\n\t\t\te.preventDefault();\n\t\t\twindow.component.replaceWith(window.componentClone); //restore the state before editing\n\t\t\tdestroySidebar();\n\t\t\t$('#lasso--component__settings').perfectScrollbar('destroy');\n\t\t});\n\n});\n\n})( jQuery );\n\n(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t/////////////\n\t\t// LIVE EDITING COMPONENTS\n\t\t// @todo - this is hella dirty and needs to be cleaned up\n\t\t// @todo - move this mess to it's own file\n\t\t////////////\n\n\t\t$(document).on('click', '.lasso-component--settings__trigger', function(){\n\n\t\t\tvar settings \t= $('#lasso--component__settings')\n\n\t\t\t// QUOTE LIVE EDIT ///////////////////\n\t\t\t//settings.find('#aesop-generator-attr-background').live('change',function(){\n\t\t\tsettings.find('#aesop-generator-attr-background').on('change',function(){\n\t\t\t  \tcomponent.css({'background-color': $(this).val()});\n\t\t\t});\n\t\t\t//settings.find('#aesop-generator-attr-text').live('change',function(){\n\t\t\tsettings.find('#aesop-generator-attr-text').on('change',function(){\n\t\t\t  \tcomponent.css({'color': $(this).val()});\n\t\t\t});\n\t\t\tsettings.find('#aesop-generator-attr-quote').on('keyup',function(){\n\t\t\t  \tcomponent.find('blockquote span').text( $(this).val() );\n\t\t\t});\n\t\t\tsettings.find('#aesop-generator-attr-cite').on('keyup',function(){\n\n\t\t\t\tvar t = component.find('blockquote cite');\n\n\t\t\t\tif ( 0 == t.length ) {\n\n\t\t\t\t\tcomponent.find('blockquote').append( '<cite class=\"aesop-quote-component-cite\">'+$(this).val()+'</cite>' );\n\n\t\t\t\t} else {\n\t\t\t  \t\tcomponent.find('blockquote cite').text( $(this).val() );\n\t\t\t\t}\n\t\t\t});\n\t\t\tsettings.find('.aesop-quote-width > #aesop-generator-attr-width').on('keyup',function(){\n\t\t\t\tcomponent.css('width', $(this).val() );\n\t\t\t});\n\t\t\tsettings.find('.aesop-quote-type #aesop-generator-attr-type').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'pull' == value ) {\n\t\t\t\t\tcomponent.css('background-color','transparent')\n\t\t\t\t}\n\n\t\t\t\tcomponent.removeClass('aesop-quote-type-block aesop-quote-type-pull')\n\n\t\t\t\tcomponent.addClass('aesop-quote-type-'+$(this).val()+' ')\n\t\t\t});\n\n\t\t\tsettings.find('.aesop-quote-align #aesop-generator-attr-align').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'left' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-right aesop-component-align-center')\n\t\t\t\t\tcomponent.find('blockquote').removeClass('aesop-component-align-right aesop-component-align-center')\n\n\t\t\t\t} else if ( 'right' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-left aesop-component-align-center')\n\t\t\t\t\tcomponent.find('blockquote').removeClass('aesop-component-align-left aesop-component-align-center')\n\n\t\t\t\t} else if ( 'center' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-left aesop-component-align-right')\n\t\t\t\t\tcomponent.find('blockquote').removeClass('aesop-component-align-left aesop-component-align-right')\n\n\t\t\t\t}\n\t\t\t\tcomponent.addClass('aesop-component-align-'+$(this).val()+' ')\n\t\t\t\tcomponent.find('blockquote').addClass('aesop-component-align-'+$(this).val()+' ')\n\t\t\t});\n\n\t\t\t// PARALLAX LIVE EDIT ///////////////////\n\t\t\tsettings.find('.aesop-parallax-caption > #aesop-generator-attr-caption').on('keyup',function(){\n\n\n\t\t\t\tvar t = component.find('.aesop-parallax-sc-caption-wrap')\n\n\t\t\t\tif ( 0 == t.length ) {\n\n\t\t\t\t\tcomponent.find('img').after( '<figcaption class=\"aesop-parallax-sc-caption-wrap bottom-left\">'+$(this).val()+'</figcaption>' );\n\n\t\t\t\t} else {\n\t\t\t  \t\tcomponent.find('.aesop-parallax-sc-caption-wrap').text( $(this).val() );\n\t\t\t\t}\n\t\t\t})\n\t\t\tsettings.find('.aesop-parallax-captionposition > #aesop-generator-attr-captionposition').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'bottom-left' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right top-left top-right')\n\n\t\t\t\t} else if ( 'bottom-right' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-left top-left top-right')\n\n\t\t\t\t} else if ( 'top-left' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right top-right bottom-left')\n\n\t\t\t\t} else if ( 'top-right' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right bottom-left top-left')\n\n\t\t\t\t}\n\n\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').addClass( value );\n\n\t\t\t})\n\n\t\t\t// IMAGE LIVE EDIT ///////////////////\n\t\t\tsettings.find('.aesop-image-caption > #aesop-generator-attr-caption').on('keyup',function(){\n\n\t\t\t\tvar t = component.find('.aesop-image-component-caption');\n\n\t\t\t\tif ( 0 == t.length ) {\n\n\t\t\t\t\tcomponent.find('img').after( '<p class=\"aesop-image-component-caption\">'+$(this).val()+'</p>' );\n\n\t\t\t\t} else {\n\t\t\t\t\tcomponent.find('.aesop-image-component-caption').text( $(this).val() );\n\t\t\t\t}\n\n\t\t\t})\n\t\t\tsettings.find('.aesop-image-imgwidth > #aesop-generator-attr-imgwidth').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-image-component-image').css('max-width', $(this).val() );\n\t\t\t})\n\t\t\tsettings.find('.aesop-image-align > #aesop-generator-attr-align').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'left' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-component-align-right aesop-component-align-center')\n\n\t\t\t\t} else if ( 'right' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-component-align-left aesop-component-align-center')\n\n\t\t\t\t} else if ( 'center' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-component-align-left aesop-component-align-right')\n\n\t\t\t\t}\n\n\t\t\t\tcomponent.find('.aesop-image-component-image').addClass('aesop-component-align-'+$(this).val()+' ')\n\n\t\t\t})\n\t\t\t\tsettings.find('.aesop-image-captionposition > #aesop-generator-attr-captionposition').on('change',function(){\n\n\t\t\t\t\tvar value = $(this).val();\n\n\t\t\t\t\tif ( 'left' == value ) {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-right aesop-image-component-caption-center')\n\n\t\t\t\t\t} else if ( 'right' == value ) {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-left aesop-image-component-caption-center')\n\n\t\t\t\t\t} else if ( 'center' == value ) {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-left aesop-image-component-caption-right')\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcomponent.find('.lasso-image-component-image').addClass('lasso-image-component-caption-'+value+' ');\n\t\t\t\t});\n\t\t\t\tsettings.find('.aesop-image-offset > #aesop-generator-attr-offset').on('keyup',function(){\n\n\t\t\t\t\tvar value = $(this).val();\n\n\t\t\t\t\tif ( component.find('.aesop-image-component-image').hasClass('aesop-component-align-left') ) {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').css('margin-left', $(this).val() );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').css('margin-right', $(this).val() );\n\t\t\t\t\t}\n\n\t\t\t\t});\n\n\n\t\t\t// CHARACTER LIVE EDIT ///////////////////\n\t\t\tsettings.find('.aesop-character-name > #aesop-generator-attr-name').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-character-title').text( $(this).val() );\n\t\t\t})\n\t\t\tsettings.find('.aesop-character-caption > #aesop-generator-attr-caption').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-character-cap').text( $(this).val() );\n\t\t\t})\n\t\t\tsettings.find('.aesop-character-align > #aesop-generator-attr-align').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'left' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-right aesop-component-align-center');\n\n\t\t\t\t} else if ( 'center' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-left aesop-component-align-right');\n\n\t\t\t\t}\n\n\t\t\t\tcomponent.addClass('aesop-component-align-'+$(this).val()+' ');\n\n\t\t\t});\n\n\t\t\t// CHAPTER LIVE EDIT ///////////////////\n\t\t\tsettings.find('.aesop-chapter-title > #aesop-generator-attr-title').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-cover-title span').text( $(this).val() );\n\t\t\t})\n\t\t\tsettings.find('.aesop-chapter-subtitle > #aesop-generator-attr-subtitle').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-cover-title small').text( $(this).val() );\n\t\t\t})\n\n\t\t\t// VIDEO LIVE EDITOR /////////////////////\n\t\t\t//settings.find('.lasso-video-src > #aesop-generator-attr-src').live('change blur',function(){\n\t\t\tsettings.find('.aesop-video-src > #aesop-generator-attr-src').on('change blur',function(){\n\n\t\t\t\tval = $(this).val()\n\n\t\t\t\tif ( 'vimeo' == val ) {\n\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//player.vimeo.com/video/'+val+' ')\n\n\t\t\t\t\tinitVideoProvider( settings, component, 'vimeo' );\n\n\t\t\t\t} else if ( 'youtube' == val ) {\n\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//www.youtube.com/embed/'+val+'?rel=0&wmode=transparent')\n\n\t\t\t\t\tinitVideoProvider( settings, component, 'youtube' );\n\t\t\t\t}\n\n\t\t\t});\n\t\t\tsettings.find('.aesop-video-id > #aesop-generator-attr-id').on('keyup',function(){\n\t\t\t\tt = $('.aesop-video-src > #aesop-generator-attr-src').val();\n\t\t\t\tval = $(this).val();\n\t\t\t\tif ( 'vimeo' == t ) {\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//player.vimeo.com/video/'+val+' ')\n\t\t\t\t} else if ( 'youtube' == t ) {\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//www.youtube.com/embed/'+val+'?rel=0&wmode=transparent')\n\t\t\t\t}\n\t\t\t});\n\t\t\tsettings.find('.aesop-video-width > #aesop-generator-attr-width').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-video-container').css('max-width', $(this).val() );\n\t\t\t});\n\n\t\t\t// CONTENT COMPONENT LIVE EDIT /////\n\t\t\t//settings.find('.lasso-content-background > #aesop-generator-attr-background').live('change',function(){\n\t\t\tsettings.find('.lasso-content-background > #aesop-generator-attr-background').on('change',function(){\n\t\t\t  \tcomponent.find('.aesop-content-comp-wrap').css({'background-color': $(this).val()});\n\t\t\t});\n\t\t\t\t//settings.find('.lasso-content-color > #aesop-generator-attr-color').live('change',function(){\n\t\t\t\tsettings.find('.aesop-content-color > #aesop-generator-attr-color').on('change',function(){\n\t\t\t\t  \tcomponent.find('.aesop-content-comp-wrap').css({'color': $(this).val()});\n\t\t\t\t});\n\t\t\t\t//settings.find('.lasso-content-height > #aesop-generator-attr-height').live('keyup',function(){\n\t\t\t\tsettings.find('.aesop-content-height > #aesop-generator-attr-height').on('keyup',function(){\n\n\t\t\t\t\tval = $(this).val()\n\n\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').css({'min-height': $(this).val()});\n\n\t\t\t\t});\n\t\t\t\t//settings.find('.lasso-content-columns > #aesop-generator-attr-columns').live('change',function(){\n\t\t\t\tsettings.find('.aesop-content-columns > #aesop-generator-attr-columns').on('change',function(){\n\n\t\t\t\t\tval = $(this).val()\n\n\t\t\t\t\tif ( '1' == val ) {\n\t\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-2 aesop-content-comp-columns-3 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-1')\n\t\t\t\t\t} else if ( '2' == val ) {\n\t\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-3 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-2')\n\t\t\t\t\t} else if ( '3' == val ) {\n\t\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-2 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-3')\n\t\t\t\t\t} else if ( '4' == val ) {\n\t\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-2 aesop-content-comp-columns-3').addClass('aesop-content-comp-columns-4')\n\t\t\t\t\t}\n\n\n\t\t\t\t});\n\t\t});\n\n\t\t/**\n\t\t*\n\t\t*\tSwap the video player with the correct id\n\t\t*\t@param object the global settings for this component\n\t\t*\t@param object the component we're editing\n\t\t*\t@param type string the type of video (vimeo, youtube)\n\t\t*\t@since 0.9.7\n\t\t*/\n\t\tfunction initVideoProvider( settings, component, type ){\n\n\t\t\t//settings.find('.lasso-video-id > #aesop-generator-attr-id').live('change',function(){\n\t\t\tsettings.find('.lasso-video-id > #aesop-generator-attr-id').on('change',function(){\n\n\t\t\t\tvideo_id = $(this).val()\n\n\t\t\t\tif ( 'vimeo' == type ) {\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//player.vimeo.com/video/'+video_id+' ')\n\t\t\t\t} else if ( 'youtube' == type ) {\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//www.youtube.com/embed/'+video_id+'?rel=0&wmode=transparent')\n\t\t\t\t}\n\n\t\t\t})\n\t\t}\n\n\n\t});\n\n})( jQuery );\n\njQuery(function( $ ) {\n\n\tfunction saveSelection() {\n\t    if (window.getSelection) {\n\t        sel = window.getSelection();\n\t        if (sel.getRangeAt && sel.rangeCount) {\n\t            return sel.getRangeAt(0);\n\t        }\n\t    } else if (document.selection && document.selection.createRange) {\n\t        return document.selection.createRange();\n\t    }\n\t    return null;\n\t}\n\n\tfunction restoreSelection(range) {\n\t    if (range) {\n\t        if (window.getSelection) {\n\t            sel = window.getSelection();\n\t            sel.removeAllRanges();\n\t            sel.addRange(range);\n\t        } else if (document.selection && range.select) {\n\t            range.select();\n\t        }\n\t    } else {\n            if (window.getSelection) {\n    \t        sel = window.getSelection();\n    \t        if (sel.getRangeAt && sel.rangeCount) {\n    \t            window.selRange =  sel.getRangeAt(0);\n    \t        }\n            }\n\t    }\n\t}\n\t\n\t\n\t\n\tlasso_editor.checkSelection = function (saveSel) {\n\t\t/*var saveSel = saveSelection;\n\t\tif (saveSel == undefined) { \n\t\t\tsaveSel =  false;\n\t\t} */\n\t\tif (saveSel == true) {\n\t\t\twindow.selRange = saveSelection();\n\t\t}\n\n\t\tif (!window.selRange || window.selRange.collapsed) {\n\t\t\tswal({\n\t\t\t\t    title:\"\",\n\t\t\t\t\ttext: lasso_editor.strings.selectText,\n\t\t\t\t\tcloseOnConfirm: true\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tvar ifSmallWidth = function(){\n\n\t\treturn 600 <= $(window).width() ? true : false;\n\t}\n\n\tvar dropClass = function() {\n\n\t\treturn \"up\";//ifSmallWidth() ? 'up' : 'down';\n\n\t}\n\t\n\t\n\n\t/////////////\n\t/// DROP UP\n\t/////////////\n\t$(document).on('click', '#lasso-toolbar--components', function(e){\n\n\t\t$(this).toggleClass('toolbar--drop-'+dropClass() );\n        // show and hide the component list \n\t\tvar dropUp \t\t\t= $(this).find('ul');\n\t\tif ($(this).hasClass( 'toolbar--drop-'+dropClass() )) {\n\t\t\t$(dropUp).show();\n\t\t} else {\n\t\t\t$(dropUp).hide();\n\t\t}\n        var components = $(dropUp).find(\"li\").length;\n        if (components<7) {\n            $(dropUp).css('width',''+(components*42+8)+'px');\n            $(dropUp).css('left','-'+((components*42+8)/2-20)+'px');\n        }   \n\t\trestoreSelection(window.selRange);\n\t\t$('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() );\n\t\tif( !lasso_editor.isMobile) {\n\t\t\t// get the height of the list of components\n\t\t\t\n\t\t\tvar\tdropUpHeight \t= $(dropUp).height(),\n\t\t\t\tcaretSpacing  \t= 15; // this is the height of the caret\n\n\t\t\t// and adjust the drop up position as necessary\n\t\t\tif ( true == ifSmallWidth() ) {\n\n\t\t\t\t$(dropUp).css({\n\t\t\t\t\tdropUp: dropUpHeight,\n\t\t\t\t\ttop: -(dropUpHeight + caretSpacing)\n\t\t\t\t});\n\n\t\t\t}\n\t\t} else {\n\t\t\t/*$(dropUp).css({\n\t\t\t\t\tdropUp: dropUpHeight,\n\t\t\t\t\ttop: 40\n\t\t\t\t});*/\n\t\t}\n\n\n\t});\n\t\n\t\n\t\n\t// if we the side component button feature is on\n\tif (lasso_editor.buttonOnEmptyP) {\n\t\tjQuery(document).on('click', '#lasso--content p', function(e){\n\t\t\t//if the user click on a paragraph\n\t\t\tif ($(this).find(\"#lasso-side-comp-button\").length == 0) {\n\t\t\t\tlasso_editor.addComponentButton();\n\t\t\t}\n\t\t});\n\t}\n\t\n\t\n\t\n\tjQuery(document).on('mousedown', '#lasso-side-comp-button', function(){\t\n\t\t// side component button handler\n\t\twindow.selRange = saveSelection();\n\t\t$(this).toggleClass('toolbar--side' );\n        // show and hide the component list \n\t\tvar drop\t\t\t= $('#lasso-side-comp-button #lasso-toolbar--components__list');\n\t\tif (drop.length ==0) {\n\t\t\tdrop \t\t\t= $('#lasso-toolbar--components__list').clone();\n\t\t\t$(this).append(drop);\n\t\t\t\n\t\t}\n\t\t\n\t\tif ($(this).hasClass( 'toolbar--side')) {\n\t\t\t$(drop).show();\n\t\t} else {\n\t\t\t$(drop).hide();\n\t\t}\n\t\t$('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() );\n\t\t\n\t\t$(drop).css({\n\t\t\t\tleft: '30px',\n\t\t\t\ttop:'0px'\n\t\t\t});\n            \n        if ($(this).find(\"li\").length<7) {\n            $(this).find(\"ul\").css('column-count',''+$(this).find(\"ul li\").length);\n            $(this).find(\"ul\").css('width','auto');\n        }       \n\t\n\t});\n\n\t/////////////\n\t/// HTML DROP UP\n\t/////////////\n\n\t//$('#lasso-toolbar--html').live('mousedown',function(){\n\t/*jQuery(document).on('mousedown', '#lasso-toolbar--html,#lasso-toolbar--components,#lasso-toolbar--link', function(){\n\t\tif( ! $(this).hasClass('html--drop-'+dropClass() ) ) {\n\t\t\tvar article = document.getElementById(lasso_editor.editor);\n\t\t\tarticle.highlight();\n\t\t\twindow.selRange = saveSelection();\n\t\t\tif( typeof window.selRange === 'undefined' || null == window.selRange ) {\n\t\t\t\twindow.selRange = saveSelection();\n\t\t\t}\n\t\t}\n\t});*/\n\n\t//$('#lasso-toolbar--html__inner').live('focusout',function(){\n\tjQuery(document).on('focusout', '#lasso-toolbar--html__inner', function(){\n\t\trestoreSelection(window.selRange);\n\t});\n\n\t//$('#lasso-toolbar--html__inner').live('focus',function(){\n\tjQuery(document).on('focus', '#lasso-toolbar--html__inner', function(){\n\t\tvar savedSelect = saveSelection();\n\t\tif ( savedSelect && $(savedSelect.commonAncestorContainer).parents('#lasso--content').length != 0 ) {\n\t\t\twindow.selRange = saveSelection();\n\t\t}\n\t});\n\n\t$(document).on('click', '#lasso-toolbar--html', function(e){\n\n\t\t$(this).toggleClass('html--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--components').removeClass('toolbar--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() );\n\n\t\t// prevent dropup from closing\n\t\t//$('#lasso-toolbar--html__wrap').live('click',function(){\n\t\tjQuery(document).on('click', '#lasso-toolbar--html__wrap', function(){\n\t\t\treturn false;\n\t\t});\n\n\t\t$(this).find('#lasso-toolbar--html__inner').focus();\n\n\t});\n\n\t//$('.lasso-toolbar--html__cancel').live('click',function(){\n\tjQuery(document).on('click', '.lasso-toolbar--html__cancel', function(){\n\n\t\t$(this).closest('li').removeClass('html--drop-'+dropClass() );\n\n\t});\n\n\t//////////////////\n\t// HTML FORMATTING IN HTML DROP UP MENU\n\t//////////////////\n\tvar htmlItemInsert = function(markup){\n\n\t\treturn $('#lasso-toolbar--html__inner').text(markup);\n\n\t}\n\t//$('#lasso-html--h2').live('click',function(e){\n\tjQuery(document).on('click', '#lasso-html--h2', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert('<h2>H2 Heading</h2>');\n\t});\n\t//$('#lasso-html--h3').live('click',function(e){\n\tjQuery(document).on('click', '#lasso-html--h3', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert('<h3>H3 Heading</h3>');\n\t});\n\t//$('#lasso-html--ul').live('click',function(e){\n\tjQuery(document).on('click', '#lasso-html--ul', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert('<ul><li>Item</li></ul>');\n\t});\n\t//$('#lasso-html--ol').live('click',function(e){\n\tjQuery(document).on('click', '#lasso-html--ol', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert('<ol><li>Item</li></ol>');\n\t});\n\tjQuery(document).on('click', '#lasso-html--table', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert(lasso_editor.tableCode);//'<table><tr><th>Cell 1</th><th>Cell 2</th></tr><tr><td>Cell 3</td><td>Cell 4</td></tr></table>');\n\t});\n\n\t////////////\n\t/// LINK DROP UIP\n\t////////////\n\t//$('#lasso-toolbar--link').live('mousedown',function(){\n\tjQuery(document).on('mousedown', '#lasso-toolbar--link', function(){\n\t\t$('#lasso-toolbar--components').removeClass('toolbar--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() );\n\t});\n\n\t//$('#lasso-toolbar--link__inner').live('focusout',function(){\n\tjQuery(document).on('focusout', '#lasso-toolbar--link__inner', function(){\n\t\trestoreSelection(window.selRange);\n\t});\n\n\t//$('#lasso-toolbar--link__inner').live('focus',function(){\n\tjQuery(document).on('focus', '#lasso-toolbar--link__inner', function(){\n\t\tvar savedSelect = saveSelection();\n\t\tif ( savedSelect && $(savedSelect.commonAncestorContainer).parents('#lasso--content').length != 0 ) {\n\t\t\twindow.selRange = saveSelection();\n\t\t}\n\t});\n\n\t$(document).on('click', '#lasso-toolbar--link', function(e){\n\n\t\t // exit if nothing is selected\n\t\tif (!lasso_editor.checkSelection()) return false;\n\n\t\t$(this).toggleClass('link--drop-'+dropClass());\n\t\t\n\n\t\t$('#aesop-toolbar--link_newtab').unbind('mousedown').mousedown(function() {\n\t\t\t$(this).prop(\"checked\", !$(this).prop(\"checked\"));\n\t\t\treturn;\n\t\t});\n\n\t\t// prevent dropup from closing\n\t\tjQuery(document).on('click', '#lasso-toolbar--link__wrap', function(){\n\t\t\treturn false;\n\t\t});\n\n\t\t$(this).find('#lasso-toolbar--link__inner').focus();\n        if (window.selRange.startContainer.parentNode.tagName == 'A') {\n            $('#lasso-toolbar--link__inner').text(window.selRange.startContainer.parentNode.href);\n        }\n\t});\n\n\t// RESTORING LINK SELECTION\n\t//$('.lasso-editing .lasso-link').live('click',function(e){\n\tjQuery(document).on('click', '.lasso-editing .lasso-link', function(e){\n\n\t\te.preventDefault();\n\n\t\t// prevent dropup from closing\n\t\t//$('#lasso-toolbar--link__wrap').live('click',function(){\n\t\tjQuery(document).on('click', '#lasso-toolbar--link__wrap', function(){\n\t\t\treturn false;\n\t\t});\n\n\t\tvar link = $(this).attr('href');\n\n\t\t$('#lasso-toolbar--link').addClass('link--drop-'+dropClass());\n\t\t$('#lasso-toolbar--link__inner').text(link);\n\t});\n\n\t/////////////\n\t/// DELETING\n\t/////////////\n\t//$('.lasso-delete').live('click',function(e) {\n\tjQuery(document).on('click', '.lasso-delete', function(e){\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\tswal({\n\t\t\ttitle: \"Delete this component?\",\n\t\t\ttype: \"warning\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: \"Yes, delete it!\",\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\t// remove component\n\t\t\t$this.closest('.aesop-component').remove();\n\n\t\t\t// remove wp image if its a wp image\n\t\t\t$this.closest('.lasso-component').remove();\n            \n            if ($this.parent().parent().hasClass('wp-block-image')) {\n                //$this.closest('.wp-block-image').remove();\n                $this.parent().parent().remove();\n            }\n\n\t\t});\n\n\t});\n\n\t/////////////\n\t/// CLONING\n\t/////////////\n\t//$('.lasso-clone').live('click',function(e) {\n\tjQuery(document).on('click', '.lasso-clone', function(e){\n\n\t\t// sore reference to this\n\t\tvar $this = $(this);\n\n\t\te.preventDefault();\n\n\t\t$this.closest('.aesop-component').clone().insertAfter( $(this).parent().parent() ).hide().fadeIn()\n\t\t$this.closest('.lasso-component').clone().insertAfter( $(this).parent().parent() ).hide().fadeIn()\n\n\t});\n\n});\njQuery(document).ready(function($){\n\n\tvar ajaxurl \t=  lasso_editor.ajaxurl,\n\t\tsave    \t=  $('.lasso--controls__right a'),\n\t\teditor \t\t=  lasso_editor.editor,\n\t\tpostid \t\t=  lasso_editor.postid,\n\t\toldHtml \t=  $('#'+editor).html(),\n\t\twarnNoSave \t=  'You have unsaved changes!';\n\t\t\n\t// Set to true when we want to reload the current page without a warning message\n\tnoWarningReload = false;\n\n\t///////////////////////\n\t// 1. IF UNSAVED CHANGES STORE IN LOCAL STORAGE\n\t// @todo - need to account for component on the page this only accounts for text\n\t///////////////////////\n\t//$('#'+editor).live('change',function(){\n\tjQuery(document).on('change', '#'+editor, function(){\n\n\t\tvar $this = $(this),\n\t\t\tnewHtml = $this.html();\n\n\t\tif ( oldHtml !== newHtml ) {\n\n\t\t\tlocalStorage.setItem( 'lasso_backup_'+postid , newHtml );\n\t\t}\n\n\t});\n\n\t///////////////////////\n\t// 2. WARN THE USER IF THEY TRY TO NAVIGATE AWAY WITH UNSAVED CHANGES\n\t///////////////////////\n\twindow.onbeforeunload = function () {\n\n\t\tif ( localStorage.getItem( 'lasso_backup_'+postid ) && lasso_editor.userCanEdit ) {\n        \treturn warnNoSave;\n        \t$('#lasso--save').css('opacity',1);\n        }\n    }\n\t\n\t// but also clear the unsaved changes if the user does navigate away\n\twindow.onunload = function () {\n\t\tif ( localStorage.getItem( 'lasso_backup_'+postid ) && lasso_editor.userCanEdit ) {\n        \tlocalStorage.clear();\n        }\n    }\n    \n    /*function process_html(html, do_shortcodify) {\n        \t\n\t\t// take care of twitter widget\n\t\thtml = process_twitter(html);\n\t\t\t\n\t    // remove objects to ignore if they are not removed already\n\t\tif (lasso_editor.showIgnoredItems ) {\n\t\t\tvar $temp = $('<div></div>').html( html );\n\t\t\t$temp.find(lasso_editor.objectsNoSave).remove();\n\t\t\t$temp.find(lasso_editor.supportedNoSave).remove();\n\t\t\thtml = $temp.html();\n\t\t}\t\n\t\t\n\t\t// remove extra classes\n\t\t{\n\t\t\tvar $temp = $('<div></div>').html( html );\n\t\t\t$temp.find(\"a\").removeClass(\"lasso-link\");\n\t\t\t$temp.find(\"span\").removeClass(\"lasso-span\");\n\t\t\t$temp.find(\"h2\").removeClass(\"lasso-h2\");\n\t\t\t$temp.find(\"h3\").removeClass(\"lasso-h3\");\n\t\t\t$temp.find(\".lasso-noclass\").removeClass(\"lasso-noclass\");\n\t\t\t$temp.find(\".lasso-undeletable\").removeClass(\"lasso-undeletable\");\n\t\t\t$temp.find(\".lasso-component--controls, .aesop-events-edit\").remove();\n\t\t\t\n\t\t\t$temp.find('*[class=\"\"]').removeAttr('class');\n\t\t\t\n\t\t\thtml = $temp.html();\n\t\t}\n\t\t\n\t\t// remove all contenteditable attr\n\t\thtml = removeEditable(html);\n\t\t\n\t\t// if custom fields\n\t\tif (lasso_editor.customFields) {\n\t\t\tsaveCustomFields(html);\n\t\t}\n\t\t\n\t\t// shortcode ultimate\n\t\thtml = shortcodify_su(html);\n\t\t\n\t\t// shortcode aesop\n\t\thtml = do_shortcodify ? shortcodify(html) : html;\n\t\t\n\t\t\n\t\t\n\t\t// restore other shortcodes to the original shortcodes\n\t\thtml = replace_rendered_shortcodes( html );\n\n\t\t// avia editor\n\t\tif (lasso_editor.aviaEditor) {\n\t\t\thtml = shortcodify_avia(html);\n\t\t}\n        \n        // WordPress Block\n        if (lasso_editor.hasGutenberg) {\n            html = process_gutenberg(html);\n        }\n        \n        // if multi page\n        if (lasso_editor.multipages != \"-1\") {\n            var res = lasso_editor.post_content.split(\"<!--nextpage-->\");\n            var html2 = \"\";\n            res[parseInt(lasso_editor.multipages)] = html;\n            html = res.join(\"<!--nextpage-->\");\n        }\n        \n        // any user supplied filters\n\t\n\t\tif (lasso_editor.filterArray) {\n\t\t\t$(lasso_editor.filterArray).each(function(key, val){\n\t\t\t\thtml = val(html );\n\t\t\t});\n\t\t}\n        \n        return html\n    }*/\n\n\t///////////////////////\n\t// 3. SAVE OR PUBLISH OBJECT\n\t///////////////////////\n\t//$('.lasso--controls__right a:not(#lasso--exit)').live('click',function(e) {\n\t//jQuery(document).on('click', '.lasso--controls__right a:not(#lasso--exit)', function(e){\n\t//jQuery('.lasso--controls__right a:not(#lasso--exit)').on('click', function(e){\n\tjQuery(document).on('click','#lasso--save, #lasso--publish', function(e){\n\n\t\tvar warnNoSave = null;\n\n\t\te.preventDefault();\n\n\t\t// sore reference to this\n\t\tvar $this = $(this);\n\n\t\t// unwrap wp images\n\t\t/*$(\".lasso--wpimg__wrap\").each(function(){\n\n\t\t\t//if ( !$(this).hasClass('wp-caption') ) {\n\t\t\t//\t$(this).children().unwrap()\n\t\t\t//}\n\n\t\t\t$('.lasso-component--controls').remove();\n\t\t});\n\n\t\t// unwrap custom components\n\t\t$('.lasso-component').each(function(){\n\t\t\t$('.lasso-component--controls').remove();\n\t\t});*/\n\n\t\t// unwrap map from hits drag holder\n\t\t$('#lasso--map-form').each(function(){\n\n\t\t\tvar $this = $(this)\n\n\t\t\t$this.find('.lasso-component--controls, .lasso--map-form__footer ').remove()\n\n\t\t\t$this.children().unwrap()\n\t\t});\n\n\t\t// if tehre are any scrollnav sections we need to break them open so the editor doesnt save the html\n\t\t$('.scroll-nav__section').each(function(){\n\t\t\t$(this).children().unwrap();\n\t\t})\n\n\t\t// remove any notices\n\t\t$('#lasso--notice').remove();\n        \n        //remove any comp buttons\n        $('#lasso-side-comp-button').remove();\n\t\t\n\t\t$('.lasso--text-popup').remove();\n        \n        \n        \t\t// let user know someting is happening on click\n\t\t$(this).addClass('being-saved');\n\n\t\t// get the html from our div\n\t\tvar html = $('#'+editor).html(),\n\t\t\tpostid = lasso_editor.postid;\n\t\tif (!html) return;\n        \n        html =  process_html(html, $this.hasClass('shortcodify-enabled'));\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// gather the data\n\t\tvar data      = {\n\t\t\taction:    \t($this.hasClass('lasso-publish-post') && lasso_editor.can_publish) ? 'process_save_publish-content' : 'process_save_content',\n\t\t\tauthor:  \tlasso_editor.author,\n\t\t\tcontent: \thtml,\n\t\t\tpost_id:   \tpostid,\n\t\t\tnonce:     \tlasso_editor.nonce\n\t\t};\n\t\t\n\t\t\n\n\t\t// intercept if publish to confirm\n\t\tif ( $this.hasClass('lasso-publish-post') ) {\t\n\t\t\tif (lasso_editor.publishHandler) {\n\t\t\t\t// custom publish handler\n\t\t\t\tlasso_editor.publishHandler(data);\n\t\t\t} else {\n\t\t\t\tswal({\n\t\t\t\t\ttitle: lasso_editor.strings.publishPost,\n\t\t\t\t\ttype: \"info\",\n\t\t\t\t\ttext: false,\n\t\t\t\t\tshowCancelButton: true,\n\t\t\t\t\tconfirmButtonColor: \"#5bc0de\",\n\t\t\t\t\tconfirmButtonText: lasso_editor.strings.publishYes,\n\t\t\t\t\tcloseOnConfirm: true\n\t\t\t\t},\n\t\t\t\tfunction(){\n\t\t\t\t\trunSavePublish(true)\n\n\t\t\t\t});\n\t\t\t\t\n\t\t\t}\n\n\t\t} else {\n\n\t\t\trunSavePublish(false)\n\n\t\t}\n        \n        function process_html(html, do_shortcodify) {\n        \t\n            // take care of twitter widget\n            html = process_twitter(html);\n                \n            // remove objects to ignore if they are not removed already\n            if (lasso_editor.showIgnoredItems ) {\n                var $temp = $('<div></div>').html( html );\n                $temp.find(lasso_editor.objectsNoSave).remove();\n                $temp.find(lasso_editor.supportedNoSave).remove();\n                html = $temp.html();\n            }\t\n            \n            // remove extra classes\n            {\n                var $temp = $('<div></div>').html( html );\n                $temp.find(\"a\").removeClass(\"lasso-link\");\n                $temp.find(\"span\").removeClass(\"lasso-span\");\n                $temp.find(\"h2\").removeClass(\"lasso-h2\");\n                $temp.find(\"h3\").removeClass(\"lasso-h3\");\n                $temp.find(\".lasso-noclass\").removeClass(\"lasso-noclass\");\n                $temp.find(\".editus-firstp\").removeClass(\"editus-firstp\");\n                $temp.find(\".lasso-undeletable\").removeClass(\"lasso-undeletable\");\n                $temp.find(\".lasso-component--controls, .aesop-events-edit\").remove();\n                \n                $temp.find('*[class=\"\"]').removeAttr('class');\n                //process <!--more-->\n                $temp.find(\"span#more-\"+lasso_editor.postid).replaceWith( \"<!--more-->\" );\n                \n                html = $temp.html();\n            }\n            \n            // remove all contenteditable attr\n            html = removeEditable(html);\n            \n            // if custom fields\n            if (lasso_editor.customFields) {\n                saveCustomFields(html);\n            }\n            \n            // WordPress Block\n            if (lasso_editor.hasGutenberg) {\n\t\t\t\tconst reg = /<p[^>]*><!--/;\n\t\t\t\thtml = html.replace(reg,\"<!--\").replace(\"--></p>\",\"-->\");\n                html = process_gutenberg(html);\n            }\n\t\t\t\n\t\t\t//shortcodes\n\t\t\t{\n                // shortcode ultimate\n                //html = shortcodify_su(html);\n                \n                // restore other shortcodes to the original shortcodes\n                html = replace_rendered_shortcodes( html );\n                \n                // shortcode aesop\n                html = do_shortcodify ? shortcodify(html) : html;\t\n\n                // avia editor\n                if (lasso_editor.aviaEditor) {\n                    html = shortcodify_avia(html);\n                }\n            }\n            \n            // if multi page\n            if (lasso_editor.multipages != \"-1\") {\n                var res = lasso_editor.post_content.split(\"<!--nextpage-->\");\n                var html2 = \"\";\n                res[parseInt(lasso_editor.multipages)] = html;\n                html = res.join(\"<!--nextpage-->\");\n            }\n            \n            // any user supplied filters\n        \n            if (lasso_editor.filterArray) {\n                $(lasso_editor.filterArray).each(function(key, val){\n                    html = val(html );\n                });\n            }\n            \n            return html\n        }\n\n\t\t\n\t\tfunction removeComment(content) {\n\t\t\treturn content.replace(/<!--[\\s\\S]*?-->/g, \"\");\n\t\t}\n\t\t\n\t\tfunction removeEditable(content) \n\t\t{\t\n\t\t\treturn content.replace(/contenteditable=\"(false|true)\"/g, \"\");\n\t\t}\n\t\t\n\t\t// gather the custom field data and save to lasso_editor.cftosave\n\n\t\tfunction saveCustomFields(content) {\n\t\t\tvar data ={};\n\t\t\tvar customFields = lasso_editor.customFields;\n\t\t\tfor (var key in customFields) {\n\t\t\t\tvar selector ='';\n\t\t\t\tvar html = false;\n\t\t\t\tvar isimgurl = false;\n\t\t\t\tif (typeof(lasso_editor.customFields[key]) == 'object') {\n\t\t\t\t\tselector = customFields[key]['selector'];\n\t\t\t\t\thtml = customFields[key]['html'];\n\t\t\t\t\tisimgurl = customFields[key]['imgurl'];\n\t\t\t\t} else {\n\t\t\t\t\tselector =customFields[key];\n\t\t\t\t}\n\t\t\t\tvar arr = $(document).find(selector);\n\t\t\t\tif (arr.length) {\n\t\t\t\t\tif (html) {\n\t\t\t\t\t\tdata[key] = arr[0].innerHTML.replace(/[\\n\\r]/g, '');;\n\t\t\t\t\t} else if (isimgurl) {\n\t\t\t\t\t\tdata[key] = $(arr[0]).attr('src');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdata[key] = arr[0].innerText;//.replace(/[\\n\\r]/g, '');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tlasso_editor.cftosave = data;\n\t\t}\n\n\t\t/**\n\t\t \t* Turn content html into shortcodes\n\t\t \t* @param  {[type]} content  [description]\n\t\t \t* @param  {[type]} selector [description]\n\t\t \t* @return {[type]}          [description]\n\t\t*/\n\t\tfunction shortcodify(content,selector){\n\n\t\t\t// Convert the html into a series of jQuery objects\n\t\t\tvar j = $.parseHTML(content);\n\t\t\tvar processed = '';\n\t\t\tif (j == null) {\n\t\t\t\treturn content;\n\t\t\t}\n\n\t\t\t// Iterate through the array of dom objects\n\t\t\tfor (var i = 0; i < j.length; i++) {\n\n\t    \t\tvar component = $(j[i]);\n\n\t    \t\t// If it's not a component, move along\n\t    \t\tif ( !component.hasClass('aesop-component') ) {\n\t\t\t\t\t\n\t\t\t\t\tif(component.find('.aesop-component').length !== 0) {\n\t\t\t\t\t\t// if there is an aesop component in a child, recursively process it\n\t\t\t\t\t\tvar comp_content = component.html();\n\t\t\t\t\t\tcomp_content = shortcodify(comp_content);\n\t\t\t\t\t\tcomponent.html(comp_content);\n\t\t\t\t\t\tprocessed += component.clone().wrap('<p>').parent().html();;\n\t\t\t\t\t} else   \t\t\t// Let's test what kind of object it is\n                    if ( component.context && component.context.nodeType == 3 ) {\n\t    \t\t\t\t// Text only object without dom\n\t    \t\t\t\tprocessed += j[i].data;\n\t    \t\t\t} else if ( (component.context && component.context.nodeType == 8)  || j[i].nodeType==8) {\n\t    \t\t\t\tprocessed += '<!--' + j[i].data + '-->';\n\t    \t\t\t} else {\n\t    \t\t\t\t// DOM object\n                        if (j[i].outerHTML) {\n                            processed += j[i].outerHTML;\n                        } else if (j[i].data){\n                            processed += j[i].data;\n                        }\n\t    \t\t\t}\n\t    \t\t\tcontinue;\n\t    \t\t}\n\n\t    \t\tvar data = component.data();\n\t    \t\tvar params = '';\n\n\t    \t\t// It's a component, let's check to make sure it's defined properly\n\t\t\t\tif ( data.hasOwnProperty('componentType') ) {\n                    if (data.componentType ==\"wpimg\") \n                        continue;\n\n\t\t\t\t\tfor ( var index in data ) {\n\n\t\t\t\t\t\t// Don't accept componentType as a param\n\t\t\t\t\t\tif ( !data.hasOwnProperty(index) || index == 'componentType' ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Build the params string out of the data attributes\n\t\t\t\t\t\tparams += \" \" + index + '=\"' + data[index] + '\"';\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar sc = '[aesop_' + data.componentType + params + ']';\n\n\t\t\t\t\t// Let's check to see if it's a \"full\" shortcode\n\t\t\t\t\tvar inner = component.find('.aesop-component-content-data');\n\n\t\t\t\t\tif ( inner.length != 0 ) {\n\t\t\t\t\t\tsc += inner[0].innerHTML + \"[/aesop_\" + data.componentType + \"]\";\n\t\t\t\t\t}\n\n\t\t\t\t\tprocessed += sc;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn processed;\n\n\t\t}\n\t\t\n\t\tfunction process_twitter(html)\n\t\t{\n\t\t\t// if twitter widget doesn't exist return\n\t\t\tif (!html) return null;\n\t\t\tif (html.indexOf(\"twitterwidget\") ==-1) return html;\n\t\t\tvar t = $('#'+editor).clone();\n\t\t\tvar t1 = t.find('twitterwidget');\n\t\t\tvar t2 = $('#'+editor).find('twitterwidget');\n\t\t\tvar i;\n\t\t\tfor (i = 0; i<t1.length; i++) {\n\t\t\t\tvar t5 = $('<div></div>').html(t2[i].shadowRoot.innerHTML).find('.EmbeddedTweet').data('click-to-open-target');\n\t\t\t\t$(t1[i]).replaceWith(t5);\n\t\t\t}\n\t\t\t\n\t\t\tvar html2 = t.html();\n\t\t\treturn html2;\n\t\t}\n\t\t\n\t\t//shortcode ultimates\n\t\tfunction shortcodify_su(content,selector){\n\n\t\t\t// Convert the html into a series of jQuery objects\n\t\t\tvar j = $.parseHTML(content);\n\t\t\tvar processed = '';\n\n\t\t\t// Iterate through the array of dom objects\n\t\t\tfor (var i = 0; i < j.length; i++) {\n\n\t    \t\tvar component = $(j[i]);\n\n\t    \t\t// If it's not a component, move along\n\t    \t\tif ( !component.hasClass('su-box') &&  !component.hasClass('su-note') && !component.hasClass('su-document') && !component.hasClass('su-spoiler')) {\n\n\t    \t\t\t// Let's test what kind of object it is\n\t    \t\t\tif ( component.context.nodeType == 3 ) {\n\t    \t\t\t\t// Text only object without dom\n\t    \t\t\t\tprocessed += j[i].data;\n\t    \t\t\t} else if ( component.context.nodeType == 8 ) {\n\t    \t\t\t\tprocessed += '<!--' + j[i].data + '-->';\n\t    \t\t\t} else {\n\t    \t\t\t\t// DOM object\n\t    \t\t\t\tprocessed += j[i].outerHTML;\n\t    \t\t\t}\n\t    \t\t\tcontinue;\n\t    \t\t}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\tif ( component.hasClass('su-box')) {\n\t\t\t\t\tvar box_title = component.find('.su-box-title')[0].innerHTML;\n\t\t\t\t\tvar box_content = component.find('.su-box-content')[0].innerHTML;\n\t\t\t\t\tvar box_color = component.find('.su-box-title')[0].style.backgroundColor;\n\t\t\t\t\tvar sc = '[su_box title=\"'+box_title+'\"'+' box_color=\"' +box_color+'\"]' + box_content+'[/su_box]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('su-note')) {\n\t\t\t\t\tvar note_content = component.find('.su-note-inner')[0].innerHTML;\n\t\t\t\t\tnote_content = shortcodify_su(note_content);\n\t\t\t\t\tvar note_color = component.find('.su-note-inner')[0].style.backgroundColor;\n\t\t\t\t\tvar text_color = component.find('.su-note-inner')[0].style.color;\n\t\t\t\t\tvar sc = '[su_note note_color=\"'+ note_color + '\" text_color=\"'+text_color +'\"]' + note_content+'[/su_note]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('su-document')) {\n\t\t\t\t\t\n\t\t\t\t\tvar ifr = component.find('iframe.su-document')[0];\n\t\t\t\t\tvar url = getParameterByName(\"url\",ifr.src);\n\t\t\t\t\tvar width = ifr.width;\n\t\t\t\t\tvar height = ifr.height;\n\t\t\t\t\tvar sc = '[su_document url=\"'+ url + '\" width=\"'+ width +'\" height=\"' + height+'\"]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('su-spoiler')) {\n\t\t\t\t\tvar spoiler_content = component.find('.su-spoiler-content')[0].innerHTML;\n\t\t\t\t\tspoiler_content = shortcodify_su(spoiler_content);\n\t\t\t\t\tvar title = component.find('.su-spoiler-title')[0].textContent;\n\t\t\t\t\t\n\t\t\t\t\tvar sc = '[su_spoiler title=\"'+ title + '\" style=\"fancy\" open=\"no\"]' + spoiler_content+'[/su_spoiler]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t}\t\t\n\n\t\t\t}\n\n\t\t\treturn processed;\n\t\t}\n        \n        function process_gutenberg(content){\n\t\t\t// Convert the html into a series of jQuery objects\n\t\t\tvar k = $.parseHTML(content);\n\t\t\tvar processed = '';\n\t\t\tif (k == null) {\n\t\t\t\treturn content;\n\t\t\t}\n            \n            j =  $('<div>').append($(k).clone());\n            //ul\n            $(j).find(\"ul\").before('<!-- wp:list -->' ).after('<!-- /wp:list -->');\n            $(j).find(\"ol\").before('<!-- wp:list {\"ordered\":true} -->' ).after('<!-- /wp:list -->');\n            \n            \n            // columns\n            $(j).find(\".wp-block-column\").each( function(index ) {\n                var data = {};\n                if ($(this).hasClass('is-vertically-aligned-center')) {\n                    data[\"verticalAlignment\"]= \"center\";\n                }\n                if ($(this).css(\"flex-basis\")!= \"\") {\n                    data[\"width\"] = $(this).css(\"flex-basis\");\n                }\n                blockCode = \"<!-- wp:column \" + JSON.stringify(data) + \" -->\";\n    \n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:column -->\" );\n            });\n\n            $(j).find(\".wp-block-columns\").each( function(index ) {\n                var data = {};\n                if ($(this).hasClass('are-vertically-aligned-center')) {\n                    data[\"verticalAlignment\"]= \"center\";\n                }\n                blockCode = \"<!-- wp:columns \" + JSON.stringify(data) + \" -->\";\n    \n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:columns -->\" );\n            });\n            \n            //paragraph\n            $(j).find(\"p\").each( function(index ) {\n                var data = {};\n                 if ($(this).hasClass('has-text-align-center')) {\n                    data[\"align\"]= \"center\";\n                }\n                \n                blockCode = \"<!-- wp:paragraph \" + JSON.stringify(data) + \" -->\";\n    \n                $(this).before(blockCode).after(\"<!-- /wp:paragraph -->\" );\n            });\n            \n            //gallery\n            $(j).find(\".wp-block-gallery\").each( function(index ) {\n                debugger;\n                var data = {};\n                 if ($(this).hasClass('aligncenter')) {\n                    data[\"align\"]= \"center\";\n                }\n                var classes = $(this).attr('class').split(\" \");\n                for (i = 0; i < classes.length; ++i) {\n                    if (classes[i].indexOf('columns-') == 0) {\n                        data[\"columns\"] = parseInt(classes[i].substr(8));\n                    }\n                } \n                var ids = [];\n                $(this).find(\"img\").each( function(index ) {\n                    ids[index] = $(this).data('id');\n                });\n                data[\"ids\"]= ids;\n                if ($(this).find(\"a\").length ==0) {\n                    data[\"linkTo\"] = \"none\";\n                } else {\n                    data[\"linkTo\"] = \"file\";\n                }\n                blockCode = \"<!-- wp:gallery \" + JSON.stringify(data) + \" -->\";\n    \n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:gallery -->\" );\n            });\n            \n            //heading\n            $(j).find(\"h1\").before('<!-- wp:heading {\"level\":1} -->' );\n            $(j).find(\"h2\").before('<!-- wp:heading {\"level\":2} -->' );\n            $(j).find(\"h3\").before('<!-- wp:heading {\"level\":3} -->' );\n            $(j).find(\"h4\").before('<!-- wp:heading {\"level\":4} -->' );\n            $(j).find(\"h5\").before('<!-- wp:heading {\"level\":5} -->' );\n            $(j).find(\"h1,h2,h3,h4,h5\").after(\"<!-- /wp:heading -->\" );\n            \n            //table\n            $(j).find(\".wp-block-table\").before(\"<!-- wp:table -->\" ).after(\"<!-- /wp:table -->\" );\n            \n            //button\n            $(j).find(\".wp-block-button\").before(\"<!-- wp:button -->\" );\n            $(j).find(\".wp-block-button\").after(\"<!-- /wp:button -->\" );\n            $(j).find(\".wp-block-buttons\").each( function(index ) {\n                var blockCode = \"<!-- wp:buttons \";\n                var data = {};\n                if ($(this).hasClass('is-content-justification-center')) {\n                    data[\"contentJustification\"]= \"center\";\n                }\n                blockCode = blockCode + JSON.stringify(data) + \" -->\";\n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:buttons -->\" );\n            });\n              \n            //group\n            $(j).find(\".wp-block-group\").each( function(index ) {\n                var data = {};\n                if ($(this).hasClass('alignfull')) {\n                    data[\"align\"]= \"full\";\n                }\n                var blockCode = \"<!-- wp:group \" + JSON.stringify(data) + \" -->\";\n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:group -->\" );\n            });\n            \n            // spacer\n            $(j).find(\".wp-block-spacer\").before(\"<!-- wp:spacer -->\" ).after(\"<!-- /wp:spacer -->\" );\n            \n            // separator\n            $(j).find(\".wp-block-separator\").before(\"<!-- wp:separator  -->\" ).after(\"<!-- /wp:separator  -->\" );\n            \n            // image\n\t\t\t$(j).find(\".wp-block-image\").each( function(index ) {\n                $(this).removeAttr('data-component-type');\n                var data = {};\n                if ($(this).find(\"img\").length == 0) {\n                    return;\n                }\n                \n\t\t\t\tvar blockCode = \"<!-- wp:image \";\n\t\t\t\t\n\t\t\t\tvar classes = $(this).find(\"img\").attr('class').split(\" \");\n\t\t\t\t\n\t\t\t\t$(this).removeAttr('width').removeAttr('height').removeAttr('readonly');\n\t\t\t\t$(this).find(\"img\").removeAttr('width').removeAttr('height').removeAttr('srcset').removeAttr('sizes').removeAttr('loading');\n\t\t\t\tvar i;\n                for (i = 0; i < classes.length; ++i) {\n                    if (classes[i].indexOf('wp-image-') == 0) {\n                        data[\"id\"] = parseInt(classes[i].substr(9));\n                    }\n                } \n\t\t\t\tif ($(this).hasClass(\"size-large\") || $(this).find('figure').hasClass(\"size-large\")) {\n\t\t\t\t\tdata[\"sizeSlug\"] = \"large\";\n\t\t\t\t}\n                if ($(this).hasClass(\"size-full\") || $(this).find('figure').hasClass(\"size-full\")) {\n\t\t\t\t\tdata[\"sizeSlug\"] = \"full\";\n\t\t\t\t}\n                 if ($(this).find(\".aligncenter\").length>0) {\n                    data[\"align\"]=\"center\";\n                }\n                if ($(this).hasClass(\"is-style-default\")) {\n\t\t\t\t\tdata[\"className\"] = \"is-style-default\";\n\t\t\t\t}\n                if ($(this).hasClass(\"is-style-rounded\")) {\n\t\t\t\t\tdata[\"className\"] = \"is-style-rounded\";\n\t\t\t\t}\n                if ($(this).find(\".alignright\").length>0) {\n                    data[\"align\"] = \"right\";\n                }\n                if ($(this).find(\".alignleft\").length>0) {\n                    data[\"align\"] = \"left\";\n                }\n         \n                blockCode = blockCode + JSON.stringify(data) + \" -->\";\n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:image -->\" );\n            });\n            \n            // cover\n\t\t\t$(j).find(\".wp-block-cover\").each( function(index ) {\n                $(this).removeAttr('data-component-type');\n\t\t\t\tvar blockCode = \"<!-- wp:cover \";\n                var data = {};\n                \n                if ($(this).find(\"img\").length > 0) {\n\t\t\t\t    data['url'] = $(this).find(\"img\").attr('src');\n                    var classes = $(this).find(\"img\").attr('class').split(\" \");\n                    $(this).removeAttr('width').removeAttr('height');\n                    if ($(this).css(\"min-height\") == \"100vh\") {\n                        data[\"minHeight\"] =100;\n                        data[\"minHeightUnit\"] = \"vh\";\n                    }\n                    $(this).find(\"img\").removeAttr('width').removeAttr('height').removeAttr('srcset').removeAttr('sizes').removeAttr('loading');\n                    var i;\n                    for (i = 0; i < classes.length; ++i) {\n                        if (classes[i] == 'alignfull') {\n                            data['align'] = \"full\";\n                        }\n                        if (classes[i].indexOf('wp-image-') == 0) {\n                            data[\"id\"] = parseInt(classes[i].substr(9));\n                        }\n                        \n                    } \n                } else {\n                    var bg = $(this).css('background-image');\n                    bg = bg.replace('url(','').replace(')','').replace(/\\\"/gi, \"\");\n                    data['url'] = bg;\n                    var classes = $(this).attr('class').split(\" \");\n                    var i;\n                    for (i = 0; i < classes.length; ++i) {\n                        if (classes[i]=='has-parallax') {\n                             data[\"hasParallax\"] = true;\n                        }\n                        else if (classes[i]=='is-repeated') {\n                             data[\"className\"] = \"is-repeated\";\n                        }\n                    } \n                }\n\t\t\t\n                blockCode = blockCode + JSON.stringify(data) + \" -->\";\n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:cover -->\" );\n            });\n            \n            //aesop components\n            $(j).find(\".aesop-component\").each( function(index ) {\n                var d = $(this).data();\n\t\t\t\tif (d['componentType'] == 'timeline_stop') d['componentType'] = 'timeline';\n\n                var blockCode = \"<!-- wp:ase/\"+d['componentType']+\" {\";\n                var index = 0;\n                $.each(d,function(key, value){\n                    if (key=='componentType') return;\n                    if (index>0) blockCode += \",\";\n                    blockCode+= '\"'+key+'\":\"'+value+'\" ';\n                    index++;\n                });\n                blockCode+=\"} /-->\";\n                $(this).before(blockCode);\n                $(this).remove();\n            });\n            \n            var html = $(j).html(); \n            html = html.replace(\" {} -->\",\" -->\");\n            return html;\n        }\n\t\t\n\t\t//shortcode avia layout editor\n\t\tfunction shortcodify_avia(content,selector){\n\t\t\t// Convert the html into a series of jQuery objects\n\t\t\tvar j = $.parseHTML(content);\n\t\t\tvar processed = '';\n\n\t\t\t// Iterate through the array of dom objects\n\t\t\tfor (var i = 0; i < j.length; i++) {\n\n\t    \t\tvar component = $(j[i]);\n\n\t    \t\t// If it's not a component, move along\n\t    \t\tif ( !component.hasClass('av_textblock_section') && !component.hasClass('av_toggle_section') && !component.hasClass('togglecontainer')) {\n\n\t    \t\t\t// Let's test what kind of object it is\n\t    \t\t\tif ( component.context.nodeType == 3 ) {\n\t    \t\t\t\t// Text only object without dom\n\t    \t\t\t\tprocessed += j[i].data;\n\t    \t\t\t} else if ( component.context.nodeType == 8 ) {\n\t    \t\t\t\tprocessed += '<!--' + j[i].data + '-->';\n\t    \t\t\t} else {\n\t    \t\t\t\t// DOM object\n\t    \t\t\t\tprocessed += j[i].outerHTML;\n\t    \t\t\t}\n\t    \t\t\tcontinue;\n\t    \t\t}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\tif ( component.hasClass('av_textblock_section')) {\n\t\t\t\t\tvar box_text = component.find('.avia_textblock')[0].innerHTML;\n\t\t\t\t\tvar sc = '[av_textblock]' + box_text+'[/av_textblock]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('togglecontainer')) {\n\t\t\t\t\t\n\t\t\t\t\tvar content = component[0].innerHTML;\n\t\t\t\t\tvar mode =\"accordion\";\n\t\t\t\t\tcontent = shortcodify_avia(content);\n\t\t\t\t\tif (component[0].hasClass('enable_toggles')) {\n\t\t\t\t\t\tmode = \"toggle\";\n\t\t\t\t\t}\n\t\t\t\t\tvar sc = \"[av_toggle_container mode='\"+mode+\"']\" + content+'[/av_toggle_container]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('av_toggle_section')) {\n\t\t\t\t\tvar toggle_title = component.find('.toggler')[0].innerText;\n\t\t\t\t\tvar toggle_content = component.find('.toggle_content')[0].innerHTML;\n\t\t\t\t\tvar sc = '[av_toggle title=\"'+toggle_title+'\"]' + toggle_content+'[/av_toggle]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn processed;\n\t\t}\n\t\t\n\t\tfunction replace_rendered_shortcodes( content ) {\n\t\t\t// also remove scripts\n\t\t\tcontent = content.replace(/<script.*>.*<\\/script>/g, \" \");\n\t\t\t\n\t\t\tif ( content.indexOf('--EDITUS_OTHER_SHORTCODE_START|' ) == -1) {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t\t\n\t\t\t/*var k = $.parseHTML(content);\n\t\t\tif (k != null) {\n\t\t\t\tj =  $('<div>').append($(k).clone());\n\t\t\t\t\n\t\t\t\t$(j).find('.editus_shortcode').each(function(){\n\t\t\t\t    var oldComment = this.previousElementSibling.innerHTML;\n\t\t\t\t\tvar re = /<!--EDITUS_OTHER_SHORTCODE_START\\|\\[(.*)\\]-->/g.exec(oldComment) ;\n\t\t\t\t\tvar cont = this.dataset.shortcode;\n\t\t\t\t\tif (cont && re && re.size>1) {\n\t\t\t\t\t\tthis.previousElementSibling.innerHTML = oldComment.replace(re[1], cont);\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\tcontent = $(j).html(); \n\t\t\t}*/\n\n\t\t\tvar re = /<!--EDITUS_OTHER_SHORTCODE_START\\|\\[([\\s\\S]*?)\\]-->([\\s\\S]*?)<!--EDITUS_OTHER_SHORTCODE_END-->/g ;\n\t\t\tif (lasso_editor.hasGutenberg) {\n\t\t\t\tcontent = content.replace(re,'<!-- wp:shortcode -->$1<!-- /wp:shortcode -->');\n\t\t\t} else {\n\t\t\t\tcontent = content.replace(re,'$1');\n\t\t\t}\n\t\t\t\n\t\t\treturn content;\n\t\t}\n\t\t\n\t\t// Save post using REST API V2\n\t\tfunction savePublishREST(postid, title, subtitle, content_, type_,status_,forcePublish){\n\t\t\t\n\t\t\tvar data      = {\n\t\t\t\tcontent: \tcontent_,\n\t\t\t\tstatus: status_\n\t\t\t};\n\t\t\tif (lasso_editor.aviaEditor) {\n\t\t\t\tdata['content'] =\"\";\n\t\t\t\tdata['metadata'] = { '_aviaLayoutBuilderCleanData': content_};\n\t\t\t}\n\t\t\t\n\t\t\t//custom fields to save\n\t\t\tif (lasso_editor.cftosave) {\n\t\t\t\tif (!data['metadata']) {\n\t\t\t\t\tdata['metadata']=  lasso_editor.cftosave;\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(data['metadata'], lasso_editor.cftosave);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tvar type;\n\t\t\tif (type_==\"post\") {\n\t\t\t\ttype = \"posts\";\n\t\t\t} else if (type_==\"page\"){\n\t\t\t\ttype = \"pages\";\n\t\t\t} else {\n\t\t\t\ttype = type_;\n\t\t\t}\n\t\t\tif (title.length>0) {\n\t\t\t\tdata['title'] = title;\n\t\t\t}\n\t\t\tif (subtitle.length>0) {\n\t\t\t\tdata['metadata'] = { '_subtitle': subtitle};\n\t\t\t}\n\t\t\t\n\t\t\tif (lasso_editor.disableSavePost == 'on') {\n\t\t\t\tdelete data['content'];\n\t\t\t}\n\t\t\t\n\t\t\t$.ajax({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\turl: lasso_editor.rest_root + 'wp/v2/'+type+'/'+postid,\n\t\t\t\tdata: data,\n\t\t\t\tbeforeSend: function ( xhr ) {\n\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t\t},\n\t\t\t\tsuccess : function( response ) {\n\t\t\t\t\tsaveSuccess();\n                    if (forcePublish) {\n                        var data = {\n                            action: \t\t'editus_publish_post',\n                            postid: \t\tlasso_editor.postid\n                        }\n\n                        $.post( lasso_editor.ajaxurl2, data);\n                    }\n\t\t\t\t},\n\t\t\t\terror : function (xhr, exception) {\n\t\t\t\t\tconsole.log( xhr );\n\t\t\t\t\talert(\"AJAX Error: \"+xhr.responseText );\n\t\t\t\t\t$('#lasso--save').removeClass('being-saved').addClass('lasso--error');\t\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t\n\t\t// code to run when post saving is successful\n\t\tfunction saveSuccess() {\n\t\t\t// change button class to saved\n\t\t\t$('#lasso--save').removeClass('being-saved').addClass('lasso--saved');\n\n\t\t\t// if this is being published then remove the publish button afterwards\n\t\t\tif ( $this.hasClass('lasso-publish-post') ) {\n\t\t\t\t$this.remove();\n\t\t\t}\n\n\t\t\t// wait a bit then remvoe the button class so they can save again\n\t\t\tsetTimeout(function(){\n\t\t\t\t$('#lasso--save').removeClass('lasso--saved');\n\n\t\t\t\tif ( $this.hasClass('lasso-publish-post') ) {\n\t\t\t\t\tlocation.reload()\n\t\t\t\t}\n\n\t\t\t},1200);\n\n\t\t\t// then remove this copy from local stoarge\n\t\t\tlocalStorage.removeItem( 'lasso_backup_'+postid );\n\t\t\tlasso_editor.dirtyByComponent = false;\n\t\t\tarticleMedium.dirty = false;\n\t\t\tif (lasso_editor.saveSuccessHookArray) {\n\t\t\t\t$(lasso_editor.saveSuccessHookArray).each(function(key, val){\n\t\t\t\t\tval();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t\n\n\t\t// make the actual ajax call to save or publish\n\t\tfunction runSavePublish(forcePublish){\n\t\t\tif (lasso_editor.saveusingrest) {\n\t\t\t\t// get the status of the post (published/draft)\n\t\t\t\tvar status_ = $('.lasso--controls__right').data( \"status\" );\n\t\t\t\tvar title=\"\";\n\t\t\t\tif ($(lasso_editor.titleClass).length>0) {\n\t\t\t\t\ttitle = $(lasso_editor.titleClass)[0].innerText;\n\t\t\t\t}\n\t\t\t\tvar subtitle=\"\";\n\t\t\t\tif ($(lasso_editor.subtitleClass).length>0) {\n\t\t\t\t\tsubtitle = $(lasso_editor.subtitleClass)[0].innerText;\n\t\t\t\t}\n\t\t\t\tif (forcePublish) {\n\t\t\t\t\tstatus_ = \"publish\";\t\t\t\t\n\t\t\t\t\tif (!lasso_editor.can_publish) {\n\t\t\t\t\t\tstatus_ = \"pending\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsavePublishREST(lasso_editor.postid, title, subtitle, data.content, $('.lasso--controls__right').data( \"posttype\" ), status_, forcePublish);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\t$.post( ajaxurl, data, function(response) {\n\n\t\t\t\tif( true == response.success ) {\n\t\t\t\t\tsaveSuccess();\n\t\t\t\t} else {\n\t\t\t\t\t$('#lasso--save').removeClass('being-saved').addClass('lasso--error');\n\t\t\t\t}\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t\t$('#lasso--save').removeClass('being-saved').addClass('lasso--error');\t\t\t\t\n\t\t\t});\n\t\t}\n\n\t});\n\t\n\t\n\tjQuery(document).on('click','#lasso--post-delete', function(e){\n\t\te.preventDefault();\n\t\tvar $this = $(this);\n\t\tswal({\n\t\t\ttitle: lasso_editor.strings.deletePost,\n\t\t\ttype: \"error\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: lasso_editor.strings.deleteYes,\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\tvar data = {\n\t\t\t\taction: \t\t'editus_delete_post',\n\t\t\t\tpostid: \t\tlasso_editor.postid,\n\t\t\t\tnonce: \t\t\tlasso_editor.deletePost\n\t\t\t}\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\t//load home page after deleting the post\n\t\t\t\twindow.location.assign(lasso_editor.siteUrl);\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\n\t\t});\n\t});\n});\n\nfunction EditusFormatAJAXErrorMessage(jqXHR, exception) {\n\tif (jqXHR.status === 0) {\n\t\treturn ('AJAX Error: Not connected.\\nPlease verify your network connection.');\n\t} else if (jqXHR.status == 404) {\n\t\treturn ('AJAX Error: The requested page not found. [404]');\n\t} else if (jqXHR.status == 500) {\n\t\treturn ('AJAX Error: Internal Server Error [500].');\n\t} else if (exception === 'parsererror') {\n\t\treturn ('AJAX Error: Requested JSON parse failed.');\n\t} else if (exception === 'timeout') {\n\t\treturn ('AJAX Error: Time out error.');\n\t} else if (exception === 'abort') {\n\t\treturn ('AJAX Error: Ajax request aborted.');\n\t} else {\n\t\treturn ('AJAX Error: Uncaught Error.\\n' + jqXHR.responseText);\n\t}\n}\n\n(function( $ ) {\n\t'use strict';\n\n\t/////////////\n\t// NEW GALLERY CREATE\n\t////////////\n\t//$('#lasso--gallery__create').live('click',function(e){\n\tjQuery(document).on('click','#lasso--gallery__create',function(e){\n\n\t\te.preventDefault();\n\n\t\t$(this).closest('form').addClass('creating-gallery');\n\n\t\t$('.ase-gallery-opts--create-gallery2').fadeIn();\n\t\t$('.ase-gallery-opts--edit-gallery').fadeOut(1);\n\n\t\t$('#ase-gallery-images li').remove();\n\t\t$('#lasso--gallery__create').remove();\n\n\t\t$('.ase-gallery-opts--edit-gallery').text(lasso_editor.strings.addNewGallery);\n\t\t$('.ase-gallery-opts--edit-gallery .lasso-option-desc').text('Select new images to create a gallery with.');\n\n\n\t});\n\n\t/////////////\n\t// NEW GALLERY UPLOAD\n\t////////////\n\n\tvar file_frame;\n\tvar\tgallery = $('#ase-gallery-images');\n\n\t//$(document).on('click', '#lasso--gallery__selectImages', function( e ){\n\tjQuery(document).on('click','#lasso--gallery__selectImages',function( e ){\n\n\t    e.preventDefault();\n\n\t    // If the media frame already exists, reopen it.\n\t    if ( file_frame ) {\n\t      \tfile_frame.open();\n\t      \treturn;\n\t    }\n\n\t    // Create the media frame.\n\t    file_frame = wp.media.frames.file_frame = wp.media({\n\t      \ttitle: lasso_editor.strings.chooseImages,\n\t      \tbutton: {\n\t        \ttext: lasso_editor.strings.addImages,\n\t      \t},\n\t      \tmultiple: true  // Set to true to allow multiple files to be selected\n\t    });\n\n\t    // When an image is selected, run a callback.\n\t    file_frame.on( 'select', function() {\n\n\t      \tvar attachments = file_frame.state().get('selection');\n\n\t\t    if (!attachments) {\n\t\t        return;\n\t\t    }\n\n\t\t    // loop through and insert the new items\n\t\t    attachments.each( function( attachment ) {\n\t\t    \tvar id = attachment.id;\n\t\t    \tvar url = attachment.attributes.sizes.thumbnail.url;\n\t\t    \tase_insert_gallery_item(id, url);\n\t\t    });\n\n\t\t    // insert the new ids from new gallery\n\t\t    var ids = attachments.map( function( attachment ) {\n\n\t\t    \tvar attachment = attachment.toJSON();\n\t\t    \treturn attachment.id;\n\n\t\t    }).join(',');\n\n\t\t    // populate gallery input with ids\n\t\t    $('#ase_gallery_ids').val( ids );\n\n\t\t    // show the save button\n\t      \t$('.has-galleries > #lasso--gallery__save').fadeIn();\n\n\t      \t// remove the select images button\n\t      \t$('#lasso--gallery__selectImages').remove();\n\n\t    });\n\n\t    // Finally, open the modal\n\t    file_frame.open();\n\t});\n\n\t//////////\n\t// NEW GALLERY SWAP\n\t//////////\n\t//$('.lasso-gallery-id #aesop-generator-attr-id').live('change',function(){\n\tjQuery(document).on('change','.aesop-gallery-id #aesop-generator-attr-id',function(){\n\n\t\teditus_gallery_swap($(this).val());\n\t\t\n\t\tvar data2      = {\n\t\t\taction:    \t'process_gallery_get-images',\n\t\t\tpost_id:   \t$(this).val(),\n\t\t\tnonce: \t\tlasso_editor.getGallImgNonce\n\t\t};\n\n\t\t// post ajax response with data\n\t\t$.post( lasso_editor.ajaxurl, data2, function(response) {\n\t\t\t$('#lasso--gallery__images').html( response.data.html );\n\n\t\t\t/////////////\n\t\t\t// CALL SORTABLE ON RECIEVED IMAGES\n\t\t\t/////////////\n\t\t\tvar\tgallery = $('#ase-gallery-images');\n\n\t\t\tgallery.ready(function(){\n\n\t\t\t\tgallery.sortable({\n\t\t\t\t\tcontainment: 'parent',\n\t\t\t\t\tcursor: 'move',\n\t\t\t\t\topacity: 0.8,\n\t\t\t\t\tplaceholder: 'ase-gallery-drop-zone',\n\t\t\t\t\tforcePlaceholderSize:true,\n\t\t\t\t\tupdate: function(){\n\t\t\t\t\t\tvar imageArray = $(this).sortable('toArray');\n\t\t\t\t\t\t$('#ase_gallery_ids').val( imageArray );\n\t\t\t\t\t},\n\t\t\t\t\tcreate: function(){\n\t\t\t\t\t\tvar imageArray = $(this).sortable('toArray');\n\t\t\t\t\t\t$('#ase_gallery_ids').val( imageArray );\n\t\t\t\t\t}\n\t\t\t\t});\n                window.component.find('.lasso-component--settings__trigger').trigger('click');\n\t\t\t});\n\t\t}).fail(function(xhr, err) { \n\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t});\n\t});\n\t\n\tfunction editus_gallery_swap(galleryID){\n\t\tvar data      = {\n\t\t\tcomponentType: 'gallery',\n\t\t\tid:   \tgalleryID\n\t\t};\n\t\twindow.get_aesop_component_ajax(data);\n\t}\n\n\t///////////\n\t// EDIT GALLERY\n\t// the sortsble instat is in settingspanel.js\n\t///////////\n\n\t// deleting gallery items\n\t$(document).on('click', '.ase-gallery-image > i.dashicons-no-alt', function(){\n\t\t$(this).parent().remove();\n\t\tgallery.sortable('refresh');\n\t\tase_encode_gallery_items();\n\t});\n\n\tfunction ase_string_encode(gData){\n\t\treturn encodeURIComponent(JSON.stringify(gData));\n\t}\n\n\tfunction ase_string_decode(gData){\n\t\treturn JSON.parse(decodeURIComponent(gData));\n\t}\n\n\tfunction ase_encode_gallery_items(){\n\t\tgallery = $('#lasso--gallery__images #ase-gallery-images');\n\t\tif (gallery.length) {\n\t\t   var imageArray = gallery.sortable('toArray');\n\t  \t   $('#ase_gallery_ids').val( imageArray );\n\t\t}\n\t}\n\n\t// inserting gallery items\n\tfunction ase_insert_gallery_item(id, url){\n\n\t\tvar item_html = \"<li id='\" + id + \"' class='ase-gallery-image'><i class='dashicons dashicons-no-alt'></i><i title='Edit Image Caption' class='dashicons dashicons-edit'></i><img src='\" + url + \"'></li>\";\n\t\t$('#ase-gallery-images').append( item_html );\n\t\tgallery.sortable('refresh');\n\t\tase_encode_gallery_items();\n\t}\n\n\t// adding additiona images to existing gallery\n\n\tvar clicked_button = false;\n\n\t$(document).on('click', '#ase-gallery-add-image', function (event) {\n    \tevent.preventDefault();\n    \tvar selected_img;\n    \tclicked_button = $(this);\n\n    \tif(wp.media.frames.ase_frame) {\n\t\t\twp.media.frames.ase_frame.open();\n\t\t\treturn;\n\t\t}\n\n    \twp.media.frames.ase_frame = wp.media({\n\t\t\ttitle: lasso_editor.strings.selectGallery,\n\t\t\tmultiple: true,\n\t\t\tlibrary: {\n\t\t\t    type: 'image'\n\t\t\t},\n\t\t\tbutton: {\n\t\t\t    text: lasso_editor.strings.useSelectedImages\n\t\t\t}\n\t\t});\n\n    \tvar ase_media_set_image = function() {\n\t\t\tvar selection = wp.media.frames.ase_frame.state().get('selection');\n\n\t\t\tif (!selection) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tselection.each(function(attachment) {\n\t\t\t\tvar id = attachment.id;\n\t\t\t\tvar url = attachment.attributes.sizes.thumbnail.url;\n\t\t\t\tase_insert_gallery_item(id, url);\n\t\t\t});\n\n\t\t};\n\n    \twp.media.frames.ase_frame.on('select', ase_media_set_image);\n\t\twp.media.frames.ase_frame.open();\n\t});\n\n\n\t// editing a single image\n\tfunction ase_edit_gallery_item(id, url, editable){\n\t\tvar item_html = \"<li id='\" + id + \"' class='ase-gallery-image'><i class='dashicons dashicons-no-alt'></i><i title='Edit Image Caption' class='dashicons dashicons-edit'></i><img src='\" + url + \"'></li>\";\n\t\t$(editable).replaceWith( item_html );\n\t\tgallery.sortable('refresh');\n\t\tase_encode_gallery_items();\n\t}\n\n\t// edit single image\n\tvar ase_media_edit_init = function()  {\n\n\t    var clicked_button;\n\n\t    $(document).on('click', '.ase-gallery-image > i.dashicons-edit', function(event){\n\t\t\tevent.preventDefault();\n\t\t\tvar selected_img;\n\t\t\tclicked_button = $(this);\n\n\t\t\tif(wp.media.frames.ase_edit_frame) {\n\t\t\t\twp.media.frames.ase_edit_frame.open();\n\t\t\t\treturn;\n\t\t\t}\n\n            wp.revisions\n\n\t\t\twp.media.frames.ase_edit_frame = wp.media({\n\t\t\t\ttitle: lasso_editor.strings.editImage,\n\t\t\t\tmultiple: false,\n\t\t\t\tlibrary: {\n\t\t\t\t  \ttype: 'image'\n\t\t\t\t},\n\t\t\t\tbutton: {\n\t\t\t\t  \ttext: lasso_editor.strings.updateSelectedImg\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar ase_media_edit_image = function() {\n\t\t\t    var selection = wp.media.frames.ase_edit_frame.state().get('selection');\n\n\t\t\t    if (!selection) {\n\t\t        \treturn;\n\t\t\t    }\n\n\t\t\t    // iterate through selected elements\n\t\t\t    selection.each(function(attachment) {\n\t\t\t    \tvar id = attachment.id;\n\t\t\t    \tvar url = attachment.attributes.sizes.thumbnail.url;\n\t\t\t    \tase_edit_gallery_item(id, url, clicked_button.parent());\n\t\t\t    });\n\n\t\t\t};\n\n\t\t\t// image selection event\n\t\t\twp.media.frames.ase_edit_frame.on('select', ase_media_edit_image);\n\t\t\twp.media.frames.ase_edit_frame.on('open',function(){\n\t\t\t\t var selection = wp.media.frames.ase_edit_frame.state().get('selection');\n\t\t\t\tvar attachment = wp.media.attachment( clicked_button.parent().attr('id') );\n\t\t\t\tattachment.fetch();\n\t\t\t\tselection.add( attachment ? [ attachment ] : [] );\n\t\t\t});\n\t\t\twp.media.frames.ase_edit_frame.open();\n\t    });\n\n\t};\n\n\t//ase_media_init('#ase-gallery-add-image', 'i');\n\tase_media_edit_init();\n\tase_encode_gallery_items();\n\n})( jQuery );\n\n(function( $ ) {\n\n\t$(document).ready(function($){\n\n\t\t// this function is repeated on settings-panel.js\n\t\tvar value_check = function( value ){\n\n\t\t\tif ( 'grid' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeIn();\n\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t}\n\n\t\t\tif ( 'thumbnail' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeIn();\n\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t}\n\n\t\t\tif ( 'photoset' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeIn();\n\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t}\n\t\t\t\t\t\t\n\t\t\tif ( 'hero' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeIn();\n\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t}\n\t\t}\n\n\t\t$('.ase-gallery-type-radio').each(function(){\n\n\t\t\tif ( $(this).is(':checked') ) {\n\t\t\t\t$(this).parent().addClass('selected');\n\t\t\t\tvar value = $(this).val();\n\t  \t\t\tvalue_check(value);\n\n\t\t\t}\n\n\t\t});\n\n\t\t//$('.ase-gallery-layout-label').live('click',function(){\n\t\tjQuery(document).on('click','.ase-gallery-layout-label', function(){\n\t\t\t$('.ase-gallery-layout-label').removeClass('selected');\n\t\t\t$(this).addClass('selected');\n\t\t\tvar value = $(this).find('input').val();\n\t\t\tvalue_check(value);\n\n\t\t\t// add the type to a hidden field\n\t\t\t$('#ase_gallery_type').val( value )\n\t\t});\n\t})\n\n})( jQuery );\n(function( $ ) {\n\n\tvar form;\n\n\t//$('#lasso--map-form').live('submit', function(e) {\n\tjQuery(document).on('submit','#lasso--map-form',function(e) {\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\t$(this).find('input[type=\"submit\"]').val('Saving...').addClass('being-saved');\n\n\t\tvar data = $this.serialize();\n\n\t\t/////////////\n\t\t//\tDO TEH SAVE\n\t\t/////////////\n\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\tif ( true == response.success ) {\n\n\t\t\t\t$this.find('input[type=\"submit\"]').val('Saved');\n\t\t\t\t$this.removeClass('being-saved').addClass('lasso--saved');\n\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t$this.find('input[type=\"submit\"]').val('Save Locations').removeClass('lasso-saved');\n\t\t\t\t},1200);\n\n\t\t\t} else {\n\t\t\t\t$this.removeClass('being-saved').addClass('lasso--error');\n\t\t\t}\n\n\n\t\t});\n\n\t});\n\n})( jQuery );\n(function( $ ) {\n\t'use strict';\n\n\t//$( '#lasso--featImgSave a' ).live('click', function(e) {\n\tjQuery(document).on('click', '#lasso--featImgSave a', function(e){\n\t\te.preventDefault();\n\n\t\tvar $this \t\t= $(this)\n\t\t,\tsaveStatus = $('#lasso--save-status')\n\n\t\tvar data = {\n\t\t\taction: 'editus_featured_img',\n\t\t\tpostid: lasso_editor.postid,\n\t\t\timage_id: $this.data('featimg-id'),\n\t\t\tnonce: \tlasso_editor.featImgNonce\n\t\t}\n\n\t\tsaveStatus.removeClass('not-visible').addClass('visible lasso--animate__spin');\n\n\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n\t\t\tif ( response ) {\n\t\t\t\tconsole.log('response')\n\t\t\t\t$('#lasso--featImgSave').css('opacity',0);\n\t\t\t\t//setTimeout(function(){\n\t\t\t\t//\tsaveStatus.removeClass('lasso--animate__spin lasso-icon-check').addClass('lasso-icon-spinner6 not-visible')\n\t\t\t\t//},500);\n\t\t\t}\n\t\t\tsaveStatus.removeClass('lasso--animate__spin lasso-icon-spinner6').addClass('lasso-icon-check');\n\n\t\t}).fail(function(xhr, err) { \n\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\tsaveStatus.removeClass('lasso--animate__spin lasso-icon-spinner6').addClass('lasso-icon-check');\n\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t});\n\n\t});\n\n\t/////////////\n\t// FILE UPLOAD\n\t////////////\n\tvar file_frame;\n\tvar className;\n\n\t$(document).on('click', '#lasso--featImgUpload > a', function( e ){\n\n\t    e.preventDefault();\n\n\t    className = e.currentTarget.parentElement.className;\n\n\t  \tvar save  = $('#lasso--featImgSave a')\n\n\t    // If the media frame already exists, reopen it.\n\t    if ( file_frame ) {\n\t      \tfile_frame.open();\n\t      \treturn;\n\t    }\n\n\t    // Create the media frame.\n\t    file_frame = wp.media.frames.file_frame = wp.media({\n\t      \ttitle: lasso_editor.strings.chooseImage,\n\t      \tbutton: {\n\t        \ttext: lasso_editor.strings.updateImage,\n\t      \t},\n\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t    });\n\n\t    // When an image is selected, run a callback.\n\t    file_frame.on( 'select', function() {\n\n\t      \tvar attachment = file_frame.state().get('selection').first().toJSON();\n\n\t      \t$('body').addClass('lasso--post-thumb-applied');\n\n\t      \t$('article').removeClass('no-post-thumbnail').addClass('has-post-thumbnail');\n\n\t      \tif ( $(lasso_editor.featImgClass).is( \"img\" ) ) {\n\t\t\t\t$(lasso_editor.featImgClass).prop(\"src\",attachment.url);\n\t\t\t\t$(lasso_editor.featImgClass).prop(\"srcset\",\"\");\n\t\t\t} else {\n\t\t\t\t$(lasso_editor.featImgClass).css({\n\t\t\t\t\t'background-image': 'url('+attachment.url+')'\n\t\t\t\t});\n\t\t\t}\n\n\t      \tsave.attr('data-featimg-id',attachment.id).trigger('click');\n\n\t      \t$('.no-post-cover-note').remove();\n\n\t    });\n\n\t    // Finally, open the modal\n\t    file_frame.open();\n\t});\n\n\t////////////\n\t// FEAT IMAGE DELETE\n\t////////////\n\t$(document).on('click', '#lasso--featImgDelete > a', function( e ){\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\tvar data = {\n\t\t\taction: 'editus_del_featured_img',\n\t\t\tpostid: lasso_editor.postid,\n\t\t\tnonce: \tlasso_editor.featImgNonce\n\t\t}\n\n\t\tswal({\n\t\t\ttitle: lasso_editor.strings.removeFeatImg,\n\t\t\ttype: \"warning\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: lasso_editor.strings.deleteYes,\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n\t\t\t\tif ( \"\" == response ) {\n\n\t\t\t\t\t// add a body class so we can do whatever with\n\t\t\t\t\t$('body').addClass('lasso--post-thumb-removed');\n\n\t\t\t\t\t$('article').removeClass('has-post-thumbnail').addClass('no-post-thumbnail');\n\n\t\t\t\t\t// add the hidden class to control shell to allow for delete button\n\t\t\t\t\t$('#lasso--featImgDelete').addClass('lasso--featImg--controlHidden');\n\t\t\t\t\t$this.closest('ul').removeClass('lasso--featImg--has-thumb');\n\n\t\t\t\t\t// remove the attr src - just a real-time update\n\t\t\t      \tif ( $(lasso_editor.featImgClass).is( \"img\" ) ) {\n\t\t\t\t\t\t$(lasso_editor.featImgClass).attr(\"src\",\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$(lasso_editor.featImgClass).css({\n\t\t\t\t\t\t\t'background-image': 'url()'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t});\n\n\n\n\t});\n\n\t////////////\n\t// FEAT IMAGE FROM SETTINGS - @since 0.9.4\n\t////////////\n\tvar featimg_frame;\n\t$(document).on('click', '#lasso--post-thumb__add', function( e ){\n\n\t    e.preventDefault();\n\n\t    var $this = $(this)\n\t    ,\tsave  = $('#lasso--featImgSave a')\n\n\t    // If the media frame already exists, reopen it.\n\t    if ( featimg_frame ) {\n\t      \tfeatimg_frame.open();\n\t      \treturn;\n\t    }\n\n\t    // Create the media frame.\n\t    featimg_frame = wp.media.frames.featimg_frame = wp.media({\n\t      \ttitle: lasso_editor.strings.chooseImage,\n\t      \tbutton: {\n\t        \ttext: lasso_editor.strings.updateImage,\n\t      \t},\n\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t    });\n\n\t    // When an image is selected, run a callback.\n\t    featimg_frame.on( 'select', function() {\n\t      \tvar attachment = featimg_frame.state().get('selection').first().toJSON();\n\t\t\t\n\t\t\tvar pic = $this.closest('.lasso--post-thumb').find('img');\n\t\t\tpic.attr('src', attachment.url );\n\t\t\t\n\t      \tsave.attr('data-featimg-id',attachment.id).trigger('click');\n\t      \t$('#lasso--postsettings__form').removeClass('no-thumbnail').addClass('has-thumbnail');\n\t\t\tpic.removeAttr(\"srcset\");\n\t\t\tnoWarningReload = true;\n\t    });\n\n\t    // Finally, open the modal\n\t    featimg_frame.open();\n\n\n\t}).on('click', '#lasso--post-thumb__delete', function( e ){\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\tvar data = {\n\t\t\taction: 'editus_del_featured_img',\n\t\t\tpostid: lasso_editor.postid,\n\t\t\tnonce: \tlasso_editor.featImgNonce\n\t\t}\n\n\t\tswal({\n\t\t\ttitle: lasso_editor.strings.removeFeatImg,\n\t\t\ttype: \"warning\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: lasso_editor.strings.deleteYes,\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n                \n\n\t\t\t\tif ( \"\" == response ) {\n\t\t\t\t\tvar defaultImg = $this.closest('.lasso--post-thumb').data('default-thumb');\n\t\t\t      \t$this.closest('.lasso--postsettings__left').find('img').attr('src', defaultImg );\n\t\t\t\t\t$this.closest('.lasso--postsettings__left').find('img').removeAttr(\"srcset\");\n\n\t\t\t      \t$('#lasso--postsettings__form').removeClass('has-thumbnail').addClass('no-thumbnail')\n\t\t\t\t\tnoWarningReload = true;\n\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t});\n\n\t});\n\n})( jQuery );\n\n(function( $ ) {\n\n\tvar form;\n    // get updated aesop componets through ajax calls (global function)\n\twindow.get_aesop_component_ajax = function(cdata)\n\t{\n\t\tvar data = {\n\t\t\t\taction: 'get_aesop_component',\n\t\t\t\tcode: 'aesop_'+cdata['componentType']\n\t\t};\n\t\tfor ( var index in cdata ) {\n\t\t\t\t// Don't accept componentType as a param\n\t\t\t\tif ( !cdata.hasOwnProperty(index) || index == 'componentType'  || index =='sortableItem') {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdata[index] = cdata[index];\n\t\t}\n\t\t\t\t\t\t\n\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\tif( response ){\n\t\t\t\t\tresponse = response.replace(/\\\\'/g, \"'\");\n\t\t\t\t\tvar $a = $(response);\n\t\t\t\t\twindow.component.replaceWith($a);\n\t\t\t\t\twindow.component = $a;\n\t\t\t\t\tif ($('.fotorama').length){\n\t\t\t\t\t\t$('.fotorama').fotorama();\n\t\t\t\t\t}\n\t\t\t\t\tif ($('.aesop-gallery-photoset').length){\n\t\t\t\t\t\t$(window).trigger( 'load' );\n                    }\n                    \n                    lasso_editor.wrapImg();\n                    \n\t\t\t\t\t$('.aesop-component').each(function(){\n\t\t\t\t\t\tif ($(this).css(\"height\")==\"0px\") {\n\t\t\t\t\t\t\t$(this).css(\"height\",\"auto\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if there's no toolbar present\n\t\t\t\t\t\tif ( !$(this).find('.lasso-component--toolbar').length > 0 ) {\n\t\t\t\t\t\t\t// if this is a map then we need to first wrap it so that we can drag the  map around\n\t\t\t\t\t\t\tif ( $(this).hasClass('aesop-map-component') ) {\n\n\t\t\t\t\t\t\t\tvar $this = $(this)\n\n\t\t\t\t\t\t\t\t// so wrap it with a aesop-compoentn aesop-map-component div\n\t\t\t\t\t\t\t\t// @todo - note once a map is inserted it can't be edited after saving again. a user has to delete the existin map and add a new map\n\t\t\t\t\t\t\t\t// to\n\t\t\t\t\t\t\t\t//$this.wrap('<form id=\"lasso--map-form\" class=\"aesop-component aesop-map-component lasso--map-drag-holder\" data-component-type=\"map\" >').before( lassoDragHandle ).after( lassoMapForm );\n\t\t\t\t\t\t\t\t$this.wrap('<div id=\"lasso--map-form\" class=\"aesop-component aesop-map-component lasso--map-drag-holder\" data-component-type=\"map\" >').before( lassoDragHandle );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t$(this).append( lasso_editor.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif ('video' == cdata['componentType']) {\n\t\t\t\t\t\t$('.aesop-video-component').fitVids();\t\t\t\n\t\t\t\t\t}\n\t\t\t\t\tif ('gallery' == cdata['componentType']) {\n\t\t\t\t\t\tget_aesop_options('gallery');\n\t\t\t\t\t}\n\t\t\t\t\tif ('gallery_pop' == cdata['componentType']) {\n\t\t\t\t\t\tget_aesop_options('gallery_pop');\n\t\t\t\t\t}\n                    if ('timeline_stop' == cdata['componentType']) {\n\t\t\t\t\t\tlasso_editor.timelineGoTime();\n\t\t\t\t\t}\n                                        \n                    // set some figures to uneditable\n                    $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\n\t\t\t\t\tlasso_editor.dirtyByComponent = true;\n\t\t\t\t} else {\n\t\t\t\t\talert(\"error\");\n\t\t\t}\n\t\t});\n\t}\n\t\n\t//reload aesop component options\n\tfunction get_aesop_options(comp)\n\t{\n\t\tvar data = {\n\t\t\t\taction: 'editus_get_ase_options',\n\t\t\t\tcomponent: comp\n\t\t};\n\t\t\t\t\t\t\n\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\tif( response ){\t\t\t\t\n\t\t\t\t\tlasso_editor.component_options[comp] = response;\n\t\t\t\t} else {\n\t\t\t\t\talert(\"error\");\n\t\t\t}\n\t\t});\n\t}\n\n\t//$('#lasso--component-settings-form').live('submit', function(e) {\n\t//jQuery(document).on('submit', '#lasso--component-settings-form', function(e){\n    jQuery(document).on('submit', '#aesop-generator-settings', function(e){\n\n\t\te.preventDefault();\n        e.stopImmediatePropagation();\n\n\t\t// store some atts\n\t\tvar $component \t= window.component\n\t\t,\tcdata \t\t= $component.data()\n\t\t,\tsaveInsert \t= $('#lasso-generator-insert')\n\t\t,\tform \t\t= $('#lasso--component-settings-form')\n\t\t,\t$this \t\t= $(this);\n\n\t\t// let people know something is happening\n\t\tsaveInsert.val(lasso_editor.strings.saving);\n\n\t\t// send the new settings to the component and update it's data attributes\n\t    $this.find('.lasso-generator-attr').each(function(){\n\n\t      \tvar optionName = $(this).closest('.lasso-option').data('option');\n\n\t      \t// save even if the entry is blank\n\t      \t//if ( '' !== $(this).val() ) {\n\t      \t//$component.attr( 'data-' + optionName, $(this).val() );\n            $component.prop( 'data-' + optionName, $(this).val() );\n\t      \t$component.data(optionName, $(this).val() );\n\t\t\t//}\n\n\t    });\n\n\t    // return the data attributes as field for the sortable item\n\t    var cleanFields = function( cdata ){\n\t    \tdelete cdata['sortableItem'];\n\t    \treturn cdata;\n\t    }\n\t\t\n\n\t    /**\n\t    *\n\t    *\tBuild a sequence that saves, adds a class, and removs the sidebar\n\t    *\t@param stall bool should we stall on save? typically used for all but the gallery component which runs an ajax call\n\t    *\t@param timeout int how long should we timeout before removing the settings sidebar\n\t    *\t@param gallery bool is this a gallery creation? otherwise let's mod the label\n\t    */\n\t    var saveSequence = function( stall, timeout, gallery ){\n\n\t    \t// add a saved class then change the save label to saved\n\t    \tvar saveActions = function(gallery){\n\n\t    \t\tsaveInsert.addClass('saved');\n\n\t    \t\tif ( true == gallery ) {\n\n\t\t\t\t\tsaveInsert.val(lasso_editor.strings.galleryCreated);\n\n\t    \t\t} else {\n\n\t\t\t\t\tsaveInsert.val(lasso_editor.strings.saved);\n\t\t\t\t}\n\t    \t}\n\n\t    \tif ( true == stall ) {\n\n\t\t\t\tsetTimeout( function(){ saveActions(); }, 500 );\n\n\t\t\t} else if ( true == gallery ) {\n\n\t\t\t\t//form.addClass('hide-all-fields').prepend('<div id=\"lasso--pagerefresh\">Gallery Created! Save your post and refresh the page to access this new gallery.</div>')\n\n\t\t\t\tsetTimeout( function(){ saveActions(true); }, 500 );\n\n\t    \t} else {\n\n\t\t    \tsaveActions();\n\n\t    \t}\n\n\t\t\tsetTimeout( function(){ $('body').removeClass('lasso-sidebar-open'); }, timeout );\n\t\t\tarticleMedium.makeUndoable();\n\t\t\tlasso_editor.dirtyByComponent = true;\n\n\t    }\n\n\t\t// make an ajax call to deal with gallery saving or creating only if it's a gallery\n\t\tif ( 'gallery' == cdata['componentType'] ) {\n\n\n\t\t\tvar data = {\n\t\t\t\taction: \t\t$('.ase-gallery-opts--create-gallery2').is(\":visible\") ? 'editus_create_gallery' : 'editus_update_gallery',\n\t\t\t\tpostid: \t\tcdata['id'],\n\t\t\t\tunique: \t\tcdata['unique'],\n\t\t\t\tfields: \t\tcleanFields(cdata),\n\t\t\t\tgallery_type:   $('#ase_gallery_type').val(),\n\t\t\t\tgallery_ids: \t$('#ase_gallery_ids').val(),\n\t\t\t\tnonce: \t\t\t$('#lasso-generator-nonce').val()\n\t\t\t}\n\t\t\tif ($('.ase-gallery-opts--create-gallery2').is(\":visible\")) {\n\t\t\t\tdata['edgallerytitle'] = document.getElementById(\"lasso--gallery__galleryname\").value;\n\t\t\t}\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n                retData = JSON.parse(response);\n\t\t\t\tif ( 'gallery-created' == retData[\"message\"] ) {\n\t\t\t\t\tsaveSequence( false, 1000, true );\n\t\t\t\t\t// load the new gallery\n\t\t\t\t\tcdata['id'] = retData[\"id\"];\n\t\t\t\t} else if ( 'gallery-updated' == retData[\"message\"] ) {\n\t\t\t\t\tsaveSequence( false, 1000 );\n\t\t\t\t\tform.before(lasso_editor.refreshRequired);\n\t\t\t\t} else {\n\n\t\t\t\t\talert( 'error' );\n\n\t\t\t\t}\n\t\t\t\twindow.get_aesop_component_ajax(cdata);\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\t\t} else {\n\n\t\t\tsaveSequence( true, 1200 );\n\n\t\t}\n\t\t\n\t\tif ( 'image' == cdata['componentType'] || 'quote' == cdata['componentType'] || 'parallax' == cdata['componentType'] || 'chapter' == cdata['componentType'] || 'video' == cdata['componentType'] ||\n\t\t      'character' == cdata['componentType'] || 'collection' == cdata['componentType'] || 'audio' == cdata['componentType']) {\n\t\t\twindow.get_aesop_component_ajax(cdata);\n\t\t} else if ('content' == cdata['componentType']) {\n\t\t\tvar inner = component.find('.aesop-component-content-data');\n\n\t\t\tif ( inner.length != 0 ) {\n\t\t\t\tcdata['content_data'] = inner[0].innerHTML;\n\t\t\t}\n\t\t\twindow.get_aesop_component_ajax(cdata);\n\t\t} /*else if ('events' == cdata['componentType']) {\n\t\t\t//aesop events\n\t\t\talert(\"Save and Reload the page to see the update.\");\n\t\t}*/\n        else {\n            window.get_aesop_component_ajax(cdata);\n        }\n\t});\n\n})( jQuery );\n\n(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t// method to destroy the modal\n\t\tvar destroyModal = function(){\n\t\t\t$('body').removeClass('lasso-modal-open' );\n\t\t\t$('.lasso--modal, #lasso--modal__overlay').remove();\n\t\t\tif (noWarningReload) {\n\t\t\t\tlocation.reload();\n\t\t\t}\n\t\t}\n\n\t\t// modal click\n\t\t//$('#lasso--post-new').live('click',function(e){\n\t\tjQuery(document).on('click','#lasso--post-new',function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\t// add a body class\n\t\t\t$('body').toggleClass('lasso-modal-open');\n\n\t\t\t// append teh modal markup ( lasso_editor_component_modal() )\n\t\t\t$('body').append(lasso_editor.newPostModal);\n\n\t\t    // if any changes happen then show the footer\n\t\t    $('.lasso--modal__trigger-footer').on('keyup',function(){\n\t\t\t  \t$('.lasso--postsettings__footer #lasso--postsettings-create').slideDown()\n\t\t\t});\n\n\t\t\tmodalResizer()\n\n\t\t});\n\n\t\t// destroy modal if clicking close or overlay\n\t\t//$('#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel').live('click',function(e){\n\t\tjQuery(document).on('click','#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel',function(e){\n\t\t\te.preventDefault();\n\t\t\tdestroyModal();\n\t\t});\n\t\t\n\t\tjQuery(document).on('click', '#lasso--postsettings-setnow', function(e){\n\t\t\t$('.editus_custom_date').datepicker( \"setDate\", new Date().setTime(Date.now()) );\n\t\t});\n\n\t\t/////////////////\n\t\t/// EXIT SETTINGS\n\t\t///////////////////\n\t\t$(document).keyup(function(e) {\n\n\t\t\tif ( 27 == e.keyCode ) {\n\n\t\t\t\tdestroyModal();\n\t\t\t}\n\n\t\t});\n\n\t\t/////////////\n\t\t// MAKE NEW POST OBJECT\n\t\t//////////////\n\t\tvar form;\n\n\t\t//$('#lasso--postnew__form').live('submit', function(e) {\n\t\tjQuery(document).on('submit', '#lasso--postnew__form', function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\tvar $this = $(this);\n\n\t\t\t$(this).find('input[type=\"submit\"]').val(lasso_editor.strings.adding);\n\n\t\t\t\n\t\t\tif (lasso_editor.saveusingrest) {\n                // Use REST API \n\t\t\t\tvar data2 = $this.serializeArray().reduce(function(obj, item) {\n\t\t\t\t\tobj[item.name] = item.value;\n\t\t\t\t\treturn obj;\n\t\t\t\t}, {});\n\t\t\t\tnewPostREST(data2.story_title, data2.object,lasso_editor.newObjectContent);\n\t\t\t} else {\n\t\t\t\tvar data = $this.serialize();\n\t\t\t\t/////////////\n\t\t\t\t//\tDO TEH SAVE\n\t\t\t\t/////////////\n\t\t\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\t\t\t\t\tif ( true == response.success ) {\n\t\t\t\t\t\t$('input[type=\"submit\"]').addClass('saved');\n\t\t\t\t\t\t$('input[type=\"submit\"]').val(lasso_editor.strings.added);\n\t\t\t\t\t\twindow.location.replace(response.link+'&preview=true');\n\t\t\t\t\t} else {\n\t\t\t\t\t\talert('error');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t});\n\n\t});\n\t\n\tfunction newPostREST(title_, type_,content_){\n\t\tvar data      = {\n\t\t\ttitle: title_,\n\t\t\tcontent: \tcontent_, \n\t\t\tstatus: \"draft\"\n\t\t};\n\t\t\n\t\tif (lasso_editor.currCat !== null) {\n\t\t\tdata.categories = $.map( lasso_editor.currCat, function( a ) {\n\t\t\t  return a.term_id;\n\t\t\t});\n\t\t}\n\t\t\n\t\tvar type;\n\t\tif (type_==\"post\") {\n\t\t\ttype = \"posts\";\n\t\t} else if (type_==\"page\"){\n\t\t\ttype = \"pages\";\n\t\t} else {\n\t\t\ttype = type_;\n\t\t}\n\t\t\t\n\t\t$.ajax({\n\t\t\tmethod: \"POST\",\n\t\t\turl: lasso_editor.rest_root + 'wp/v2/'+type,\n\t\t\tdata: data,\n\t\t\tbeforeSend: function ( xhr ) {\n\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t},\n\t\t\tsuccess : function( response ) {\n\t\t\t\t$('input[type=\"submit\"]').addClass('saved');\n\t\t\t\t$('input[type=\"submit\"]').val(lasso_editor.strings.added);\n\n\t\t\t\twindow.location.replace(response.link+'&preview=true');\n\t\t\t},\n\t\t\terror : function (xhr, exception) {\n\t\t\t\talert(\"AJAX Error: \"+xhr.responseText );\t\t\n\t\t\t}\n\t\t});\n\t}\n\n\t/////////////\n\t// POST OBJECT CHANGE - since 0.9.5\n\t/////////////\n\t//$('#lasso--select-type').live('change',function() {\n\tjQuery(document).on('change', '#lasso--select-type', function(){\n\n\t\tvar val = $(this).val()\n\n\t\t$('input[name=\"object\"]').val( val )\n\n\t\t$(this).closest('.story-slug-option').find('label span:not(.lasso-util--help)').text( val )\n\t});\n\n})( jQuery );\n\n(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t/////////////\n\t\t// SAVE TITLE\n\t\t/////////////\n\n\t\t$(lasso_editor.titleClass).on('blur', function() {\n\n\t\t\tvar target = $(this);\n\n\t\t\tvar data = {\n\t\t\t\taction: \t\t'process_title-update_post',\n\t\t\t\tpostid: \t\tlasso_editor.postid,\n\t\t\t\ttitle:          $.trim( target.text() ),\n\t\t\t\tnonce: \t\t\tlasso_editor.titleNonce\n\t\t\t}\n\n\t\t\t/////////////\n\t\t\t//\tUPDATE THE TITLE\n\t\t\t/////////////\n\t\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\t\tif ( true == response.success ) {\n\n\t\t\t\t\tvar saveClass = 'lasso-title-saved';\n\n\t\t\t\t\ttarget.addClass(saveClass);\n\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\ttarget.removeClass(saveClass);\n\t\t\t\t\t},500);\n\t\t\t\t}\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\t\t});\n\n\t});\n\n})( jQuery );\n\n(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t// get the attachment id from teh class wp-image-XXX, where XXX is the id of the attached iamge\n\t\t// this oly works if the image was inserted from within the wordpress post editor\n\t\tvar ase_edit_frame;\n\t\tvar className;\n\n\t\t$(document).on('click', '.lasso--wpimg-edit',function(e){\n\n\t\t\te.preventDefault();\n            \n            if ($(this).parent().parent().find('img').length==0) {\n                return;\n            }\n            var id ='';\n\t\t\tvar selected_img\n\t\t\t, \tclicked = $(this)\n\t\t\t, \tcls \t\t= $(this).parent().next('img').attr('class');\n            if (cls) {\n                id = cls.match(/\\d+/);\n            }\n\n\t\t    className = e.currentTarget.parentElement.className;\n\n\t\t    // create frame\n\t\t    ase_edit_frame = wp.media.frames.ase_edit_frame = wp.media({\n\t\t      \ttitle: lasso_editor.strings.selectImage,\n\t\t      \tbutton: {\n\t\t        \ttext: lasso_editor.strings.insertImage,\n\t\t      \t},\n\t\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t\t    });\n\n\t\t    // open frame\n\t\t\tase_edit_frame.on('open',function(){\n\t\t\t\tvar selection = ase_edit_frame.state().get('selection');\n                if (id) {\n\t\t\t\t\tvar attachment = wp.media.attachment( id );\n\t\t\t\t\tattachment.fetch();\n\t\t\t\t\tselection.add( attachment ? [ attachment ] : [] );\n                }\n\t\t\t});\n\n\t\t    // update image on select\n\t\t    ase_edit_frame.on( 'select', function() {\n                // here after simple wpimg image select\n\n\t\t      \tvar attachment = ase_edit_frame.state().get('selection').first().toJSON()\n\t\t      \t,\timageURL   = undefined === attachment.sizes.large ? attachment.sizes.full.url : attachment.sizes.large.url\n\n\t\t      \t$(clicked).parent().parent().find('img').prop({\n\t\t      \t\t'src': imageURL,\n                    'srcset' :\"\",\n\t\t      \t\t'alt': attachment.alt,\n\t\t      \t\t'class': 'aligncenter size-large wp-image-'+attachment.id+''\n\t\t      \t});\n\t\t\t\t//$(\"html\").scrollTop(lasso_editor.scrollTop);\n                $('#lasso-side-comp-button,.lasso--text-popup').remove();\n                // set some figures to uneditable\n                $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\n\t\t    });\n\n\t\t\tlasso_editor.scrollTop = $(window).scrollTop();\n\t\t    // Finally, open the modal\n\t\t    ase_edit_frame.open();\n\n\t\t})\n\t});\n\n})( jQuery );\n(function( $ ) {\n\n\t$(document).on('submit', '#lasso--custom-field-form', function(e) {\n\n\t\te.preventDefault();\n\t\t$('#lasso--save').trigger('click');\n\n\t\tvar $this \t= $(this)\n\t\t,\tsubmit \t= $this.find('input[type=\"submit\"]')\n\t\t,\tstrings = lasso_editor.strings\n\t\t,\tdata\t= $this.serialize();\n\n\t\tsubmit.val( strings.saving );\n\n\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\tif( true == response.success ) {\n\n\t\t\t\tsubmit.val( strings.saved ).addClass('saved');\n\n\t\t\t\t/*console.log(response)\n\n\t\t\t\tsetTimeout(function(){\n\n\t\t\t\t\tsubmit.removeClass('saved');\n\t\t\t\t\tsubmit.val( strings.save );\n\n\t\t\t\t},1000);*/\n\t\t\t\tlocation.reload();\n\n\t\t\t}\n\n\t\t}).fail(function(xhr, err) { \n\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t});\n\n\t});\n\n\n})( jQuery );\n\n(function( $ ) {\n\n\t// dyanmically center modals vertically based on size of modal\n\tjQuery(document).ready(function($){\n\n\t\tmodalResizer = function(){\n\n\t\t\tvar modal = $('.lasso--modal')\n\t\t\t,   mHeight = modal.height()\n\t\t\t,\twHeight  = $(window).height()\n\t\t\t,\teHeight  = $('.lasso--modal').hasClass('lasso--tour__modal') ? 0 : 30 // this is the height of the submit button that is hidden utnil the user changes a setting\n\n\t\t\tmodal.css({\n\t\t\t\t'top' : (wHeight - mHeight - eHeight) / 2\n\t\t\t})\n\n\t\t}\n\t\t$('.lasso--modal').imagesLoaded( function() {\n\t\t\tmodalResizer();\n\t\t})\n\n\t\tjQuery(window).resize(function(){ modalResizer(); });\n\n\t});\n\n})( jQuery );\n(function( $, Backbone, _, WP_API_Settings, undefined ) {\n\n\tvar contentTemplate = $('#lasso-tmpl--post' )\n\t, \tpostTemplate \t= _.template( contentTemplate.html() )\n\t//, \tposts \t\t\t= new wp.api.collections.Posts()\n\t//,\tpages \t\t\t= new wp.api.collections.Pages()\n\t,\tpostAll         = $('#lasso--post-all')\n\t,\tpostList        = '#lasso--post-list'\n\t,\tloadingText     = lasso_editor.strings.loading\n\t,\tloadMoreText    = lasso_editor.strings.loadMore\n\t,\tnoPostsText     = lasso_editor.strings.noPostsFound\n\t,   fetchFailText   = lasso_editor.strings.fetchFail\n\t,\tbody \t\t\t= $('body')\n\t,\tnoPostsMessage  = '<li id=\"lasso--end-posts\">'+noPostsText+'</li>'\n\t,\tfetchFailMessage  = '<li id=\"lasso--end-posts\">'+fetchFailText+'</li>'\n\t,\tnoResultsDiv  \t= lasso_editor.noResultsDiv\n\t, \tloader\t\t\t= '<div id=\"lasso--loading\" class=\"lasso--loading\"><div class=\"lasso--loader\"></div></div>'\n\t,\tmoreButton      = '<a href=\"#\" id=\"lasso--load-more\">'+loadMoreText+'</a>'\n\t,\tcloseButton      = '<a href=\"#\" id=\"lasso--close-modal-posts\">'+lasso_editor.strings.close+'</a>'\n\t,\tclear     \t\t= '<i id=\"lasso--clear-search\" class=\"dashicons dashicons-dismiss\"></i>'\n\t,\tclearItem   \t= '#lasso--clear-search'\n\t,\thideClass       = 'lasso--hide'\n\t,\tshowClass       = 'lasso--show'\n\t,\thelper      \t= '#lasso--helper'\n\t,\tpage \t\t\t= 1\n    ,   lastType        = 'posts'\n    ,   collection      = false\n    ,   initial         = true\n    ,   totalPages      = null\n    ,\tapi             = WP_API_Settings.root\n    ,\ttimer\n\t// infinite load options\n\tvar options = {\n\t\tdata: {\n\t\t\tpage: page,\n\t\t\tfilter: {\n\t\t\t\tpost_status: ['publish','draft','pending'] \n\t\t\t}\n\t\t}\n\t}\n\n\t//////////////////\n\t// DESTROY LOADER\n\t/////////////////\n\tfunction destroyLoader(){\n\t\t$('#lasso--loading').remove()\n\t}\n\n\t/////////////////\n\t// INITIALIZE SCROLL\n\t/////////////////\n\tfunction initScroll() {\n\n        $(postList).perfectScrollbar({\n\t\t\tsuppressScrollX: true\n\t\t});\n    }\n\n\t// set links clickable\n\t//$(\"a\").attr('contenteditable',false);\n\t\n\tfunction fetchError(xhr){\n\t\t$( '#lasso--loading' ).remove();\n\t\t\n\t\ttry {\n\t\t\tvar data = JSON.parse(xhr.responseText);\n\t\t\tif (data['code'] == 'rest_post_invalid_page_number' ) {\n\t\t\t\t$( '#lasso--load-more' ).remove();\n\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t} else {\n\t\t\t\t// show some info\n\t\t\t\t$( postList ).append( fetchFailMessage + '<div style=\"overflow-y: scroll; height:400px;\"><code style=\"font-size:8px;\">'+JSON.stringify(xhr).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')+'</code></div>' );\t\n\t\t\t}\n\t\t}\n\t\tcatch (e){\n\t\t\t$( postList ).append( fetchFailMessage);\n\t\t}\n\t}\n\t\t\n\t//////////////////\n\t// FETCH POSTS HELPER FUNCTION\n\t/////////////////\n\tfunction fetchPosts( type ){\t\n\t\tvar capable = lasso_editor.edit_others_posts;\n\t\tlastType = type;\n\t\tif ( 'pages' == type ) {\n\t\t\tcapable = lasso_editor.edit_others_pages;\n\t\t} /*else if ( 'posts' == type ) {\n            //collection = new wp.api.collections.Posts( options );\n        } else {\n\t\t\t// this is a working, alternate way to get collection of custom post type\n\t\t\t/*var customPost = wp.api.models.Post.extend({\n\t\t\t\turlRoot: WP_API_Settings.root + 'wp/v2/'+type,\n\t\t\t\tdefaults: {\n\t\t\t\t\ttype: type\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar customCollection = wp.api.collections.Posts.extend({\n\t\t\t\turl: WP_API_Settings.root + 'wp/v2/'+type,\n\t\t\t\tmodel: customPost\n\t\t\t});\n\t\t\tcollection = new customCollection;*\n\t\t}*/\n\t\t\n\t\tif (type=='posts') {\n\t\t\toptions = capable ? setOptionsPost( type, page ) : setOptionsPost( type, page, lasso_editor.author );\n\t\t\tcollection = new wp.api.collections.Posts( );\n\t\t\tcollection.fetch(  options ).done( function() {\n\t\t\t\t//remove more button\n\t\t\t\t$( '#lasso--load-more,#lasso--close-modal-posts' ).remove();\n\t\t\t\t// if we have more posts then load them\n\t\t\t\tif ( collection.length > 0 ) {\n\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + collection.state.currentPage + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\tif (lasso_editor.restapi2) {\n\t\t\t\t\t\tcollection.each( function ( model ) {\n\t\t\t\t\t\t\t//post.link title status id\n\t\t\t\t\t\t   setContainer.append( postTemplate( { post: model.attributes, link_: model.attributes._links.self[0].href, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcollection.each( function ( model ) {\n\t\t\t\t\t\t   setContainer.append( postTemplate( { post: model.attributes, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\t// append to the post container\n\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t//put back more button\n\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t$(postList).append( closeButton );\n\n\t\t\t\t\t// show search filtering\n\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible')\n\n\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t// re-init scroll\n\t\t\t\t\tinitScroll()\n\t\t\t\t}else{\n\t\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t$('#lasso--end-posts').fadeOut('slow')\n\t\t\t\t\t}, 1000)\n\t\t\t\t}\n\t\t\t\t// destroy the spinny loader\n\t\t\t\tdestroyLoader();\n\t\t\t}).fail(function(xhr, err) {\n\t\t\t\tfetchError(xhr);\n\t\t\t});\n\t\t} else {\n\t\t\t/*var author = capable ? lasso_editor.author : -1;\n\t\t\tvar parms = getParams( true, page, author );\n\t\t\tjQuery.ajax({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\turl: WP_API_Settings.root+'wp/v2/'+type+parms,//'?status[]=draft&author[]='+lasso_editor.author,\n\t\t\t\t//dataType: \"json\",\n\t\t\t\tbeforeSend: function(xhr){\n\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t\t},\n\t\t\t\tsuccess : function( data ) {\n\t\t\t\t\tdispPosts(data, type);\n\t\t\t\t\tparms = getParams( false, page, author );\n\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\turl: WP_API_Settings.root+'wp/v2/'+type+parms,\n\t\t\t\t\t\t//dataType: \"json\",\n\t\t\t\t\t\tbeforeSend: function(xhr){\n\t\t\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsuccess : function( data ) {\n\t\t\t\t\t\t\tdispPosts(data, type);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdone: function(data)  {\t\t\t\t\t\t\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(xhr, err)  {\n\t\t\t\t\t\t    $( '#lasso--loading' ).remove();\n\t\t\t\t\t\t\t//alert(xhr.responseText);\n\t\t\t\t\t\t\t//fetchError(xhr);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tdone: function(data)  {\n\t\t\t\t\t\n\t\t\t\t},\n\t\t\t\terror: function(xhr, err)  {\n\t\t\t\t    $( '#lasso--loading' ).remove();\n\t\t\t\t\t//alert(xhr.responseText);\n\t\t\t\t\t//fetchError(xhr);\n\t\t\t\t\tparms = getParams( false, page, lasso_editor.author );\n\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\turl: WP_API_Settings.root+'wp/v2/'+type+parms,\n\t\t\t\t\t\t//dataType: \"json\",\n\t\t\t\t\t\tbeforeSend: function(xhr){\n\t\t\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsuccess : function( data ) {\n\t\t\t\t\t\t\tdispPosts(data, type);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdone: function(data)  {\t\t\t\t\t\t\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(xhr, err)  {\n\t\t\t\t\t\t    $( '#lasso--loading' ).remove();\n\t\t\t\t\t\t\t//alert(xhr.responseText);\n\t\t\t\t\t\t\t//fetchError(xhr);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});*/\n\n\t\t\t\n\t\t\t\n\t\t\toptions = capable ? setOptions( type, page ) : setOptions( type, page, lasso_editor.author );\n\t\t\tjQuery.getJSON(WP_API_Settings.root+'wp/v2/'+type,options, function(data) {\n\t\t\t\t$( '#lasso--load-more' ).remove();\n\t\t\t\tif ( data.length > 0 ) {\n\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + page + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\tjQuery.each( data, function( i, val ) {\n\t\t\t\t\t   setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) );\n\t\t\t\t\t});\n\t\t\t\t\t// append to the post container\n\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t//put back more button\n\t\t\t\t\tif (data.length>=7 ) {\n\t\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t}\n\n\t\t\t\t\t// show search filtering\n\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible');\n\t\t\t\t\t// re-init scroll\n\t\t\t\t\tinitScroll()\n\t\t\t\t} else {\n\t\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t$('#lasso--end-posts').fadeOut('slow')\n\t\t\t\t\t}, 1000)\n\t\t\t\t}\n\t\t\t\tdestroyLoader();\n\t\t\t\t\t\n\t\t\t})\n\t\t\t.fail(function(xhr, err)  {\n\t\t\t\tfetchError(xhr);\n\t\t\t});\n\t\t}\n\t}\n\t\n\tfunction dispPosts(data, type) {\n\t\t$( '#lasso--load-more' ).remove();\n\t\tif ( data.length > 0 ) {\n\t\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + page + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\t\tjQuery.each( data, function( i, val ) {\n\t\t\t\t\t\t   setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// append to the post container\n\t\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t\t//put back more button\n\t\t\t\t\t\tif (data.length>=7 ) {\n\t\t\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// show search filtering\n\t\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible');\n\t\t\t\t\t\t// re-init scroll\n\t\t\t\t\t\tinitScroll()\n\t\t} else {\n\t\t\t\t\t\t//$( postList ).append( noPostsMessage );\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\t$('#lafesso--end-posts').fadeOut('slow')\n\t\t\t\t\t\t}, 1000)\n\t\t}\n\t\tdestroyLoader();\n\t}\n\t\n\tfunction getParams( draft, page, author ) {\n\t\tvar params = '?page='+page;\n\t   if (author != -1) {\n\t\t   params += '&author[]='+author;\n\t   }\n\t   if (draft) {\n\t\t   params += '&status[]=draft';\n\t   }\n\t   return params;\n    }\n\n    /**\n     * Helper function to reset options\n     *\n     * @param type post type\n     * @param page page\n     *\n     * @returns {{data: {page: *, filter: {post_type: *, post_status: string[]}}}}\n     */\n    function setOptions( type, page, author ) {\n\t   if (!author) {\n\t\t   return {\n                page: page,\n                type: type,\n\t\t\t\t//status: 'draft',\n\t\t\t\tper_page: 7,\n\t\t\t\t//filter: {\n\t\t\t\t\t//post_status: ['publish','draft','pending'],\n\t\t\t\t//\tposts_per_page: 7,\n\t\t\t\t\t//author: author\n\t\t\t\t//}\n\t\t   };\n\t   }\n       return {\n            page: page,\n            type: type,\n\t\t\tauthor: author,\n\t\t\t//status: ['publish','draft','pending'],\n\t\t\tper_page: 7,\n            /*filter: {\n                post_status: ['publish','draft','pending'],\n                posts_per_page: 7,\n                author: author\n            }*/\n        }\n    }\n\t\n\tfunction setOptionsPost( type, page, author ) {\n\n       return options = {\n            data: {\n                page: page,\n                type: type,\n\t\t\t\tauthor: author,\n\t\t\t\tstatus:['publish','draft','pending'],\n\t\t\t\tper_page: 7,\n                filter: {\n                    post_status: ['publish','draft','pending'],\n                    posts_per_page: 7,\n                    author: author\n                }\n            }\n        }\n    }\n\n\t//////////////////\n\t// OPEN INITIAL POSTS\n\t/////////////////\n\t$( postAll ).on('click',function(e){\n\n\t\te.preventDefault();\n\n\t\t// add a body class\n\t\tbody.toggleClass('lasso-modal-open');\n\n\t\t// append teh modal markup ( lasso_editor_component_modal() )\n\t\tbody.append( lasso_editor.allPostModal );\n\n\t\t// get the intial posts\n\t\tfetchPosts('posts');\n\n\t\tmodalResizer();\n\n\t});\n\n    /**\n     * Load more click event\n     */\n    $( body ).on('click', '#lasso--load-more', function(e){\n        e.preventDefault();\n\n        type = $( this ).attr( 'data-post-type' );\n\n        $(this).addClass('lasso--btn-loading').text( loadingText );\n\n        if (lastType == type) {\n\t\t\tpage++;\n\t\t} else {\n\t\t\tpage = 1;\n\t\t}\n\n        lastType = type;\n\n        fetchPosts( type );\n\n    }).on('click','#lasso--close-modal-posts',function(e){\n\t\t\te.preventDefault();\n\t\t\tdestroyModal();\n\n\t}).on('click', '.lasso--show-objects', function(e){\n\n\t\te.preventDefault();\n\n\t\t$('.lasso--show-objects').removeClass('active');\n\t\t$(this).addClass('active');\n\n\t\t$('#lasso--post-list').empty();\n        type = $(this).data('post-type');\n        page = 1;\n        totalPages = null;\n        $( '#lasso--load-more' ).attr( 'data-post-type', type);\n\n\t\t$(postList).prepend( loader );\n\n\t\tfetchPosts( type );\n\n\t}).on('click', '#lasso--post__delete', function(e){\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\tswal({\n\t\t\ttitle: lasso_editor.strings.deletePost,\n\t\t\ttype: \"error\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: lasso_editor.strings.deleteYes,\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\tvar data = {\n\t\t\t\taction: \t\t'editus_delete_post',\n\t\t\t\tpostid: \t\t$this.closest('a').data('postid'),\n\t\t\t\tnonce: \t\t\tlasso_editor.deletePost\n\t\t\t}\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n\t\t\t\tif ( \"\" == response ) {\n\n\t\t\t\t\t$this.closest('li').fadeOut().remove()\n\n\t\t\t\t}\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\t\t});\n\n\t}).on('keyup','#lasso--search-field',function( e ){ // live search - @since 0.9.5\n\n\t\t// clear the previous timer\n\t\tclearTimeout(timer)\n\n\t\tvar key \t\t= e.which\n\t\t,\tthat        = this\n\t\t,\tval \t\t= $.trim( $(this).val() )\n\t\t,\tvalEqual    = val == $(that).val()\n\t\t,\tnotEmpty    = '' !== val\n\t\t,\ttype        = $('.active.lasso--show-objects').data('post-type')\n\t\t,\turl \t\t= api+'/'+type+'s?filter[s]='+val+'&filter[posts_per_page]=50'\n\t\t,\tinput       = '#lasso--search-field'\n\t\t,\tresults     = $('#lasso--results-found')\n\t\t,\thelperText  = lasso_editor.strings.helperText\n\t\t,\thelperSpan  = '<span id=\"lasso--helper\">'+helperText+'</span>'\n\n\t\t// 800ms delay so we dont exectute excessively\n\t\ttimer = setTimeout(function() {\n\n\t\t\t// don't proceed if the value is empty or not equal to itself\n\t\t\tif ( !valEqual && !notEmpty )\n\t\t\t\treturn false;\n\n\t\t\t// what if the user only types two characters?\n\t\t\tif ( val.length == 2 && !$(helper).length ) {\n\n\t\t\t\tdestroyClose()\n\t\t\t\t$(input).after( helperSpan )\n\n\t\t\t}\n\n\t\t\t// if we have more than 3 characters and if value is teh same\n\t\t\tif ( val.length >= 3 || val.length >= 3 && 13 == key ) {\n\n\t\t\t\t// append loading indicator\n\t\t\t\t$(postList).prepend( loader );\n\n\t\t\t\t// remove any helpers\n\t\t\t\t$( helper ).fadeOut().remove();\n\n\t\t\t\t// remove the cose\n\t\t\t\tdestroyClose();\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t//http://localhost/wordpress/wp-json/wp/v2/posts?search=test%205\n\t\t\t\t\n\t\t\t\tvar page = 1;\n\t\t\t\tvar capable = lasso_editor.edit_others_posts;\n\t\t\t\t\n\t\t\t\t\n\t\t\t\tif (type=='posts') {\n\t\t\t\t\toptions = capable ? setOptionsPost( type, page ) : setOptionsPost( type, page, lasso_editor.author );\n\t\t\t\t\toptions.data['search']=val;\n\t\t\t\t\tcollection = new wp.api.collections.Posts( );\n\t\t\t\t\tcollection.fetch(  options ).done( function() {\n\t\t\t\t\t\t\n\t\t\t\t\t\t$(postList).children().remove();\n\t\t\t\t\t\t//remove more button\n\t\t\t\t\t\t$( '#lasso--load-more,#lasso--close-modal-posts' ).remove();\n\t\t\t\t\t\t// if we have more posts then load them\n\t\t\t\t\t\tif ( collection.length > 0 ) {\n\t\t\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + collection.state.currentPage + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\t\t\tif (lasso_editor.restapi2) {\n\t\t\t\t\t\t\t\tcollection.each( function ( model ) {\n\t\t\t\t\t\t\t\t\t//post.link title status id\n\t\t\t\t\t\t\t\t   setContainer.append( postTemplate( { post: model.attributes, link_: model.attributes._links.self[0].href, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcollection.each( function ( model ) {\n\t\t\t\t\t\t\t\t   setContainer.append( postTemplate( { post: model.attributes, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// append to the post container\n\t\t\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t\t\t//put back more button\n\t\t\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t\t\t$(postList).append( closeButton );\n\n\t\t\t\t\t\t\t// show search filtering\n\t\t\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible')\n\n\t\t\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t\t\t// re-init scroll\n\t\t\t\t\t\t\tinitScroll()\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\t\t$('#lasso--end-posts').fadeOut('slow')\n\t\t\t\t\t\t\t}, 1000)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// destroy the spinny loader\n\t\t\t\t\t\tdestroyLoader();\n\t\t\t\t\t}).fail(function(xhr, err) {\n\t\t\t\t\t\tfetchError(xhr);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\toptions = capable ? setOptions( type, page ) : setOptions( type, page, lasso_editor.author );\n\t\t\t\t\toptions['search']=val;\n\t\t\t\t\tjQuery.getJSON(WP_API_Settings.root+'wp/v2/'+type,options, function(data) {\n\t\t\t\t\t\t$( '#lasso--load-more' ).remove();\n\t\t\t\t\t\t$(postList).children().remove();\n\t\t\t\t\t\tif ( data.length > 0 ) {\n\t\t\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + page + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\t\t\tjQuery.each( data, function( i, val ) {\n\t\t\t\t\t\t\t   setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t// append to the post container\n\t\t\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t\t\t//put back more button\n\t\t\t\t\t\t\tif (data.length>=7 ) {\n\t\t\t\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// show search filtering\n\t\t\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible');\n\t\t\t\t\t\t\t// re-init scroll\n\t\t\t\t\t\t\tinitScroll()\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\t\t$('#lasso--end-posts').fadeOut('slow')\n\t\t\t\t\t\t\t}, 1000)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdestroyLoader();\n\t\t\t\t\t\t\t\n\t\t\t\t\t})\n\t\t\t\t\t.fail(function(xhr, err)  {\n\t\t\t\t\t\tfetchError(xhr);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t}, 600);\n\n\t}).on('click','#lasso--search__toggle', function( e ) { // open close search\n\n\t\te.preventDefault()\n\n\t\tvar input = $('#lasso--search-field')\n\n\n\t\t// toggle visible class\n\t\t$('.lasso--search').toggleClass( 'lasso--search__visible' )\n\n\t\t// focus on input\n\t\tinput.focus()\n\n\t\t// if the search isnt visible and not empty then destroy the search\n\t\tif ( !$(this).parent().hasClass('lasso--search__visible') && input.val() !== '' ) {\n\t\t\tdestroySearch('post')\n\t\t}\n\n\t}).on('click', clearItem, function(e){\n\n\t\te.preventDefault();\n\t\tdestroySearch('post');\n\n\t});\n\n\t/**\n\t* \tUtility function destroy search close\n\t*/\n\tfunction destroyClose(){\n\n\t\t$( clearItem ).remove();\n\n\t}\n\n\t/**\n\t*\tHelper fucntion to destroy the search\n\t*\t@param type string the type of post to fetch (post or page)\n\t*\t@since 0.9.5\n\t*/\n\tfunction destroySearch( type ){\n\n\t\t// remove teh children\n\t\t$(postList).children().remove()\n\n\t\t// fetch initial posts\n\t\tfetchPosts( type )\n\n\t\t// clear previous seach term\n\t\t$( '#lasso--search-field' ).val('').focusout() // weird bug with focusout not wokring\n\n\t\t// hide searh results\n\t\t$('#lasso--results-found').parent().css('opacity',0)\n\n\t\t// remove helper if any\n\t\t$( helper ).remove();\n\n\t\t// remove close\n\t\tdestroyClose()\n\t}\n\t\n\tjQuery(document).on('click', '#lasso--post-list', function(e){\n\t\t\tif (e.target.id === 'lasso--post-list') {\n\t\t\t\t// close modal if the user clicks on empty spaces\n\t\t\t\t// destroy posts modal\n\t\t\t\t$('#lasso--all-posts__modal').remove();\n\t\t\t\t$( '#lasso--modal__overlay' ).remove();\n\t\t\t\t$('body').remove('#lasso--modal__overlay');\n\t\t\t}\n\t});\n\n})( jQuery, Backbone, _, WP_API_Settings );\n(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\tdestroyModal = function(){\n\t\t\t$('body').removeClass('lasso-modal-open');\n\t\t\t$('#lasso--tour__modal,#lasso--all-posts__modal,#lasso--modal__overlay').remove();\n\t\t}\n\n\t\t//$('#lasso--tour__modal input[type=\"submit\"]').live('click', function(e) {\n\t\tjQuery(document).on('click', '#lasso--tour__modal input[type=\"submit\"]', function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\tvar target = $(this);\n\n\t\t\tif ( !$('#hide_tour').is(':checked') ) {\n\n\t\t\t\tdestroyModal()\n\n\t\t\t} else {\n\t\t\t\tif (lasso_editor.saveusingrest) {\n\t\t\t\t\tvar data = {\n\t\t\t\t\t\taction: \t\t'process_tour_hide',\n\t\t\t\t\t\tnonce: \t\t\t$(this).data('nonce')\n\t\t\t\t\t}\n\n\t\t\t\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\t\t\t\tif ( true == response.success ) {\n\n\t\t\t\t\t\t\tdestroyModal();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}).fail(function(xhr, err) { \n\t\t\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tvar data = {\n\t\t\t\t\t\taction: \t\t'process_tour_hide',\n\t\t\t\t\t\tnonce: \t\t\t$(this).data('nonce')\n\t\t\t\t\t}\n\n\t\t\t\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\t\t\t\tif ( true == response.success ) {\n\n\t\t\t\t\t\t\tdestroyModal();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}).fail(function(xhr, err) { \n\t\t\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t\t\t});\t\t\t\t\n\t\t\t\t}\n\t\t\t}\n\n\t\t});\n\n\t});\n\n})( jQuery );\n\n(function( $ ) {\n\tjQuery(document).ready(function($){\n\t\tif ( $( \"#lasso--tour__slides\" ).length ) {\n\n\t\t\t$('body').addClass('lasso-modal-open');\n\n\t\t\t$('.lasso--loading').remove();\n\t\t\t$('#lasso--tour__slides').hide().fadeIn()\n\n\t\t\t$('#lasso--tour__slides').unslider({\n\t\t\t\tdots: true,\n\t\t\t\tdelay:7000\n\t\t\t});\n\t\t}\n\t});\n})( jQuery );\n\n(function( $ ) {\n\n    $(document).ready(function(){\n\n        var vars \t\t= lasso_editor\n        ,\trevisions\n        , \trevision_id = 0\n        , \tnext\n        , \tprevious\n       \t, \ttotal\n\n       \trevisionList = $('#lasso--revision-list');\n\n        // method to destroy the modal\n        var destroyModal = function(){\n            $('body').removeClass('lasso-modal-open');\n            $('#lasso--revision__modal').remove();\n            $('#lasso--post-revisions').show();\n        };\n\n        // destroy loader\n\t\tfunction destroyLoader(){\n\t\t\t$('#lasso--loading').remove();\n\t\t}\n\n        //Update title/post content for a revision\n        var restoreRevision = function( revision_id ) {\n\n            if( revision_id in revisions ){\n                revision = revisions[ revision_id ];\n                $( vars.titleClass ).html( revision.post_title );\n                $( vars.article_object ).html( revision.post_content );\n                $('body').attr('data-revision', revision_id );\n\n            }\n        };\n\t\t\n\n        // modal click\n        $('#lasso--post-revisions').on('click',function(e){\n\n            e.preventDefault();\n\n            // preent double clicking and opening\n            $(this).hide();\n\n            // append revision modal\n            $('body').append(vars.revisionModal);\n\n            innerModal = $('#lasso--revision__modal .lasso--modal__inner');\n\n            // make the modal draggable\n            innerModal.draggable({ cursor:'move', opacity:0.8 });\n\n            data = {\n                action : 'process_revision_get',\n                postid : vars.postid,\n                nonce : vars.nonce\n            };\n\n            $.post( vars.ajaxurl, data, function(response) {\n\n            \t// do we have a response\n                if ( true == response.success ) {\n\n                \trevisionList = $('#lasso--revision-list');\n                \tslider       = $('#lasso--slider');\n                \tlassoHide    = $('#lasso--hide');\n\n                \t// remove any count classes\n                \tremoveRevisionCount();\n\n                \t// desroy the loader\n                \tdestroyLoader();\n\n                \t// show the button and slider\n                \tlassoHide.show();\n\n                \t// if we have revisions\n                    if ( 'object' == typeof response.data && response.data.length ) {\n\n                        revisions = response.data;\n\n                        var total = revisions.length == 1 ? 1 : revisions.length -1;\n\n                        if ( revisions.length !== 1 ) {\n\n\t                        $.each( revisions, function( i, post )  {\n\n\t                            revisionList.append( '<li class=\"lasso--jump-revision\" data-revision=\"'+i+'\"><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"'+post.modified_date+'\">' + post.modified_time + '</span></li>' )\n\n\t                        });\n\n\t\t\t\t\t\t\t// init slider and restore on slide\n\t\t\t\t\t\t    slider.slider({\n\t\t\t\t\t\t      \tmin: 0,\n\t\t\t\t\t\t      \tmax: total,\n\t\t\t\t\t\t      \tanimate:'fast',\n\t\t\t\t\t\t      \tvalue: 0,\n\t\t\t\t\t\t      \tzindex:999,\n\t\t\t\t\t\t\t    slide: function( event, ui ) {\n\t\t\t\t\t\t\t        restoreRevision( ui.value )\n\t\t\t\t\t\t\t    }\n\n\t\t\t\t\t\t    });\n\n\t\t\t\t\t\t    // restore revision and sync slider on click\n\t\t\t\t\t\t    $('.lasso--jump-revision').on('click',function(e){\n\n\t\t\t\t\t\t    \te.preventDefault();\n\n\t\t\t\t\t\t    \tvar val = $(this).data('revision');\n\n\t\t\t\t\t\t    \tslider.slider( 'value', val );\n\n\t\t\t\t\t\t    \trestoreRevision( val );\n\t\t\t\t\t\t    })\n\n\t\t\t\t\t\t    revisionList.attr('data-count', total + 1 ) // because we start at 0\n\n\t\t\t\t\t\t} else {\n\n                        \tlassoHide.hide();\n                        \tinnerModal.append( vars.noRevisionsDiv );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t    $('body').addClass('lasso--revision-count-'+revisions.length );\n\n\t\t\t\t\t    maybeRestoreCurrent();\n\n                        modalResizer();\n\n                    }else{\n                    \t$('#lasso--hide').hide()\n                       \tinnerModal.append( vars.noRevisionsDiv );\n                       \tmodalResizer();\n                    }\n\n                } else {\n\n                    alert('error');\n\n                }\n\n\n            }).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n            modalResizer();\n\n        });\n\n\t\t// select a revision and start editing\n\t\t$(document).on('click', '#lasso--select-revision', function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\tdestroyModal();\n\n\t\t\t$('#lasso--edit').trigger('click');\n\n\t\t\taddBackupNotice();\n\n\t\t}).on('click','#lasso--close-modal',function(e){\n\n\t\t\te.preventDefault();\n\t\t\tdestroyModal();\n\n\t\t});\n\n        /////////////////\n        /// EXIT SETTINGS\n        ///////////////////\n        $(document).keyup(function(e) {\n\n            if ( 27 == e.keyCode ) {\n\n                destroyModal();\n            }\n\n        });\n\n        // restore teh current revision but only if a user is editing one\n        function maybeRestoreCurrent(){\n\n        \tif( $('body').data('revision') ) {\n\n        \t\tslider.slider('value', $('body').data('revision') )\n\n        \t}\n        }\n\n        // add a backup notice if we're editing a backukp\n        function addBackupNotice(){\n\n        \tif ( !$('#lasso--notice').length ) {\n\n\t\t\t\t$(vars.article_object).before('<div id=\"lasso--notice\" class=\"lasso--notice lasso--notice-warning\">'+vars.strings.editingBackup+'</div>');\n\t\t\t}\n        }\n\n        // remove/reset revisino count\n        function removeRevisionCount(){\n\n\t        $('body').removeClass (function (index, css) {\n\t\t\t    return (css.match (/(^|\\s)lasso--revision-count-\\S+/g) || []).join(' ');\n\t\t\t});\n        }\n\n    });\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/all-posts.js",
    "content": "(function( $, Backbone, _, WP_API_Settings, undefined ) {\n\n\tvar contentTemplate = $('#lasso-tmpl--post' )\n\t, \tpostTemplate \t= _.template( contentTemplate.html() )\n\t//, \tposts \t\t\t= new wp.api.collections.Posts()\n\t//,\tpages \t\t\t= new wp.api.collections.Pages()\n\t,\tpostAll         = $('#lasso--post-all')\n\t,\tpostList        = '#lasso--post-list'\n\t,\tloadingText     = lasso_editor.strings.loading\n\t,\tloadMoreText    = lasso_editor.strings.loadMore\n\t,\tnoPostsText     = lasso_editor.strings.noPostsFound\n\t,   fetchFailText   = lasso_editor.strings.fetchFail\n\t,\tbody \t\t\t= $('body')\n\t,\tnoPostsMessage  = '<li id=\"lasso--end-posts\">'+noPostsText+'</li>'\n\t,\tfetchFailMessage  = '<li id=\"lasso--end-posts\">'+fetchFailText+'</li>'\n\t,\tnoResultsDiv  \t= lasso_editor.noResultsDiv\n\t, \tloader\t\t\t= '<div id=\"lasso--loading\" class=\"lasso--loading\"><div class=\"lasso--loader\"></div></div>'\n\t,\tmoreButton      = '<a href=\"#\" id=\"lasso--load-more\">'+loadMoreText+'</a>'\n\t,\tcloseButton      = '<a href=\"#\" id=\"lasso--close-modal-posts\">'+lasso_editor.strings.close+'</a>'\n\t,\tclear     \t\t= '<i id=\"lasso--clear-search\" class=\"dashicons dashicons-dismiss\"></i>'\n\t,\tclearItem   \t= '#lasso--clear-search'\n\t,\thideClass       = 'lasso--hide'\n\t,\tshowClass       = 'lasso--show'\n\t,\thelper      \t= '#lasso--helper'\n\t,\tpage \t\t\t= 1\n    ,   lastType        = 'posts'\n    ,   collection      = false\n    ,   initial         = true\n    ,   totalPages      = null\n    ,\tapi             = WP_API_Settings.root\n    ,\ttimer\n\t// infinite load options\n\tvar options = {\n\t\tdata: {\n\t\t\tpage: page,\n\t\t\tfilter: {\n\t\t\t\tpost_status: ['publish','draft','pending'] \n\t\t\t}\n\t\t}\n\t}\n\n\t//////////////////\n\t// DESTROY LOADER\n\t/////////////////\n\tfunction destroyLoader(){\n\t\t$('#lasso--loading').remove()\n\t}\n\n\t/////////////////\n\t// INITIALIZE SCROLL\n\t/////////////////\n\tfunction initScroll() {\n\n        $(postList).perfectScrollbar({\n\t\t\tsuppressScrollX: true\n\t\t});\n    }\n\n\t// set links clickable\n\t//$(\"a\").attr('contenteditable',false);\n\t\n\tfunction fetchError(xhr){\n\t\t$( '#lasso--loading' ).remove();\n\t\t\n\t\ttry {\n\t\t\tvar data = JSON.parse(xhr.responseText);\n\t\t\tif (data['code'] == 'rest_post_invalid_page_number' ) {\n\t\t\t\t$( '#lasso--load-more' ).remove();\n\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t} else {\n\t\t\t\t// show some info\n\t\t\t\t$( postList ).append( fetchFailMessage + '<div style=\"overflow-y: scroll; height:400px;\"><code style=\"font-size:8px;\">'+JSON.stringify(xhr).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')+'</code></div>' );\t\n\t\t\t}\n\t\t}\n\t\tcatch (e){\n\t\t\t$( postList ).append( fetchFailMessage);\n\t\t}\n\t}\n\t\t\n\t//////////////////\n\t// FETCH POSTS HELPER FUNCTION\n\t/////////////////\n\tfunction fetchPosts( type ){\t\n\t\tvar capable = lasso_editor.edit_others_posts;\n\t\tlastType = type;\n\t\tif ( 'pages' == type ) {\n\t\t\tcapable = lasso_editor.edit_others_pages;\n\t\t} /*else if ( 'posts' == type ) {\n            //collection = new wp.api.collections.Posts( options );\n        } else {\n\t\t\t// this is a working, alternate way to get collection of custom post type\n\t\t\t/*var customPost = wp.api.models.Post.extend({\n\t\t\t\turlRoot: WP_API_Settings.root + 'wp/v2/'+type,\n\t\t\t\tdefaults: {\n\t\t\t\t\ttype: type\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar customCollection = wp.api.collections.Posts.extend({\n\t\t\t\turl: WP_API_Settings.root + 'wp/v2/'+type,\n\t\t\t\tmodel: customPost\n\t\t\t});\n\t\t\tcollection = new customCollection;*\n\t\t}*/\n\t\t\n\t\tif (type=='posts') {\n\t\t\toptions = capable ? setOptionsPost( type, page ) : setOptionsPost( type, page, lasso_editor.author );\n\t\t\tcollection = new wp.api.collections.Posts( );\n\t\t\tcollection.fetch(  options ).done( function() {\n\t\t\t\t//remove more button\n\t\t\t\t$( '#lasso--load-more,#lasso--close-modal-posts' ).remove();\n\t\t\t\t// if we have more posts then load them\n\t\t\t\tif ( collection.length > 0 ) {\n\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + collection.state.currentPage + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\tif (lasso_editor.restapi2) {\n\t\t\t\t\t\tcollection.each( function ( model ) {\n\t\t\t\t\t\t\t//post.link title status id\n\t\t\t\t\t\t   setContainer.append( postTemplate( { post: model.attributes, link_: model.attributes._links.self[0].href, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcollection.each( function ( model ) {\n\t\t\t\t\t\t   setContainer.append( postTemplate( { post: model.attributes, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\t// append to the post container\n\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t//put back more button\n\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t$(postList).append( closeButton );\n\n\t\t\t\t\t// show search filtering\n\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible')\n\n\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t// re-init scroll\n\t\t\t\t\tinitScroll()\n\t\t\t\t}else{\n\t\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t$('#lasso--end-posts').fadeOut('slow')\n\t\t\t\t\t}, 1000)\n\t\t\t\t}\n\t\t\t\t// destroy the spinny loader\n\t\t\t\tdestroyLoader();\n\t\t\t}).fail(function(xhr, err) {\n\t\t\t\tfetchError(xhr);\n\t\t\t});\n\t\t} else {\n\t\t\t/*var author = capable ? lasso_editor.author : -1;\n\t\t\tvar parms = getParams( true, page, author );\n\t\t\tjQuery.ajax({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\turl: WP_API_Settings.root+'wp/v2/'+type+parms,//'?status[]=draft&author[]='+lasso_editor.author,\n\t\t\t\t//dataType: \"json\",\n\t\t\t\tbeforeSend: function(xhr){\n\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t\t},\n\t\t\t\tsuccess : function( data ) {\n\t\t\t\t\tdispPosts(data, type);\n\t\t\t\t\tparms = getParams( false, page, author );\n\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\turl: WP_API_Settings.root+'wp/v2/'+type+parms,\n\t\t\t\t\t\t//dataType: \"json\",\n\t\t\t\t\t\tbeforeSend: function(xhr){\n\t\t\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsuccess : function( data ) {\n\t\t\t\t\t\t\tdispPosts(data, type);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdone: function(data)  {\t\t\t\t\t\t\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(xhr, err)  {\n\t\t\t\t\t\t    $( '#lasso--loading' ).remove();\n\t\t\t\t\t\t\t//alert(xhr.responseText);\n\t\t\t\t\t\t\t//fetchError(xhr);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tdone: function(data)  {\n\t\t\t\t\t\n\t\t\t\t},\n\t\t\t\terror: function(xhr, err)  {\n\t\t\t\t    $( '#lasso--loading' ).remove();\n\t\t\t\t\t//alert(xhr.responseText);\n\t\t\t\t\t//fetchError(xhr);\n\t\t\t\t\tparms = getParams( false, page, lasso_editor.author );\n\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\turl: WP_API_Settings.root+'wp/v2/'+type+parms,\n\t\t\t\t\t\t//dataType: \"json\",\n\t\t\t\t\t\tbeforeSend: function(xhr){\n\t\t\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsuccess : function( data ) {\n\t\t\t\t\t\t\tdispPosts(data, type);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdone: function(data)  {\t\t\t\t\t\t\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(xhr, err)  {\n\t\t\t\t\t\t    $( '#lasso--loading' ).remove();\n\t\t\t\t\t\t\t//alert(xhr.responseText);\n\t\t\t\t\t\t\t//fetchError(xhr);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});*/\n\n\t\t\t\n\t\t\t\n\t\t\toptions = capable ? setOptions( type, page ) : setOptions( type, page, lasso_editor.author );\n\t\t\tjQuery.getJSON(WP_API_Settings.root+'wp/v2/'+type,options, function(data) {\n\t\t\t\t$( '#lasso--load-more' ).remove();\n\t\t\t\tif ( data.length > 0 ) {\n\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + page + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\tjQuery.each( data, function( i, val ) {\n\t\t\t\t\t   setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) );\n\t\t\t\t\t});\n\t\t\t\t\t// append to the post container\n\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t//put back more button\n\t\t\t\t\tif (data.length>=7 ) {\n\t\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t}\n\n\t\t\t\t\t// show search filtering\n\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible');\n\t\t\t\t\t// re-init scroll\n\t\t\t\t\tinitScroll()\n\t\t\t\t} else {\n\t\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t$('#lasso--end-posts').fadeOut('slow')\n\t\t\t\t\t}, 1000)\n\t\t\t\t}\n\t\t\t\tdestroyLoader();\n\t\t\t\t\t\n\t\t\t})\n\t\t\t.fail(function(xhr, err)  {\n\t\t\t\tfetchError(xhr);\n\t\t\t});\n\t\t}\n\t}\n\t\n\tfunction dispPosts(data, type) {\n\t\t$( '#lasso--load-more' ).remove();\n\t\tif ( data.length > 0 ) {\n\t\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + page + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\t\tjQuery.each( data, function( i, val ) {\n\t\t\t\t\t\t   setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// append to the post container\n\t\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t\t//put back more button\n\t\t\t\t\t\tif (data.length>=7 ) {\n\t\t\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// show search filtering\n\t\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible');\n\t\t\t\t\t\t// re-init scroll\n\t\t\t\t\t\tinitScroll()\n\t\t} else {\n\t\t\t\t\t\t//$( postList ).append( noPostsMessage );\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\t$('#lafesso--end-posts').fadeOut('slow')\n\t\t\t\t\t\t}, 1000)\n\t\t}\n\t\tdestroyLoader();\n\t}\n\t\n\tfunction getParams( draft, page, author ) {\n\t\tvar params = '?page='+page;\n\t   if (author != -1) {\n\t\t   params += '&author[]='+author;\n\t   }\n\t   if (draft) {\n\t\t   params += '&status[]=draft';\n\t   }\n\t   return params;\n    }\n\n    /**\n     * Helper function to reset options\n     *\n     * @param type post type\n     * @param page page\n     *\n     * @returns {{data: {page: *, filter: {post_type: *, post_status: string[]}}}}\n     */\n    function setOptions( type, page, author ) {\n\t   if (!author) {\n\t\t   return {\n                page: page,\n                type: type,\n\t\t\t\t//status: 'draft',\n\t\t\t\tper_page: 7,\n\t\t\t\t//filter: {\n\t\t\t\t\t//post_status: ['publish','draft','pending'],\n\t\t\t\t//\tposts_per_page: 7,\n\t\t\t\t\t//author: author\n\t\t\t\t//}\n\t\t   };\n\t   }\n       return {\n            page: page,\n            type: type,\n\t\t\tauthor: author,\n\t\t\t//status: ['publish','draft','pending'],\n\t\t\tper_page: 7,\n            /*filter: {\n                post_status: ['publish','draft','pending'],\n                posts_per_page: 7,\n                author: author\n            }*/\n        }\n    }\n\t\n\tfunction setOptionsPost( type, page, author ) {\n\n       return options = {\n            data: {\n                page: page,\n                type: type,\n\t\t\t\tauthor: author,\n\t\t\t\tstatus:['publish','draft','pending'],\n\t\t\t\tper_page: 7,\n                filter: {\n                    post_status: ['publish','draft','pending'],\n                    posts_per_page: 7,\n                    author: author\n                }\n            }\n        }\n    }\n\n\t//////////////////\n\t// OPEN INITIAL POSTS\n\t/////////////////\n\t$( postAll ).on('click',function(e){\n\n\t\te.preventDefault();\n\n\t\t// add a body class\n\t\tbody.toggleClass('lasso-modal-open');\n\n\t\t// append teh modal markup ( lasso_editor_component_modal() )\n\t\tbody.append( lasso_editor.allPostModal );\n\n\t\t// get the intial posts\n\t\tfetchPosts('posts');\n\n\t\tmodalResizer();\n\n\t});\n\n    /**\n     * Load more click event\n     */\n    $( body ).on('click', '#lasso--load-more', function(e){\n        e.preventDefault();\n\n        type = $( this ).attr( 'data-post-type' );\n\n        $(this).addClass('lasso--btn-loading').text( loadingText );\n\n        if (lastType == type) {\n\t\t\tpage++;\n\t\t} else {\n\t\t\tpage = 1;\n\t\t}\n\n        lastType = type;\n\n        fetchPosts( type );\n\n    }).on('click','#lasso--close-modal-posts',function(e){\n\t\t\te.preventDefault();\n\t\t\tdestroyModal();\n\n\t}).on('click', '.lasso--show-objects', function(e){\n\n\t\te.preventDefault();\n\n\t\t$('.lasso--show-objects').removeClass('active');\n\t\t$(this).addClass('active');\n\n\t\t$('#lasso--post-list').empty();\n        type = $(this).data('post-type');\n        page = 1;\n        totalPages = null;\n        $( '#lasso--load-more' ).attr( 'data-post-type', type);\n\n\t\t$(postList).prepend( loader );\n\n\t\tfetchPosts( type );\n\n\t}).on('click', '#lasso--post__delete', function(e){\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\tswal({\n\t\t\ttitle: lasso_editor.strings.deletePost,\n\t\t\ttype: \"error\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: lasso_editor.strings.deleteYes,\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\tvar data = {\n\t\t\t\taction: \t\t'editus_delete_post',\n\t\t\t\tpostid: \t\t$this.closest('a').data('postid'),\n\t\t\t\tnonce: \t\t\tlasso_editor.deletePost\n\t\t\t}\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n\t\t\t\tif ( \"\" == response ) {\n\n\t\t\t\t\t$this.closest('li').fadeOut().remove()\n\n\t\t\t\t}\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\t\t});\n\n\t}).on('keyup','#lasso--search-field',function( e ){ // live search - @since 0.9.5\n\n\t\t// clear the previous timer\n\t\tclearTimeout(timer)\n\n\t\tvar key \t\t= e.which\n\t\t,\tthat        = this\n\t\t,\tval \t\t= $.trim( $(this).val() )\n\t\t,\tvalEqual    = val == $(that).val()\n\t\t,\tnotEmpty    = '' !== val\n\t\t,\ttype        = $('.active.lasso--show-objects').data('post-type')\n\t\t,\turl \t\t= api+'/'+type+'s?filter[s]='+val+'&filter[posts_per_page]=50'\n\t\t,\tinput       = '#lasso--search-field'\n\t\t,\tresults     = $('#lasso--results-found')\n\t\t,\thelperText  = lasso_editor.strings.helperText\n\t\t,\thelperSpan  = '<span id=\"lasso--helper\">'+helperText+'</span>'\n\n\t\t// 800ms delay so we dont exectute excessively\n\t\ttimer = setTimeout(function() {\n\n\t\t\t// don't proceed if the value is empty or not equal to itself\n\t\t\tif ( !valEqual && !notEmpty )\n\t\t\t\treturn false;\n\n\t\t\t// what if the user only types two characters?\n\t\t\tif ( val.length == 2 && !$(helper).length ) {\n\n\t\t\t\tdestroyClose()\n\t\t\t\t$(input).after( helperSpan )\n\n\t\t\t}\n\n\t\t\t// if we have more than 3 characters and if value is teh same\n\t\t\tif ( val.length >= 3 || val.length >= 3 && 13 == key ) {\n\n\t\t\t\t// append loading indicator\n\t\t\t\t$(postList).prepend( loader );\n\n\t\t\t\t// remove any helpers\n\t\t\t\t$( helper ).fadeOut().remove();\n\n\t\t\t\t// remove the cose\n\t\t\t\tdestroyClose();\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t//http://localhost/wordpress/wp-json/wp/v2/posts?search=test%205\n\t\t\t\t\n\t\t\t\tvar page = 1;\n\t\t\t\tvar capable = lasso_editor.edit_others_posts;\n\t\t\t\t\n\t\t\t\t\n\t\t\t\tif (type=='posts') {\n\t\t\t\t\toptions = capable ? setOptionsPost( type, page ) : setOptionsPost( type, page, lasso_editor.author );\n\t\t\t\t\toptions.data['search']=val;\n\t\t\t\t\tcollection = new wp.api.collections.Posts( );\n\t\t\t\t\tcollection.fetch(  options ).done( function() {\n\t\t\t\t\t\t\n\t\t\t\t\t\t$(postList).children().remove();\n\t\t\t\t\t\t//remove more button\n\t\t\t\t\t\t$( '#lasso--load-more,#lasso--close-modal-posts' ).remove();\n\t\t\t\t\t\t// if we have more posts then load them\n\t\t\t\t\t\tif ( collection.length > 0 ) {\n\t\t\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + collection.state.currentPage + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\t\t\tif (lasso_editor.restapi2) {\n\t\t\t\t\t\t\t\tcollection.each( function ( model ) {\n\t\t\t\t\t\t\t\t\t//post.link title status id\n\t\t\t\t\t\t\t\t   setContainer.append( postTemplate( { post: model.attributes, link_: model.attributes._links.self[0].href, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcollection.each( function ( model ) {\n\t\t\t\t\t\t\t\t   setContainer.append( postTemplate( { post: model.attributes, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// append to the post container\n\t\t\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t\t\t//put back more button\n\t\t\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t\t\t$(postList).append( closeButton );\n\n\t\t\t\t\t\t\t// show search filtering\n\t\t\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible')\n\n\t\t\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t\t\t// re-init scroll\n\t\t\t\t\t\t\tinitScroll()\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\t\t$('#lasso--end-posts').fadeOut('slow')\n\t\t\t\t\t\t\t}, 1000)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// destroy the spinny loader\n\t\t\t\t\t\tdestroyLoader();\n\t\t\t\t\t}).fail(function(xhr, err) {\n\t\t\t\t\t\tfetchError(xhr);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\toptions = capable ? setOptions( type, page ) : setOptions( type, page, lasso_editor.author );\n\t\t\t\t\toptions['search']=val;\n\t\t\t\t\tjQuery.getJSON(WP_API_Settings.root+'wp/v2/'+type,options, function(data) {\n\t\t\t\t\t\t$( '#lasso--load-more' ).remove();\n\t\t\t\t\t\t$(postList).children().remove();\n\t\t\t\t\t\tif ( data.length > 0 ) {\n\t\t\t\t\t\t\tvar setContainer = $( '<div data-page-num=\"' + page + '\" class=\"lasso--object-batch\" id=\"lasso--object-batch-' + page + '\"></div>' );\n\n\t\t\t\t\t\t\tjQuery.each( data, function( i, val ) {\n\t\t\t\t\t\t\t   setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) );\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t// append to the post container\n\t\t\t\t\t\t\t$(postList).append( setContainer );\n\n\t\t\t\t\t\t\t//put back more button\n\t\t\t\t\t\t\tif (data.length>=7 ) {\n\t\t\t\t\t\t\t\t$(postList).append( moreButton );\n\t\t\t\t\t\t\t\t$( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading');\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// show search filtering\n\t\t\t\t\t\t\t$('.lasso--post-filtering').removeClass('not-visible').addClass('visible');\n\t\t\t\t\t\t\t// re-init scroll\n\t\t\t\t\t\t\tinitScroll()\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$( postList ).append( noPostsMessage );\n\t\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\t\t$('#lasso--end-posts').fadeOut('slow')\n\t\t\t\t\t\t\t}, 1000)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdestroyLoader();\n\t\t\t\t\t\t\t\n\t\t\t\t\t})\n\t\t\t\t\t.fail(function(xhr, err)  {\n\t\t\t\t\t\tfetchError(xhr);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t}, 600);\n\n\t}).on('click','#lasso--search__toggle', function( e ) { // open close search\n\n\t\te.preventDefault()\n\n\t\tvar input = $('#lasso--search-field')\n\n\n\t\t// toggle visible class\n\t\t$('.lasso--search').toggleClass( 'lasso--search__visible' )\n\n\t\t// focus on input\n\t\tinput.focus()\n\n\t\t// if the search isnt visible and not empty then destroy the search\n\t\tif ( !$(this).parent().hasClass('lasso--search__visible') && input.val() !== '' ) {\n\t\t\tdestroySearch('post')\n\t\t}\n\n\t}).on('click', clearItem, function(e){\n\n\t\te.preventDefault();\n\t\tdestroySearch('post');\n\n\t});\n\n\t/**\n\t* \tUtility function destroy search close\n\t*/\n\tfunction destroyClose(){\n\n\t\t$( clearItem ).remove();\n\n\t}\n\n\t/**\n\t*\tHelper fucntion to destroy the search\n\t*\t@param type string the type of post to fetch (post or page)\n\t*\t@since 0.9.5\n\t*/\n\tfunction destroySearch( type ){\n\n\t\t// remove teh children\n\t\t$(postList).children().remove()\n\n\t\t// fetch initial posts\n\t\tfetchPosts( type )\n\n\t\t// clear previous seach term\n\t\t$( '#lasso--search-field' ).val('').focusout() // weird bug with focusout not wokring\n\n\t\t// hide searh results\n\t\t$('#lasso--results-found').parent().css('opacity',0)\n\n\t\t// remove helper if any\n\t\t$( helper ).remove();\n\n\t\t// remove close\n\t\tdestroyClose()\n\t}\n\t\n\tjQuery(document).on('click', '#lasso--post-list', function(e){\n\t\t\tif (e.target.id === 'lasso--post-list') {\n\t\t\t\t// close modal if the user clicks on empty spaces\n\t\t\t\t// destroy posts modal\n\t\t\t\t$('#lasso--all-posts__modal').remove();\n\t\t\t\t$( '#lasso--modal__overlay' ).remove();\n\t\t\t\t$('body').remove('#lasso--modal__overlay');\n\t\t\t}\n\t});\n\n})( jQuery, Backbone, _, WP_API_Settings );"
  },
  {
    "path": "public/assets/js/source/enter-editor.js",
    "content": "jQuery(document).ready(function($){\n\n\tvar editor \t\t\t= lasso_editor.editor,\n\t\tstrings \t\t= lasso_editor.strings,\n\t\tsettingsLink\t= lasso_editor.settingsLink,\n\t\tpost_container  = lasso_editor.article_object,\n\t\ttoolbar \t\t= lasso_editor.toolbar,\n        toolbarPopup \t\t= lasso_editor.toolbarPopup,\n\t\ttoolbarHeading \t= lasso_editor.toolbarHeadings,\n\t\tpanel           = lasso_editor.component_sidebar,\n\t\tpostid          = lasso_editor.postid,\n\t\tmodal \t\t\t= lasso_editor.component_modal,\n\t\tcomponents \t\t= lasso_editor.components,\n\t\tfeatImgClass   \t= lasso_editor.featImgClass,\n\t\tfeatImgNonce    = lasso_editor.featImgNonce,\n\t\ttitleClass      = lasso_editor.titleClass,\n\t\tuploadControls  = lasso_editor.featImgControls,\n\t\twpImgEdit \t\t= lasso_editor.wpImgEdit,\n\t\tlassoDragHandle = lasso_editor.handle,\n\t\tlassoMapForm \t= lasso_editor.mapFormFooter,\n\t\tmapLocations    = lasso_editor.mapLocations,\n\t\tmapZoom    \t\t= lasso_editor.mapZoom,\n\t\tmapStart        = lasso_editor.mapStart,\n\t\tobjectsNoSave   = lasso_editor.objectsNoSave,\n\t\tobjectsNonEditable = lasso_editor.objectsNonEditable,\n\t\tsupportedNoSave = lasso_editor.supportedNoSave\n\n\tfunction restoreSelection(range) {\n\t    if (range) {\n\t        if (window.getSelection) {\n\t            var sel = window.getSelection();\n\t            sel.removeAllRanges();\n\t            sel.addRange(range);\n\t        } else if (document.selection && range.select) {\n\t            range.select();\n\t        }\n\t    }\n\t}\n    \n    function saveSelection() {\n        if (window.getSelection) {\n            article.highlight();\n            sel = window.getSelection();\n            if (sel.getRangeAt && sel.rangeCount) {\n                return sel.getRangeAt(0);\n            }\n        } else if (document.selection && document.selection.createRange) {\n            return document.selection.createRange();\n        }\n        return null;\n    }\n\n\t/*\n\tfunction to disable selection. Not used for now\n\tjQuery.fn.extend({\n\t\tdisableSelection : function() {\n\t\t\treturn this.each(function() {\n\t\t\t\tthis.onselectstart = function() { return false; };\n\t\t\t\tthis.unselectable = \"on\";\n\t\t\t\tjQuery(this).css('user-select', 'none');\n\t\t\t\tjQuery(this).css('-o-user-select', 'none');\n\t\t\t\tjQuery(this).css('-moz-user-select', 'none');\n\t\t\t\tjQuery(this).css('-khtml-user-select', 'none');\n\t\t\t\tjQuery(this).css('-webkit-user-select', 'none');\n\t\t\t});\n\t\t}\n\t});*/\n\t\n\n\t$('#lasso--edit').click(function(e){\n\t\n\t\tif ($(post_container).length ==0 ){\n\t\t\t// try one more time, support for shapely theme\n\t\t\tvar contClasses = [\".shapely-content\",\".entry-content\",\".aesop-entry-content\",\".novella-entry-content\",\".post-content\", \".entry-content-wrapper\",\".post_content\",\".gp-entry-content\"];\n\t\t\tfor (var i = 0; i < contClasses.length; i++) {\t\t\n\t\t\t\tif ($(contClasses[i]).length >0 ){\n\t\t\t\t\tpost_container = contClasses[i];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tif ($(post_container).length ==0 ){\n\t\t\t\t// if we can't find the article class, warn them and exit\n\t\t\t\tswal({\n\t\t\t\t\ttitle: strings.warning,\n\t\t\t\t\ttype: 'info',\n\t\t\t\t\ttext: strings.missingClass,\n\t\t\t\t\tshowCancelButton: true,\n\t\t\t\t\tcancelButtonText: strings.cancelText,\n\t\t\t\t\tconfirmButtonColor: '#007aab',\n\t\t\t\t\tconfirmButtonText: strings.missingConfirm,\n\t\t\t\t\tcloseOnConfirm: false\n\t\t\t\t},\n\t\t\t\tfunction(){\n\t\t\t\t\tlocation.replace(settingsLink);\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t\n\t\tlasso_editor.article_object = post_container;\n\t\t\n\t\t// ways to inject codes into the enterEditor\n\t\tif (lasso_editor.enterEditorHookArray) {\n\t\t\t$(lasso_editor.enterEditorHookArray).each(function(key, val){\n\t\t\t\tval();\n\t\t\t});\n\t\t}\n\t\t\n\t\t// lock the post for editing\n\t\tvar data = {\n\t\t\t\taction: 'editus_lock_post',\n\t\t\t\tpostid: lasso_editor.postid\n\t\t};\n\t\tlasso_editor.dontlock = false;\n\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\tif( response ){\n\t\t\t\tif (response.trim()==\"true\") {\n\t\t\t\t\tlasso_editor.dontlock = true;\n\t\t\t\t} else {\n                    swal({\n                            title:\"Lock Post Fail\",\n                            text: response,\n                            closeOnConfirm: true\n                    });\n                    exitEditor();\n                }\n\t\t\t\t\n\t\t\t} else {\n\t\t\t\talert(\"Error locking the post for editing\");\n\t\t\t\texitEditor();\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t//keep locking periodically\n\t\tif (!lasso_editor.dontlock) {\n\t\t\tlasso_editor.lockIntervalID = window.setInterval(lockPost, 120000);\n\t\t}\n\t\t\n\t\t\n\t\tfunction lockPost() {\n\t\t\tvar data = {\n\t\t\t\taction: 'editus_lock_post',\n\t\t\t\tpostid: lasso_editor.postid\n\t\t\t};\n\t\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\t/*if( response ){\n\t\t\t\t\tif (response!=\"true\") {\n\t\t\t\t\t\talert(response);\n\t\t\t\t\t\texitEditor();\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t} else {\n\t\t\t\t\talert(\"Error locking the post for edit\");\n\t\t\t\t\texitEditor();\n\t\t\t\t}*/\n\t\t\t\t\n\t\t\t});\n\t\t}\n\t\n\t\te.preventDefault();\n\n\t\t// add body class editing\n\t\t$('body').toggleClass('lasso-editing');\n\n\t\t//append editor id to post container\n\t\t$(post_container).prop('id', editor);\n\n\t\t// append toolbar\n\t\t$(toolbar).hide().appendTo('body').fadeIn(300);\n\n\t\t// fade in controls if previous exacped\n\t\t$('.lasso--controls__right').css('opacity',1);\n\n\t    // set edtior to editable\n\t    $('#'+editor).attr('contenteditable',true);\n\n\t    // add settings panel\n\t\t$('body').append(panel);\n\n\t\t// append upload bar to featured image if present\n\t\tif ( $( featImgClass ).length > 0 ) {\n\t\t\tif ( $(lasso_editor.featImgClass).is( \"img\" ) ) {\n\t\t\t\t$(featImgClass).parent().append( uploadControls );\n\t\t\t} else {\n\t\t\t\t$(featImgClass).append( uploadControls );\n\t\t\t}\n\t\t}\n\n\t\t// append contenteditable to title if set\n\t\tif ( $(titleClass).length > 0 ) {\n\t\t\t$(titleClass).attr('contenteditable', true);\n\t\t} else {\n\t\t\t// try one more time with .entry-title\n\t\t\tvar titleClasses = [\".entry-title-primary\",\".entry-title\",\".novella-entry-title\"];\n\t\t\tfor (var i = 0; i < titleClasses.length; i++) {\n\t\t\t\tif ( $(titleClasses[i]).length > 0 ) {\n\t\t\t\t\tlasso_editor.titleClass = titleClass = titleClasses[i];\n\t\t\t\t\t$(titleClass).attr('contenteditable', true);\n\t\t\t\t\tbreak;\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\t\n\t\tlasso_editor.subtitleClass=\"\";\n\t\tvar subtitleClasses = [\".entry-subtitle\",\".novella-entry-subtitle\"];\n\t\tfor (var i = 0; i < subtitleClasses.length; i++) {\n\t\t\tif ( $(subtitleClasses[i]).length > 0 ) {\n\t\t\t\tlasso_editor.subtitleClass = subtitleClasses[i];\n\t\t\t\t$(subtitleClasses[i]).attr('contenteditable', true);\n\t\t\t\tbreak;\n\t\t\t};\n\t\t}\n\n\t\t// if tehre are any scrollnav sections we need to break them open so that we can drag compnents around in them\n\t\t$('.scroll-nav__section').each(function(){\n\t\t\t$(this).children().unwrap();\n\t\t})\n\n\t\t// add an exit editor button\n\t\t$('.lasso--controls__right ').prepend('<a title=\"'+lasso_editor.strings.exiteditor+'\" id=\"lasso--exit\" href=\"#\"></a>');\n\n\t\t// append the toolbar to any components that dont have them\n\t\t// @todo - this likely needs to be changed to a lasso- namespaced item which then needs to be updated in Aesop Story Engine\n\t\t$('.aesop-component').each(function(){\n\n\t\t\t// if there's no toolbar present\n\t\t\tif ( !$('.lasso-component--toolbar').length > 0 ) {\n\n\t\t\t\t// if this is a map then we need to first wrap it so that we can drag the  map around\n\t\t\t\tif ( $(this).hasClass('aesop-map-component') ) {\n\n\t\t\t\t\tvar $this = $(this)\n\n\t\t\t\t\t// so wrap it with a aesop-compoentn aesop-map-component div\n\t\t\t\t\t// @todo - note once a map is inserted it can't be edited after saving again. a user has to delete the existin map and add a new map\n\t\t\t\t\t// to\n\t\t\t\t\t//$this.wrap('<form id=\"lasso--map-form\" class=\"aesop-component aesop-map-component lasso--map-drag-holder\" data-component-type=\"map\" >').before( lassoDragHandle ).after( lassoMapForm );\n\t\t\t\t\t$this.wrap('<div id=\"lasso--map-form\" class=\"aesop-component aesop-map-component lasso--map-drag-holder\" data-component-type=\"map\" >').before( lassoDragHandle );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t$(this).append( lassoDragHandle );\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n        lasso_editor.wrapImg = function () {\n            // find images inserted from within the wordpress backend post editor and\n            // wrap them in a div, then append an edit button for editing the image\n            /*$(\"[class*='wp-image-']\").each(function(){\n                var $this = $(this)\n                if ( !$('.lasso--wpimg-edit').length > 0 ) {\n                    if ( $this.parent().hasClass('wp-caption') ) {\n                        $this.parent().addClass('lasso--wpimg__wrap')\n                    } else {\n                        $this.wrap('<figure data-component-type=\"wpimg\" class=\"lasso--wpimg__wrap lasso-component\">')\n                    }\n                    \n                    \n                    $this.parent().data( $this.data() );\n                    var s =$this.attr('src');\n                    if (s) {\n                       $this.parent().data({componentType:\"wpimg\", img: $this.attr('src')});  \n                    }\n                }\n            });*/\n            \n            //$('.lasso-component:not(.lasso--wpimg__wrap)').each(function(){\n            $('.lasso-component').each(function(){\n\n                var $this = $(this)\n                if ( $(this).find('.lasso-component--controls').length == 0 ) {\n                    if (!lasso_editor.oldWPimg) {\n                        $(this).prepend( lassoDragHandle );\n                        var img = $(this).find('img')[0];\n                        var ctrl = $this.find('.lasso-component--controls')[0];\n                        if ($(img).hasClass('alignnone') || $(img).hasClass('alignleft')) {\n                            $(ctrl).removeClass('editus-center');\n                        }\n                        if ($(img).hasClass('alignright')) {\n                            $(ctrl).removeClass('editus-center');\n                            $(ctrl).addClass('editus-right');\n                        }\n                    } else { \n                        if ( $this.parent().hasClass('wp-caption') ) {\n                            $this.parent().addClass('lasso--wpimg__wrap')\n                        }/* else if ( !$this.parent().hasClass('lasso--wpimg__wrap') ) {\n                            $this.wrap('<figure data-component-type=\"wpimg\" class=\"lasso--wpimg__wrap lasso-component\">')\n                        }*/\n                        $this.parent().prepend(lasso_editor.wpImgEdit);\n                    }\n\n                }\n\n            })\n            \n            //wp image block\n\t\t\t$('.wp-block-image').each(function(){\n                var $this = $(this)\n                if ( $(this).find('.lasso-component--controls').length == 0 ) {\n                    $this.prepend(lasso_editor.wpImgBlockEdit);\n\t\t\t\t\t$this.attr('data-component-type','wpimg-block');\n                }\n\n            })\n            \n            //wp cover block\n            $('.wp-block-cover').each(function(){\n                var $this = $(this)\n                if ( $(this).find('.lasso-component--controls').length == 0 ) {\n                    $this.prepend(lasso_editor.wpImgBlockEdit);\n                    $this.find(\".lasso-clone,.lasso-delete\").remove();\n                    $this.find(\".lasso-component--controls\").width('61px');\n\t\t\t\t\t$this.attr('data-component-type','wpcover-block');\n                }\n\n            })\n        }\n        \n        lasso_editor.wrapImg();\n\n\t\t\n\t\t\n\n\t\t/////////////////\n\t\t///\n\t\t///   CONTENT EDITABLE / TOOLBAR\n\t\t///\n\t\t/// - attributes and tags are set to null to allow any markup and block level items to be passed through\n\t\t///   this means that medium.js is only providing us with a helper API to invoke certain markup and to \n\t\t///   insert HTML. It's important to realize that the_content filter together with wpautop is responsible\n\t\t///   for automatically making new paragraph elements on enter\n\t\t///\n\t\t///////////////////\n\t\tarticle = document.getElementById(editor),\n\t    articleMedium = new Medium({\n\t        element: article,\n\t        mode: Medium.richMode,\n\t        attributes: null,\n\t        tags: null,\n\t        placeholder:lasso_editor.strings.justWrite,\n\t\t    pasteAsText: true,\n\t    \tcssClasses: {\n\t\t\t\teditor: 'lasso-editor',\n\t\t\t\tpasteHook: 'lasso-editor-paste-hook',\n\t\t\t\tplaceholder: 'lasso-editor-placeholder',\n\t\t\t\tclear: 'lasso-editor-clear'\n\t\t\t}\n\t    });\n\t\t\n\t\t$(objectsNonEditable).attr('contenteditable',false);\n\t\t$(objectsNonEditable).attr('readonly',true);\n        \n        // set some figures uneditable\n        $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\n\t\t\n\t\t// remove any additional markup so we dont save it as HTML\n\t\tif (objectsNoSave.length) {\n\t\t    objectsNoSave = objectsNoSave+\",\"+supportedNoSave;\n\t\t} else {\n\t\t\tobjectsNoSave = supportedNoSave;\n\t\t}\n\t\t\n\t\tlasso_editor.objectsNoSave = objectsNoSave;\n\t\t\n\t\tif ($(objectsNonEditable).length || (lasso_editor.showIgnoredItems && ($(objectsNoSave).length)|| $(supportedNoSave).length )) {\n\t\t\tlasso_editor.readOnlyExists = true;\n\t\t} else {\n\t\t\tlasso_editor.readOnlyExists = false;\n\t\t}\n\t\tif (!lasso_editor.showIgnoredItems) {\n\t\t    $(objectsNoSave).remove();\n\t\t    $(supportedNoSave).remove();\n\t\t} else {\n\t\t\t$(objectsNoSave).attr('contenteditable',false);\n\t\t    $(objectsNoSave).attr('readonly',true);\n\t\t}\n\t\t\n\t\t// detect avia editor\n\t\tlasso_editor.aviaEditor = ($('.av_toggle_section,.av_textblock_section').length>0);\n\t\t\n\t\t// set links clickable\n\t\tif (!lasso_editor.linksEditable) {\n\t\t\t$(\"a\").attr('contenteditable',false);\n\t\t}\n\t\t\n\t\tif (lasso_editor.disableEditPost) {\n\t\t\t//set everything uneditable\n\t\t\t$( \"[contenteditable]\" ).attr('contenteditable',false);\n\t\t}\n\t\t\n\t\t// custom fields\n\t\tif (lasso_editor.customFields) {\n\t\t\tvar joined = [];\n\t\t\tfor (var key in lasso_editor.customFields) {\n\t\t\t\tvar imgControls = '<a title=\"Replace Image\" href=\"\" class=\"editus-custom-image-control\" style=\"position:absolute;right:0px;\"><i class=\"lasso-icon-image\" style=\"color: black;font-size: 20px\"></i></a>';\n\t\t\t\tif (typeof(lasso_editor.customFields[key]) == 'object') {\n\t\t\t\t\tvar selector = lasso_editor.customFields[key]['selector'];\n\t\t\t\t\tjoined.push(selector);\n\t\t\t\t\tif (lasso_editor.customFields[key]['imgurl']) {\n\t\t\t\t\t\tif ($(selector).find('.editus-custosm-image-control').length == 0) {\n\t\t\t\t\t\t\t$(selector).parent().parent().append( imgControls );\n\t\t\t\t\t\t\t$(selector).parent().parent().css(\"position\", \"relative\");\n\t\t\t\t\t\t\t$(selector).parent().parent().find('.editus-custom-image-control').mousedown(imgDialog);\n\t\t\t\t\t\t}\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t   joined.push(lasso_editor.customFields[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlasso_editor.cfselector = joined.join(',');\n\t\t\t$(lasso_editor.cfselector).attr('contenteditable',true);\n\t\t\tif (lasso_editor.undeletableExists = ($(lasso_editor.cfselector).length>0)) {\n\t\t\t\t$(lasso_editor.cfselector).addClass('lasso-undeletable');\n\t\t\t}\n\t\t}\n\t\t\n\t\t//$(objectsNonEditable).disableSelection();\n\n\t    // this forces the default new element in content editable to be a paragraph element if\n\t    // it has no previous element to depart from \n\t    // ref http://stackoverflow.com/a/15482748\n\t    document.execCommand('defaultParagraphSeparator', false, 'p');\n\n\t\t// cursor to the beginning\n        if (articleMedium.element.firstChild == null) {\n\t\t\tvar node = document.createElement(\"p\");\n\t\t\tvar textnode = document.createTextNode(\" \");         // Create a text node\n\t\t\tnode.appendChild(textnode);   \n\t\t\tarticleMedium.element.appendChild(node);\n\t\t}\n\t\tarticleMedium.cursor.caretToBeginning(articleMedium.element.firstChild);\n\n\t\tarticle.highlight = function() {\n\t\t\tif (document.activeElement !== article) {\n\n\t\t\t\t//articleMedium.select();\n\t\t\t\tarticle.focus();\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\n\t\t\n\t\tif (lasso_editor.toolbarPopup) {\n            $(lasso_editor.toolbarPopup).hide().appendTo('body');\n        }\n\t\t\n\t\t\n\t\t//color\n\t\tif (lasso_editor.showColor) {\n            var cv = \"#ff0000\";\n\t\t\t// red is the default color\n\t\t\t$( '#lasso-toolbar--color-pick' ).iris();\n\t\t\t$( '#lasso-toolbar--color-pick' ).iris('color', '#f00');\n            $('head').append('<style id=\"editus-colorpick\">#lasso-toolbar--color-pick:before, #lasso-toolbar--color-set:before{color:#ff0000 !important;}</style>');\n\t\t\t\n\t\t\t$(window).mousedown(function() {\n\t\t\t    //Hide the color picker if visible\n\t\t\t\t$(\"#lasso-toolbar--color-pick\").iris('hide');\n\t\t\t});\n\t\t\t\n\t\t\tfunction rgb2hex(rgb) {\n\t\t\t\trgb = rgb.match(/^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$/);\n\t\t\t\tfunction hex(x) {\n\t\t\t\t\treturn (\"0\" + parseInt(x).toString(16)).slice(-2);\n\t\t\t\t}\n\t\t\t\treturn \"#\" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);\n\t\t\t}\n\t\t\tif (!lasso_editor.isMobile) {\n\t\t\t    $(\".iris-picker\").css({position:'absolute', top:-180});\n\t\t\t}\n\t\t\t$(\"#lasso-toolbar--color-pick\").iris({\n\t\t\t\tpalettes: true,\n\t\t\t\tchange: function(event, ui) {\n\t\t\t\t\t// event = standard jQuery event, produced by whichever control was changed.\n\t\t\t\t\t// ui = standard jQuery UI object, with a color member containing a Color.js object\n\n\t\t\t\t\t// change the color\n                    $('style#editus-colorpick').remove();\n                    cv = ui.color.toString();\n                    $('head').append('<style id=\"editus-colorpick\">#lasso-toolbar--color-pick:before, #lasso-toolbar--color-set:before{color:'+cv+' !important;}</style>');\n\n\t\t\t\t}\n\t\t\t});\n            \n\t\t\t$('#lasso-toolbar--color-pick').on('mousedown', function(event) {\t\n\t\t\t\tif (event.target.id == 'lasso-toolbar--color-pick') {\n\t\t\t\t   $(\"#lasso-toolbar--color-pick\").iris('toggle');\n\t\t\t\t}\n                event.stopPropagation();\t\t\t\t\n\t\t\t});\n\t\t\t\n\t\t\t$('#lasso-toolbar--color-set').on('mousedown', function() {\n\t\t\t\t$(\"#lasso-toolbar--color-pick\").iris('hide');\n\t\t\t\tarticleMedium.element.contentEditable = true;\n\t\t\t\t// exit if nothing is selected\n\t\t\t\tif (!lasso_editor.checkSelection(true)) return false;\n\t\t\t\t\n\t\t\t\t//var colorVar = rgb2hex($('#lasso-toolbar--color-pick').css(\"color\"));\n\t\t\t\tarticleMedium.invokeElement('span', { style: 'color:' + cv + ';'});\n\t\t\t\t//unselect\n\t\t\t\tif (window.getSelection) {\n\t\t\t\t  if (window.getSelection().empty) {  // Chrome\n\t\t\t\t\twindow.getSelection().empty();\n\t\t\t\t  } else if (window.getSelection().removeAllRanges) {  // Firefox\n\t\t\t\t\twindow.getSelection().removeAllRanges();\n\t\t\t\t  }\n\t\t\t\t} else if (document.selection) {  // IE?\n\t\t\t\t  document.selection.empty();\n\t\t\t\t}\n                $(\".lasso--text-popup\").hide();\n\t\t\t\tarticleMedium.makeUndoable();\n\t\t\t\treturn false;\n\t\t\t});\n\t\t}\n\n\t\t\n\t\t\n\t\t// color end\n\t\t\n\t\t//alignement\n\t\tif (lasso_editor.showAlignment) {\n\t\t\tfunction alignHelper(align) {\n\t\t\t\tvar focusedElements = articleMedium.html.textElementsAtCaret();\n\t\t\t\tif (focusedElements) {\n\t\t\t\t\tfor (i = 0; i < focusedElements.length; i++) {\n\t\t\t\t\t  focusedElements[i].style.textAlign = align;\n\t\t\t\t\t}\t\t\t\n\t\t\t\t}\n\t\t\t\tarticleMedium.makeUndoable();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$('#lasso-toolbar--right-align').mousedown(function() {\n\t\t\t\treturn alignHelper(\"right\");\n\t\t\t});\n\t\t\t\n\t\t\t$('#lasso-toolbar--left-align').mousedown(function() {\n\t\t\t\treturn alignHelper(\"left\");\n\t\t\t});\n\t\t\t\n\t\t\t$('#lasso-toolbar--center-align').mousedown(function() {\n\t\t\t\treturn alignHelper(\"center\");\n\t\t\t});\n\t\t}\n\t\t\n\t\t//end alignment\n\t\t\n\t\t$('#lasso-toolbar--ul').mousedown(function() {\n\t\t\t\tmakeList(\"ul\");\n\t\t});\n\t\t$('#lasso-toolbar--ol').mousedown(function() {\n\t\t\t\tmakeList(\"ol\");\n\t\t});\n\t\t\n\t\tfunction makeList(list_type) {\n\t\t\tvar list = $(\"<\"+list_type+\"/>\");\n\t\t\tvar focusedElements = articleMedium.html.textElementsAtCaret();\n\t\t\tif (focusedElements) {\n\t\t\t\t\tfor (i = 0; i < focusedElements.length; i++) {\n\t\t\t\t\t  list.append(\"<li>\" + focusedElements[i].innerHTML + \"</li>\");\n\t\t\t\t\t  if (i>0) {\n\t\t\t\t\t\t  focusedElements[i].parentNode.removeChild(focusedElements[i]); \n\t\t\t\t\t  }\n\t\t\t\t\t}\t\n\t\t\t\t\t$(focusedElements[0]).replaceWith(list[0]);\t\t\t\t\n\t\t\t}\n\t\t\t\t\n\t\t\tarticleMedium.makeUndoable();\n\t\t\tarticle.highlight();\n\t\t\t//setCursor($(focusedElements[0]));\n\t\t\t//articleMedium.cursor.caretToBeginning(articleMedium.element.firstChild);\n\t\t}\n\t\t\n\t\t\t\tif (!lasso_editor.disableEditSC) {\n\t\t\tprocessShortcodes();\n\t\t}\n\t\t\n\t\tfunction processShortcodes()\n\t\t{\n\t\t\t$(article).children().filter(function(){\n\t\t\t\treturn this.innerHTML.includes(\"EDITUS_OTHER_SHORTCODE_START\");\n\t\t\t}).each(function(i, e){\n\t\t\t\tvar re = /<!--EDITUS_OTHER_SHORTCODE_START\\|\\[(.*)\\]-->/g ;\n\t\t\t    var cont = re.exec(this.innerHTML);\n\t\t\t\t\t\t\t\n\t\t\t\t$(this).next().append( '<div class=\"editus_shortcode\" contenteditable=\"false\">'+lasso_editor.strings.editShortcode+'</div>' );\n\t\t\t\t\n\t\t\t\t$(this).next().addClass(\"editus_shortcode_p\");\n\t\t\t\t\n\t\t\t\tif (cont) $(this).next().find('.editus_shortcode')[0].dataset.shortcode = cont[1];\n\t\t\t});\n\t\t}\n\t\t\n\t\t$(document).on('click','.editus_shortcode', function(e){\n\t\t\tvar $this = $(this);\n\t\t\n\t\t\tvar s = $(window).scrollTop();\n\t\t\tswal({\n\t\t\t\ttitle: lasso_editor.strings.editShortcode,\n\t\t\t\ttext: \"<textarea id='shortcode_edit' name='shortcode'>\"+ this.dataset.shortcode +\"</textarea>\",\n\t\t\t\tshowCancelButton: true,\n\t\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\t\tconfirmButtonText: \"Modify\",\n\t\t\t\tcloseOnConfirm: true,\n\t\t\t\tobj: this\n\t\t\t},\n\t\t\tfunction(){\n\t\t\t\tvar val = $('textarea#shortcode_edit').val();\n\t\t\t\tvar data = {\n\t\t\t\t\taction: 'editus_do_shortcode',\n\t\t\t\t\tcode: val,\n\t\t\t\t\tID: lasso_editor.postid\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\t\t\trestoreSelection(window.selRange);\n\t\t\t\t\t\tif( response && response.includes(\"EDITUS_OTHER_SHORTCODE_END\")){\n\t\t\t\t\t\t\t$this.parent().prev().remove();\n\t\t\t\t\t\t\t//$this.next().remove();\n\t\t\t\t\t\t\t$this.parent().replaceWith( response.replace(\"<!--EDITUS_OTHER_SHORTCODE_END-->\",\"\") );\n\t\t\t\t\t\t\tprocessShortcodes();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\talert(\"Shortcode processing failed\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$(window).scrollTop(s);\n\t\t\t\t});\t\t\t\t\n\t\t\t});\n\t\t})\n\t\t\n\t\tfunction taghelper(tag) {\n\t\t\tarticleMedium.element.contentEditable = true;\n\t\t\tarticle.highlight();\n\t\t    articleMedium.invokeElement(tag);\n\t\t\tarticleMedium.makeUndoable();\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\t$('[id=\"lasso-toolbar--bold\"]').on('mousedown', function(e) {\n\t\t\treturn taghelper(lasso_editor.boldTag);\n\t\t});\n\t\t\n        $('[id=\"lasso-toolbar--underline\"]').on('mousedown', function(e) {\n\t\t\treturn taghelper('u');\n\t\t});\n\n        $('[id=\"lasso-toolbar--italic\"]').on('mousedown', function(e) {\n\t\t\treturn taghelper(lasso_editor.iTag);\n\t\t});\n        $('[id=\"lasso-toolbar--strike\"]').on('mousedown', function(e) {\n\t\t\treturn taghelper('strike');\n\t\t});\n        \n        $(document).on('keydown', function ( e ) {\n            // remove formatting when the use pushes ctrl+space\n            if ((e.metaKey || e.ctrlKey) && ( e.which == 32) ) {\n                document.execCommand('removeFormat');\n                document.execCommand('formatBlock', false, 'p')\n            }\n        });\n\n\t\tfunction heading_helper(heading) {\n\t\t\tarticleMedium.element.contentEditable = true;\n\t\t\tarticle.highlight();\n\n\t\t\tarticleMedium.invokeElement(heading);\n\t\t\t//reg = '/<h2 class=\"lasso-h2\">([^<>]*)<\\/h2>/i';\n\t\t\treg = new RegExp('<'+heading+' class=\"lasso-'+heading+'\">([^<>]*)<\\\\/'+heading+'>', 'i');;\n\t\t\t\t// the following code breaks the paragraphs before and after heading\n\t\t\t$(articleMedium.element).html(function(index,html){\n\t\t\t\t//return html.replace(/<h2 class=\"lasso-h2\">([^<>]*)<\\/h2>/i,'</p><'+heading+'>$1</'+heading+'><p>');\n\t\t\t\treturn html.replace(reg,'</p><'+heading+'>$1</'+heading+'><p>');\n\t\t\t});\n\n\t\t\tarticleMedium.makeUndoable();\n\t\t\treturn false;\n\t\t}\n\n\t\t\n\t\tdocument.getElementById('lasso-toolbar--link').onmousedown = function() {\n\t\t\t\t var article = document.getElementById(lasso_editor.editor);\n    \t\t\tarticle.highlight();\n    \t\t\twindow.selRange = saveSelection();\n\t\t\t};\n\t\tdocument.getElementById('lasso-toolbar--html').onmousedown = function() {\n\t\t\t\t var article = document.getElementById(lasso_editor.editor);\n    \t\t\tarticle.highlight();\n    \t\t\twindow.selRange = saveSelection();\n    \t\t\tif( typeof window.selRange === 'undefined' || null == window.selRange ) {\n    \t\t\t\twindow.selRange = saveSelection();\n    \t\t\t}\n\t\t\t};\n\n\t\tif ( toolbarHeading ) {\n\t\t\tdocument.getElementById('lasso-toolbar--h2').onmousedown = function() {\n\t\t\t\treturn heading_helper('h2');\n\t\t\t};\n\n\t\t\tdocument.getElementById('lasso-toolbar--h3').onmousedown = function() {\n\t\t\t\treturn heading_helper('h3');\n\t\t\t};\n\t\t}\n\t\tif ( lasso_editor.toolbarHeadingsH4 ) {\n\t\t\tdocument.getElementById('lasso-toolbar--h4').onmousedown = function() {\n\t\t\t\treturn heading_helper('h4');\n\t\t\t};\n\t\t\tdocument.getElementById('lasso-toolbar--h5').onmousedown = function() {\n\t\t\t\treturn heading_helper('h5');\n\t\t\t};\n\t\t\tdocument.getElementById('lasso-toolbar--h6').onmousedown = function() {\n\t\t\t\treturn heading_helper('h6');\n\t\t\t};\n\t\t}\n\n\t\t\n\t\tdocument.getElementById('lasso-toolbar--link__create').onmousedown = function() {\n\t\t\tarticleMedium.element.contentEditable = true;\n\t\t    article.highlight();\n\t\t    restoreSelection(window.selRange);\n\t\t\tvar html = '<a class=\"lasso-link\" contenteditable=\"false\" ';\n\t\t\t\n\t\t\tif (!lasso_editor.linkEditable) { \n\t\t\t\thtml = '<a class=\"lasso-link\" ';\n\t\t\t}\n\n\t\t\tvar target = $('#lasso-toolbar--link__inner').text();\n            \n            if (target==\"\") {\n                html = window.selRange.toString();\n            } else {\n                if (lasso_editor.prefixHTTP && !target.match(/http/i)){\n                    target = 'http://'+target;\n                }\n                if ($('#aesop-toolbar--link_newtab').is(':checked')) {\n                    html = html+' target=\"_blank\" href=\"'+ target +'\">'+window.selRange+'</a>';\n                } else {\n                    html = html+' href=\"'+ target +'\">'+window.selRange+'</a>';\n                }\n            }\n            articleMedium.insertHtml(html);\n            var container = window.selRange.startContainer.parentNode,\n                containerTag = container.localName;\n\n            if ( containerTag == 'a' ) {\n                var containerObject = $(window.selRange.startContainer.parentNode);\n                containerObject.replaceWith(containerObject[0].innerHTML);\n            }\n            \n\t\t    window.selRange = null;\n\n\t\t    // close modal drag\n        \t$('#lasso-toolbar--link').removeClass('link--drop-up link--drop-down');\n\t\t\t\n\t\t\tarticleMedium.makeUndoable();\n\n\t\t    return false;\n\t\t};\n\t\t\n\t\t// process shortcode using AJAX service and insert the result\n\t\tfunction do_shortcode_ajax(content)\n\t\t{\n\t\t\tvar data = {\n\t\t\t\t\taction: 'editus_do_shortcode',\n\t\t\t\t\tcode: content,\n\t\t\t\t\tID: lasso_editor.postid\n\t\t\t};\n\t\t\t\n\t\t\t\t\t\t\t\n\t\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n                    restoreSelection(window.selRange);\n\t\t\t\t\tif( response ){\n\t\t\t\t\t\treturn insert_html(response);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn insert_html(content);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t\n\t\t\n\t\tfunction insert_html(htmlContent, contentishtml) {\t\t\n\t\t\tvar html = contentishtml; \n\t\t\tif (contentishtml == undefined) {\n\t\t\t\thtml = true;\n\t\t\t}\n\t\t\ttry  {\n\t\t\t\tvar container = window.selRange.startContainer;\n\t\t\t\tvar containerTag = container.localName;\n\t\t\t\tvar containerObject = $(container);\n\t\t\t\tvar htmlCopy = htmlContent;\n\t\t\t\tif (html) {\n                    //htmlContent is html, not an object\n\t\t\t\t\thtmlContent = $(htmlContent);\n\t\t\t\t\thtmlContent.attr('contenteditable','true');\n\t\t\t\t} else {\n\t\t\t\t\thtmlCopy = htmlContent[0].outerHTML;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// handle 3 specific scenarios dealing with <p>'s\n\t\t\t\t// note: might need climb up dom tree depending on nesting use case\n\t\t\t\tif (containerTag == 'p') {\n\t\t\t\t\tvar innerText = container.innerText.replace(/(\\r\\n|\\n|\\r)/gm,\"\");\n\t\t\t\t\tif (!html) {\t\n\t\t\t\t\t\t// currently we come here only if when inserting components\n                        \t\t\t\t\t\n\t\t\t\t\t\t/*htmlContent.insertAfter( containerObject );\n\t\t\t\t\t\tif (innerText ==\"\") {\n\t\t\t\t\t\t\t// empty p tag\n\t\t\t\t\t\t\tcontainerObject.remove();\n\t\t\t\t\t\t}*/\n\t\t\t\t\t\t// decided to change the behavior Now the component is inserted before the empty paragraph\t\n\t\t\t\t\t\thtmlContent.insertBefore( containerObject );\n\t\t\t\t\t\tif (innerText ==\"\") {\n\t\t\t\t\t\t\tarticleMedium.cursor.caretToBeginning(container);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tarticleMedium.insertHtml( htmlCopy );\n\t\t\t\t\t}\n\t\t\t\t\t\n\n\t\t\t\t} else {\n\t\t\t\t\t// within a p tag\n\t\t\t\t\tcontainer = container.parentNode;\n\t\t\t\t\tcontainerTag = container.localName;\n\n\t\t\t\t\tif( containerTag == 'p') {\n\t\t\t\t\t\t//if (string.indexOf(<) !== -1;\n\t\t\t\t\t\t//htmlContent.insertAfter( containerObject );\n\t\t\t\t\t\tarticleMedium.insertHtml( htmlCopy );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// let's just go ahead and paste it on location\n\t\t\t\t\t\tarticleMedium.insertHtml( '<p>'+htmlCopy+'</p>' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t//window.selRange = null;\n\n\t\t\t\t// close modal drag\n\t\t\t\t$('#lasso-toolbar--html').removeClass('html--drop-up');\n\t\t\t\t\n\t\t\t\tarticleMedium.makeUndoable();\n\t\t\t\tlasso_editor.addComponentButton();\n\n\t\t\t\treturn htmlContent;\n\t\t\t} catch (e) {\n\t\t\t\talert(e.message);\n\t\t\t\t\n\t\t\t}\n\t\t}\n\t\t\n\t\tfunction isURL(str) {\n\t\t\tvar pattern = new RegExp('^(https?:\\\\/\\\\/)?'+ // protocol\n\t\t\t  '((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|'+ // domain name and extension\n\t\t\t  '((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))'+ // OR ip (v4) address\n\t\t\t  '(\\\\:\\\\d+)?'+ // port\n\t\t\t  '(\\\\/[-a-z\\\\d%@_.~+&:]*)*'+ // path\n\t\t\t  '(\\\\?[;&a-z\\\\d%@_.,~+&:=-]*)?'+ // query string\n\t\t\t  '(\\\\#[-a-z\\\\d_]*)?$','i'); // fragment locator\n\t\t\t  return pattern.test(str);\n\t\t}\n\t\t\n\t\tdocument.getElementById('lasso-toolbar--html__insert').onmousedown = function() {\n\t\t    articleMedium.element.contentEditable = true;\n\t\t    restoreSelection(window.selRange);\n\n\n\t\t\tvar htmlContent = $('#lasso-toolbar--html__inner').text();\n\t\t\tif (htmlContent.indexOf(\"]\") != -1) {\n\t\t\t\tdo_shortcode_ajax(htmlContent);\n\t\t\t\treturn false;\n\t\t\t} else if (isURL(htmlContent)) {\n\t\t\t\tdo_shortcode_ajax(\"[embed]\"+htmlContent+\"[/embed]\");\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\treturn insert_html(htmlContent);\n\t\t\t}\n\t\t};\n\n\t\tif (lasso_editor.enableAutoSave) {\n\t\t\tlasso_editor.intervalID = window.setInterval(autoSave, 60000);\n\t\t}\n\t\t\n\t\tfunction autoSave() {\n\t\t\tif (localStorage.getItem( 'lasso_backup_'+postid ) || lasso_editor.dirtyByComponent) \n\t\t\t{\n\t\t\t\t$('.lasso--controls__right #lasso--save').trigger('click');\n\t\t\t}\n\t\t}\n\t\t\n\t\tfunction clearTimer()\n\t\t{\n\t\t\tif (lasso_editor.intervalID) {\n\t\t\t     window.clearInterval(lasso_editor.intervalID);\n\t\t\t\t lasso_editor.intervalID = 0;\n\t\t\t}\n\t\t\tif (lasso_editor.lockIntervalID) {\n\t\t\t     window.clearInterval(lasso_editor.lockIntervalID);\n\t\t\t\t lasso_editor.lockIntervalID = 0;\n\t\t\t\t //unlock post\n\t\t\t\t var data = {\n\t\t\t\t\taction: 'editus_unlock_post',\n\t\t\t\t\tpostid: lasso_editor.postid\n\t\t\t\t};\n\t\t\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\t\t\t\t\t\n\t\t\t\t});\t\t\t \n\t\t\t}\n\t\t}\n\t\t\n\t\t/////////////////\n\t\t/// EXIT EDITOR\n\t\t///////////////////\n\t\tfunction exitEditor(){\n\t\t\tclearTimer();\n\n\t\t\tif ($('body').hasClass('lasso-sidebar-open')) {\n\t\t\t\t//e.preventDefault();\n\t\t\t\t$('body').removeClass('lasso-sidebar-open');\n\t\t\t\t$('#lasso--component__settings').perfectScrollbar('destroy');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t$('body').removeClass('lasso-sidebar-open lasso-editing');\n\n\t\t\t$('.lasso--toolbar_wrap,#lasso--sidebar,#lasso--featImgControls,.lasso-component--controls,#lasso--exit,#lasso-side-comp-button,.lasso--text-popup,.editus_shortcode').fadeOut().remove();\n\n\n\t\t\t$('#lasso--edit').css('opacity',1);\n\t\t\t$('.lasso--controls__right').css('opacity',0);\n\t\t\t$(post_container).attr('id','');\n\n\t\t\t// unwrap wp images\n\t\t\t/*$('.lasso--wpimg__wrap').each(function(){\n\t\t\t\t$(this).children().unwrap()\n\t\t\t});*/\n\n\t\t\t// unwrap map from hits drag holder\n\t\t\t$('#lasso--map-form').each(function(){\n\n\t\t\t\tvar $this = $(this)\n\n\t\t\t\t$this.find('.lasso-component--controls, .lasso--map-form__footer ').remove()\n\n\t\t\t\t$this.children().unwrap()\n\t\t\t});\n\n\t\t\t$(titleClass).attr('contenteditable', false);\n\n\t\t\t$(articleMedium.element).find(\"*\").removeAttr('contenteditable');\n\t\t\tarticleMedium.destroy();\n\t\t\t\n\t\t\t// ways to inject codes into the exitEditor\n\t\t\tif (lasso_editor.exitEditorHookArray) {\n\t\t\t\t$(lasso_editor.exitEditorHookArray).each(function(key, val){\n\t\t\t\t\tval();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tlasso_editor.exitEditor = exitEditor;\n\t\t\n\t\t// on escape key exit\n\t\t$(document).keyup(function(e) {\n\n\t\t\tif ( 27 == e.keyCode ) {\n\t\t\t\tif ($('#lasso-toolbar--link').hasClass('link--drop-up')) {\n\t\t\t\t\t$('#lasso-toolbar--link').removeClass('link--drop-up');\n                } else if ($('#lasso-toolbar--html').hasClass('html--drop-up')) {\n\t\t\t\t\t$('#lasso-toolbar--html').removeClass('html--drop-up');\n\t\t\t\t} else {\n\t\t\t\t   exitEditor()\n\t\t\t\t}\n\t\t\t}\n\n\t\t});\n\t\t// on utility class exit\n\t\t//$('#lasso--exit').live('click',function(e){\n\t\tjQuery(document).on('click','#lasso--exit', function(e){\n\t\t\te.preventDefault();\n\t\t\t//previously we just called exitEditor(), now the following reloads the page if there is an unsaved change\n\t\t\tif (articleMedium.dirty) {\n\t\t\t\tclearTimer();\n\t\t\t   location.reload();\n\t\t\t} else {\n\t\t\t  exitEditor();\n\t\t\t}\n\t\t})\n\n\t\t// on control s save\n\t\t$(document).keydown(function(e) {\n\t\t    if ((e.which == '115' || e.which == '83' ) && (e.ctrlKey || e.metaKey)){\n\t\t        e.preventDefault();\n\t\t        \t\n\t\t        $('.lasso-editing #lasso--save').trigger('click')\n\n\t\t        return false;\n\t\t    }\n\t\t    return true;\n\t\t});\n\n\t\t///////////\n\t\t// INITIALIZE TIMELINE\n\t\t//////////\n        lasso_editor.timelineGoTime = function(){\n\t\t\t// if there's no toolbar present\n\t\t\tif ( !$('.aesop-timeline').length > 0 ) {\n\t\t\t\t$('body').append('<div class=\"aesop-timeline\"></div>').addClass('has-timeline');\n\t\t\t}\n\n\n\t\t\tif ( !$('.aesop-timeline .scroll-nav').length > 0 ) {\n\n\t\t\t\t$('.aesop-entry-content').scrollNav({\n\t\t\t\t    sections: '.aesop-timeline-stop',\n\t\t\t\t    arrowKeys: true,\n\t\t\t\t    insertTarget: '.aesop-timeline',\n\t\t\t\t    insertLocation: 'appendTo',\n\t\t\t\t    showTopLink: false,\n\t\t\t\t    showHeadline: false,\n\t\t\t\t    scrollOffset: 0,\n\t\t\t\t});\n\n\t\t\t\t$('.aesop-timeline-stop').each(function(){\n\t\t\t\t\t$(this).append( lassoDragHandle );\n\t\t\t\t});\n\n\t\t\t}\n\n\t\t\t$('.aesop-timeline-stop').each(function(){\n\t\t\t\t\tvar label = $(this).attr('data-title');\n\t\t\t\t\t$(this).text(label);\n                if ( $(this).find('.lasso-component--controls').length == 0 ) {\n                    $(this).append( lassoDragHandle );\n                }\n\n\t\t\t});\n\t\t}\n\n\t\t///////////\n\t\t// INITIALIZE VIDEO\n\t\t///////////\n\t\tvar videoGoTime = function(){\n\t\t\t$('.aesop-video-component').fitVids()\n\t\t}\n\n\t\tvar start_point \t= mapStart ? mapStart : [29.76, -95.38]\n\t\t, \tstart_zoom \t\t= mapZoom ? mapZoom : 12\n\t\t, \tmapTileProvider = lasso_editor.mapTileProvider;\n\n\t\t///////////\n\t\t// INITIALIZE MAPS\n\t\t///////////\n\t\tvar mapsGoTime = function(){\n\n\t\t\tvar lat = start_point.lat ? start_point.lat : 29.76\n\t\t\t,\tlng = start_point.lng ? start_point.lng : -95.38;\n\n\t\t\tvar map = L.map('aesop-map-component',{\n\t\t\t\tscrollWheelZoom: false,\n\t\t\t\tzoom: start_zoom,\n\t\t\t\tcenter: [lat, lng]\n\t\t\t});\n\n\t\t\tsetMapCenter(start_point[0],start_point[1]);\n\n\t\t\tjQuery('#lasso-map-address').geocomplete().bind('geocode:result', function(event, result){\n\t\t\t\tvar lat = result.geometry.location.k;\n\t\t\t\tvar lng = result.geometry.location.B;\n\t\t\t\tmap.panTo(new L.LatLng(lat,lng));\n\t\t\t\tsetMapCenter(lat,lng);\n\t\t\t});\n\n\t\t\tL.tileLayer(mapTileProvider, {\n\t\t\t\tmaxZoom: 20//start_zoom\n\t\t\t}).addTo(map);\n\n\t\t\tmapLocations.forEach(function(location) {\n\t\t\t\tcreateMapMarker([location['lat'],location['lng']],location['title']).addTo(map);\n\t\t\t\tcreateMarkerField( marker._leaflet_id, encodeMarkerData(location['lat'], location['lng'], location['title']) );\n\t\t\t});\n\n\t\t\t// adding a new marker\n\t\t\tmap.on('click', onMapClick);\n\t\t\tmap.on('dragend', onMapDrag);\n\t\t\tmap.on('zoomend', onMapZoom);\n\n\t\t\tfunction setMapCenter(k, B) {\n\t\t\t\tvar ldata = encodeLocationData(k,B);\n\t\t\t\tjQuery('input[name=\"ase-map-component-start-point\"]').remove();\n\t\t\t\tjQuery('.lasso--map-form__footer').append('<input type=\"hidden\" name=\"ase-map-component-start-point\" data-ase=\"map\" value=\"' + ldata + '\">');\n\t\t\t\tjQuery('#lasso-map-address').val(k + ', ' + B);\n\t\t\t}\n\n\t\t\tfunction setMapZoom(z) {\n\t\t\t\tjQuery('input[name=\"ase-map-component-zoom\"]').remove();\n\t\t\t\tjQuery('.lasso--map-form__footer').append('<input type=\"hidden\" name=\"ase-map-component-zoom\" data-ase=\"map\" value=\"' + z + '\">');\n\t\t\t}\n\n\t\t\tfunction onMarkerDrag(e) {\n\t\t\t\tupdateMarkerField(e.target);\n\t\t\t}\n\n\t\t\tfunction onMapDrag(e) {\n\t\t\t\tvar mapCenter = e.target.getCenter()\n\t\t\t\tsetMapCenter(rnd(mapCenter.lat),rnd(mapCenter.lng));\n\t\t\t}\n\n\t\t\tfunction onMapZoom(e) {\n\t\t\t\tsetMapZoom(e.target.getZoom());\n\t\t\t}\n\n\t\t\tfunction rnd(n) {\n\t\t\t\treturn Math.round(n * 100) / 100\n\t\t\t}\n\n\t\t\tfunction onMapClick(e) {\n\n\t\t\t    var geojsonFeature = {\n\n\t\t\t        \"type\": \"Feature\",\n\t\t\t        \"properties\": {},\n\t\t\t        \"geometry\": {\n\t\t\t                \"type\": \"Point\",\n\t\t\t                \"coordinates\": [e.latlng.lat, e.latlng.lng]\n\t\t\t        }\n\t\t\t    }\n\n\t\t\t    var marker;\n\n\t\t\t    L.geoJson(geojsonFeature, {\n\n\t\t\t        pointToLayer: function(feature, latlng){\n\n\t\t\t            marker = L.marker(e.latlng, {\n\n\t\t\t                title: 'Resource Location',\n\t\t\t                alt: 'Resource Location',\n\t\t\t                riseOnHover: true,\n\t\t\t                draggable: true,\n\n\t\t\t            }).bindPopup(\"\\\n\t\t\t            \t<input type='text' name='ase_marker_text[]' value='Location Title'>\\\n\t\t\t            \t<a class='marker-update-button dashicons dashicons-yes'/></a>\\\n\t\t\t            \t<a class='marker-delete-button dashicons dashicons-trash'/></a>\\\n\t\t\t            \t\");\n\n\t\t\t            marker.on('popupopen', onPopupOpen);\n\t\t\t            marker.on('dragend', onMarkerDrag);\n\n\t\t\t            return marker;\n\t\t\t        }\n\t\t\t    }).addTo(map);\n\n\t\t\t   \tcreateMarkerField( marker._leaflet_id, encodeMarkerData(e.latlng.lat, e.latlng.lng, 'Location Title') );\n\n\t\t\t}\n\n\t\t\t// open popup\n\t\t\tfunction onPopupOpen() {\n\n\t\t\t    var tempMarker = this;\n\n\t\t\t    // To remove marker on click of delete button in the popup of marker\n\t\t\t    jQuery('.marker-delete-button:visible').click(function () {\n\t\t\t    \tjQuery('input[data-marker=\"' + tempMarker._leaflet_id + '\"]').remove();\n\t\t\t      \tmap.removeLayer(tempMarker);\n\t\t\t    });\n\n\t\t\t    // Update the title of the location\n\t\t\t    jQuery('.marker-update-button:visible').click(function (t) {\n\t\t\t    \tvar title = t.target.previousElementSibling.value;\n\t\t\t    \tvar tdata = encodeMarkerData(tempMarker._latlng.lat, tempMarker._latlng.lng, title);\n\t\t\t    \tjQuery('input[data-marker=\"' + tempMarker._leaflet_id + '\"]').val(tdata);\n\t\t\t    \ttempMarker.options.title = title;\n\t\t\t    \ttempMarker.closePopup();\n\t\t\t    \ttempMarker.bindPopup(\"\\\n\t\t\t\t            \t<input type='text' name='ase_marker_text[]' value='\" + title + \"'>\\\n\t\t\t\t            \t<a class='marker-update-button dashicons dashicons-yes'/></a>\\\n\t\t\t\t            \t<a class='marker-delete-button dashicons dashicons-trash'/></a>\\\n\t\t\t\t            \t\");\n\t\t\t    });\n\t\t\t}\n\n\t\t\t// create map marker\n\t\t\tfunction createMapMarker(latlng, title) {\n\t            marker = L.marker(latlng, {\n\t              \ttitle: title,\n\t              \talt: title,\n\t              \triseOnHover: true,\n\t              \tdraggable: true,\n\t            }).bindPopup(\"\\\n\t            \t<input type='text' name='ase_marker_text[]' value='\" + title + \"'>\\\n\t            \t<a class='marker-update-button dashicons dashicons-yes'/></a>\\\n\t            \t<a class='marker-delete-button dashicons dashicons-trash'/></a>\\\n\t            \t\");\n\t            marker.on('popupopen', onPopupOpen);\n\t            marker.on('dragend', onMarkerDrag);\n\t            return marker;\n\t\t\t}\n\n\t\t\tfunction getAllMarkers() {\n\t\t\t    var allMarkersObjArray = []; // for marker objects\n\t\t\t    var allMarkersGeoJsonArray = []; // for readable geoJson markers\n\t\t\t    jQuery.each(map._layers, function (ml) {\n\t\t\t        if (map._layers[ml].feature) {\n\t\t\t          \tallMarkersObjArray.push(this)\n\t\t\t          \tallMarkersGeoJsonArray.push(JSON.stringify(this.toGeoJSON()))\n\t\t\t        }\n\t\t\t    })\n\t\t\t}\n\n\t\t\t// let's create a hidden form element for the marker\n\t\t\tfunction createMarkerField(mid, mdata) {\n\t\t\t  \tjQuery('.lasso--map-form__footer').append('<input type=\"hidden\" name=\"ase-map-component-locations[]\" data-ase=\"map\" data-marker=\"' + mid + '\" value=\"' + mdata + '\">');\n\t\t\t}\n\n\t\t\tfunction updateMarkerField(m) {\n\t\t\t\tvar tdata = encodeMarkerData(m._latlng.lat, m._latlng.lng, m.options.title);\n\t\t\t\tjQuery('input[data-marker=\"' + m._leaflet_id + '\"]').val(tdata);\n\t\t\t}\n\n\t\t\t// encode the information into a string\n\t\t\tfunction encodeMarkerData(mlat, mlng, mtitle) {\n\t\t\t\treturn encodeURIComponent(JSON.stringify({lat: mlat, lng: mlng, title: mtitle}));\n\t\t\t}\n\n\t\t\t// encode location into a string\n\t\t\tfunction encodeLocationData(mlat, mlng) {\n\t\t\t\treturn encodeURIComponent(JSON.stringify({lat: mlat, lng: mlng}));\n\t\t\t}\n\n\t\t\t// decode the information\n\t\t\tfunction decodeMarkerData(mdata) {\n\t\t\t\treturn decodeURIComponent(JSON.parse(mdata));\n\t\t\t}\n\t\t}\n        \n        // the code to enable map editing after reload.\n        if ($( \".aesop-map-component\" ).length) {\n            $( \".aesop-map-component\" ).replaceWith(setComponent(\"map\"));\n            mapsGoTime();\n        }\n\n\t\tfunction setComponent(type) {\n\t\t\t// if an image is dragged in\n\t\t\tvar comp =\"\";\n            if (!components[type] || !components[type]['content']) return null;\n\n\t\t\tif ( 'wpimg' == type && lasso_editor.oldWPimg) {\n\t\t\t\tcomp = $(components[type]['content']).prepend( wpImgEdit );\n\t\t\t// else it's likely an aesop component\n\t\t\t} else if ( 'htmlparagraph' != type && 'htmltable' != type) {\n\t\t\t\tcomp = $(components[type]['content'])\n\t\t\t\t\t\t\t.prepend( lassoDragHandle )\n\t\t\t\t\t\t\t.attr({\n\t\t\t\t\t\t\t\t'data-component-type': type\n\t\t\t\t\t\t\t});\n\t\t\t} else {\n                comp = $(components[type]['content']);\n            }\n\t\t\treturn comp;\n\t\t}\n\t\t\n\t\tfunction postComponent(comp,type) {\n            // set some figures to uneditable\n            $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\t\t\t// TODO: if a stock wordpress image is dragged in\t\t\t\n\n\t\t\tif ('timeline_stop' == type ) { lasso_editor.timelineGoTime() }\n\n\t\t\tif ('video' == type ) { videoGoTime() }\n\t\t\t$('#lasso-side-comp-button').remove();\n            if ( 'map' == type ) { \n                mapsGoTime(); \n            } else {\n                $(comp).find('.lasso-settings').trigger('click');\n            }\n\t\t}\n\t\t\n\t\t\t\t\n\t\tfunction  imgDialog( ){\n\t\t\tvar that = this;\n\t\t    // Create the media frame.\n\t\t    var lasso_file_frame = wp.media.frames.file_frame = wp.media({\n\t\t      \ttitle: 'Select Image',\n\t\t      \tbutton: {\n\t\t        \ttext: 'Insert Image',\n\t\t      \t},\n\t\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t\t    });\n\n\t\t    // When an image is selected, run a callback.\n\t\t    lasso_file_frame.on( 'select', function() {\n\t\t      \tvar attachment = lasso_file_frame.state().get('selection').first().toJSON();\n\t\t\t\t$(that).parent().data('imgid',''+attachment.id);\n\t\t\t\tif ($(that).parent().find('img').length > 0) {\n\t\t\t\t\t$(that).parent().find('img').attr('src', attachment.url );\n\t\t\t\t} else {i\n\t\t\t\t\t$(that).parent().css({\n\t\t\t\t  \t\t'background-image': 'url('+ attachment.url +')'\n\t\t\t\t  \t});\n\t\t\t\t}\n                // set some figures to uneditable\n                $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\n\t\t    });\n\n\t\t    // Finally, open the modal\n\t\t\tlasso_file_frame.open();\n\t\t};\n\n\t\t/////////////////\n\t\t/// DRAG DROP\n\t\t///////////////////\n\t\t// recent change: when a new component is dropped, the setting window is opened automatically\n\t\t$('#'+editor).sortable({\n\t\t\topacity: 0.65,\n\t\t\tplaceholder:'lasso-drop-zone',\n\t\t\thandle: '.lasso-drag',\n            cursor:'move',\n            tolerance:'pointer',\n            refreshPositions: true,\n            helper: function( e, ui ) {\n\n\t\t    \t// get the curent target and add the type class to the drag event\n\t\t\t\tvar item = ui['context'],\n\t\t\t\t\ttype = $(item).attr('data-component-type');\n\n            \treturn $('<div class=\"lasso-drag-holder lasso-toolbar--component__'+type+'\"></div>');\n            },\n        \tbeforeStop: function (event, ui) { draggedItem = ui.item },\n            receive: function (event,ui) {\n\n            \t// close modal drag\n            \t$('#lasso-toolbar--components').removeClass('toolbar--drop-up');\n\n\t\t\t\tarticleMedium.makeUndoable();\n            \t// get the item and type\n\t\t\t\tvar item = draggedItem['context'];\n                if (!item) item = draggedItem;\n\t\t\t\tvar type = $(item).attr('data-type');\n\t\t\t\t// item2 will be the content tthat gets inserted. It also has edit controls\n                \n\n\t\t\t\t// if coming from draggable replace with our content and prepend toolbar\n\t\t\t\tif ( origin == 'draggable' ) {\n\t\t\t\t\t// check if it's inserted at the end\n\t\t\t\t\tvar newIndex = $(this).data(\"ui-sortable\").currentItem.index();\n\t\t\t\t    var sortable_len = $(this).data(\"ui-sortable\").items.length;\n\t\t\t\t\tvar last = false;\n\t\t\t\t\tif (newIndex>= (sortable_len-1)) {\n\t\t\t\t\t\tlast = true;\n\t\t\t\t\t\t\n\t\t\t\t\t}\n\n\t\t\t\t\t\n\t\t\t\t\tvar item2 = setComponent(type);\n\t\t\t\t\t\n\t\t\t\t\tif (last) {\n\t\t\t\t\t\titem2.append('<p><br></p>');\n\t\t\t\t\t}\n\t\t\t\t\t$(item).replaceWith( item2);\n\t\t\t\t\t\n\n\t\t\t\t\tpostComponent(item2,type);\n\t\t\t\t\t\n\t\t\t\t}\n\n\t\t    }\n\t\t});\n        \n        \n        lasso_editor.addComponentButton = function()\n        {\n\t\t\t// this function checks the current selected element and adds the component button if appropriate\n\t\t\tif (!lasso_editor.buttonOnEmptyP) {\n\t\t\t\t// if this feature is not turned on, return\n\t\t\t\treturn;\n\t\t\t}\n\t\t\twindow.selRange = saveSelection();\n            if (!window.selRange) return;\n\t\t\tvar container = window.selRange.startContainer,\n\t\t\tcontainerTag;\n            if ($(container).attr('id') == \"lasso--content\") {\n                container = $(container).children()[0];\n            }\n\t\t\t$('#lasso-side-comp-button').remove();\n\t\t\tcontainerTag = container.localName;\n\t\t\tparentTag = $(container).parent().prop(\"tagName\");\n            \n            if ($(container).parent().attr('id') != \"lasso--content\") {\n\t\t\t\tif (parentTag == 'figure' || parentTag == 'div' || $(container).parent().parent().attr('id') != \"lasso--content\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\t\t\t\n            \n\t\t\tif ( containerTag == 'p' || ((containerTag=='b' || containerTag=='em' || containerTag=='i' || containerTag=='strike' || containerTag=='span') && $(container).parent().text() == \"\")) \n\t\t\t{\t\n\t\t\t\tvar innerText = container.innerText.replace(/(\\r\\n|\\n|\\r)/gm,\"\");\n\t\t\t\tif (innerText != \"\") {\n\t\t\t\t\t//this paragraph is not empty, return\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar top_ = container.offsetTop-10;\n\t\t\t\tvar left_ = container.offsetLeft-30;\n\t\t\t\t\n\t\t\t\tif ($(container).parent().attr('id') != \"lasso--content\") {\n\t\t\t\t\t$(container).parent().empty();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar button = $('<div id=\"lasso-side-comp-button\" style=\"width:30px;height:30px;position:absolute;\" contenteditable=\"false\"></div>');\n\t\t\t\tbutton.css({top:top_,left:left_});\n    \n\t\t\t\t$(\"#lasso--content\").append(button);\n\t\t\t\tif (button.offset().left<0) {\n\t\t\t\t\tbutton.offset({left:0});\n\t\t\t\t}\n\t\t\t}\n        }\n\n\n        // the following codes decide which UI triggers drag-drop and which UI triggers click-insert\n        // If we are only using drag-drop then clickToInsertElement would be empty\n\t\tvar clickToInsertElement = '#lasso-side-comp-button #lasso-toolbar--components__list li';\n\t\tif (lasso_editor.clickToInsert) {\n\t\t\tclickToInsertElement = '#lasso-toolbar--components__list li'\n\t\t} \t\t\n\t\t\t\n\t\telse \n\t\t{\n\t\t\t$('#lasso-toolbar--components #lasso-toolbar--components__list li').draggable({\n\t\t\t\taxis:'y',\n\t\t\t\thelper:'clone',\n\t\t\t\tcursor: 'move',\n\t\t\t\tconnectToSortable: '#'+editor,\n\t\t\t\tstart: function(ui) {\n\n\t\t\t\t\t// add an origin so sortable can detect where comign from\n\t\t\t\t\torigin = 'draggable';\n\n\t\t\t\t\t// get the curent target and add the type class to the drag event\n\t\t\t\t\tvar item = ui.currentTarget,\n\t\t\t\t\t\ttype = $(item).attr('data-type');\n\n\t\t\t\t\t$(this).addClass(type);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tjQuery(document).on('mousedown', clickToInsertElement, function(){\n\t\t\t\tvar type = $(this).attr('data-type');\n\t\t\t\tvar item = setComponent(type);\n\t\t\t\trestoreSelection(window.selRange);\n                $('#lasso-side-comp-button').remove();\n                if ($('#'+editor).children().length==1 && $('#'+editor).find('.editus-firstp').length ==1) {\n                    $('.editus-firstp').replaceWith(item);\n                } else {\n                    var t = insert_html(item, false);\n                }\n\t\t\t\t\n\t\t\t\tpostComponent(item,type);\n\t\t\t\tlasso_editor.addComponentButton();\n\t\t});\n            \n                    \n        // replace the content if the content is empty\n        if ( $('#'+editor).children().length && $('#'+editor).children().prop(\"tagName\") == \"P\" && $('#'+editor).children().text() == \"\") {\n            $('#'+editor).html(lasso_editor.newObjectContent);\n            $('#'+editor).children().focus();\n            lasso_editor.addComponentButton();\n        }\n        \n        lasso_editor.hidePopup = function(){\n            $(\".lasso--text-popup\").hide();\n\t\t}\n        \n        lasso_editor.checkForPopup = function()\n        {\n            if (!lasso_editor.toolbarPopup) return;\n            \n            s = window.getSelection();\n            oRange = s.getRangeAt(0); //get the text range\n            if (!oRange.collapsed ) {\n                oRect = oRange.getBoundingClientRect();\n                ;\n                oRect2 = document.getElementById(editor).getBoundingClientRect();\n                oRect3 = document.body.getBoundingClientRect();\n                var t2 = $('body').offset().top;\n                //var t2 = document.body.offsetTop.getBoundingClientRect().top;\n                var left = ((oRect.right+oRect.left) - $(\".lasso--text-popup\").width())/2;\n                if (left <= 0) left = 0;\n                var t = oRect.bottom-document.body.getBoundingClientRect().top;\n                $(\".lasso--text-popup\").css(\"left\",left);\n                $(\".lasso--text-popup\").css(\"top\",t+t2);\n                $(\".lasso--text-popup\").css(\"display\",\"table\");\n                $(\".lasso--text-popup\").css(\"position\",\"absolute\");\n            } else {\n                lasso_editor.hidePopup();\n            }\n        };\n\t\t\n\t\t$('#'+editor).on('mouseup',function() {\n            lasso_editor.checkForPopup();\n        });\n        \n        $('#'+editor).focusout(function() {\n            lasso_editor.hidePopup();\n        });\n\t\t\n            \n        // ways to inject codes into the enterEditor\n\t\tif (lasso_editor.enterEditorHookArray2) {\n\t\t\t$(lasso_editor.enterEditorHookArray2).each(function(key, val){\n\t\t\t\tval();\n\t\t\t});\n\t\t}   \n\n\t});\n\tif (lasso_editor.skipToEdit)\n\t{\n\t\t$('#lasso--edit').trigger('click');\n\t\tlasso_editor.skipToEdit = false;\n\t}\n\t\n\tif (lasso_editor.setupHookArray) {\n\t\t$(lasso_editor.setupHookArray).each(function(key, val){\n\t\t\tval();\n\t\t});\n\t}\n});\n\n\n\n\n\n"
  },
  {
    "path": "public/assets/js/source/modal-sizing.js",
    "content": "(function( $ ) {\n\n\t// dyanmically center modals vertically based on size of modal\n\tjQuery(document).ready(function($){\n\n\t\tmodalResizer = function(){\n\n\t\t\tvar modal = $('.lasso--modal')\n\t\t\t,   mHeight = modal.height()\n\t\t\t,\twHeight  = $(window).height()\n\t\t\t,\teHeight  = $('.lasso--modal').hasClass('lasso--tour__modal') ? 0 : 30 // this is the height of the submit button that is hidden utnil the user changes a setting\n\n\t\t\tmodal.css({\n\t\t\t\t'top' : (wHeight - mHeight - eHeight) / 2\n\t\t\t})\n\n\t\t}\n\t\t$('.lasso--modal').imagesLoaded( function() {\n\t\t\tmodalResizer();\n\t\t})\n\n\t\tjQuery(window).resize(function(){ modalResizer(); });\n\n\t});\n\n})( jQuery );"
  },
  {
    "path": "public/assets/js/source/post-settings.js",
    "content": "(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t/////////////////\n\t\t/// MODAL LOGIC\n\t\t///////////////////\n\n\t\t// method to destroy the modal\n\t\tvar destroyModal = function(){\n\t\t\t$('body').removeClass('lasso-modal-open');\n\t\t\t$('#lasso--post-settings__modal, #lasso--modal__overlay').remove();\n\t\t}\n\t\t\n\t\tjQuery(document).on('click', '.lasso--postsettings__option', function(e){\n\t\t\tif ($(e.target).hasClass('tagit')) {\n\t\t\t\t// close the modal window if the user clicks on empty spaces\n\t\t\t\t// destroy posts modal\n\t\t\t\t\n\t\t\t\tdestroyModal();\n\t\t\t}\t\t\t\n\t\t});\n\n\t\t// modal click\n\t\t//$('#lasso--post-settings').live('click',function(e){\n\t\tjQuery(document).on('click','#lasso--post-settings, #lasso--post-settings2',function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\t// add a body class\n\t\t\t$('body').toggleClass('lasso-modal-open');\n\n\t\t\t// append teh modal markup ( lasso_editor_component_modal() )\n\t\t\t$('body').append(lasso_editor.component_modal);\n\n\t\t\t/////////////////\n\t\t\t/// UI SLIDER INIT AND METHODS\n\t\t\t///////////////////\n\n\t\t\tvar statusReturn = function( value ) {\n\n\t\t\t\tvar out;\n\t\t\t\tif ( 100 == value ) {\n\t\t\t\t\tout = 'draft';\n\t\t\t\t} else if ( 150 == value ) {\n\t\t\t\t\tout = 'pending';\n\t\t\t\t} else if ( 200 == value ) {\n\t\t\t\t\tout = 'publish';\n\t\t\t\t} else if ( 'draft' == value ) {\n\t\t\t\t\tout = 100;\n\t\t\t\t} else if ( 'pending' == value ) {\n\t\t\t\t\tout = 150;\n\t\t\t\t} else if ( 'publish' == value ) {\n\t\t\t\t\tout = 200;\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t}\n\n\t\t\t// init slider\n\t\t    $('#lasso--slider').slider({\n\t\t      \tvalue:statusReturn(lasso_editor.post_status),\n\t\t      \tmin: 100,\n\t\t      \tmax: 200,\n\t\t      \tstep: lasso_editor.supportPendingStatus ? 50 : 100,\n\t\t      \tanimate:'fast',\n\t\t      \tslide: function( event, ui ) {\n\t\t        \t$('input[name=\"status\"]').val( statusReturn(ui.value) );\n\n\t\t        \t$('.lasso--postsettings__footer').slideDown()\n\n\t\t        \tif ( 100 == ui.value ) {\n\t\t        \t\t$('.story-status').removeClass('story-status-publish').addClass('story-status-draft')\n\t\t        \t} else if ( 200 == ui.value ) {\n\t\t        \t\t$('.story-status').removeClass('story-status-draft').addClass('story-status-publish')\n\t\t        \t}\n\t\t      \t}\n\t\t    });\n\t\t    $('input[name=\"status\"]').val( statusReturn( $( \"#lasso--slider\" ).slider('value') ) );\n\n\t\t    /*// if any changes happen then show the footer\n\t\t    $('.lasso--modal__trigger-footer').on('keyup',function(){\n\t\t\t  \t$('.lasso--postsettings__footer').slideDown()\n\t\t\t});*/\n\n\t\t    // categories\n\t\t    var cats = $('#lasso--cat-select')\n\t\t    ,\ttags = $('#lasso--tag-select')\n            ,   custom = $('#lasso--custom-taxo-input')\n\n\t\t\tcats.tagit({\n\t\t\t\t//fieldName:'itemName[fieldName][]',\n\t\t\t\tplaceholderText: lasso_editor.strings.catsPlaceholder, //'add categories...',\n\t\t\t\tavailableTags: lasso_editor.postCategories,\n                allowSpaces: true\n\t\t\t});\n\n\t\t\tcats.on('change',function(event){\n\t\t\t\t$('.lasso--postsettings__footer').slideDown()\n\t\t\t})\n\n\t\t\ttags.tagit({\n\t\t\t\t//fieldName:'itemName[fieldName][]',\n\t\t\t\tplaceholderText: lasso_editor.strings.tagsPlaceholder,//'add tags...',\n\t\t\t\tavailableTags: lasso_editor.postTags,\n                allowSpaces: true\n\t\t\t});\n\n\t\t\ttags.on('change',function(event){\n\t\t\t\t$('.lasso--postsettings__footer').slideDown()\n\t\t\t})\n\t\t\t\n\t\t\tif( $('.editus_custom_date').length ) {\n\t\t\t\t$('.editus_custom_date').datepicker({});\n\t\t\t}\n            \n            if (lasso_editor.supCustTaxo) {           \n                var selTaxo = $('#lasso--custom-taxo-select').val();\n                custom.val(lasso_editor.postCusTaxonomies[selTaxo]);\n                custom.tagit({\n                    placeholderText: lasso_editor.strings.catsPlaceholder,//'add tags...',\n                    availableTags: lasso_editor.extCusTaxonomies[selTaxo],\n                    allowSpaces: true\n                });\n                              \n                $('#lasso--custom-taxo-select').on('change', function() {\n                    lasso_editor.postCusTaxonomies[selTaxo] = custom.val();\n                    \n                    custom.tagit(\"destroy\");\n                    custom.val(lasso_editor.postCusTaxonomies[$(this).val()]);\n                    custom.tagit({\n                        placeholderText: lasso_editor.strings.taxoPlaceholder, //'add categories...',\n                        availableTags: lasso_editor.extCusTaxonomies[$(this).val()],\n                        allowSpaces: true\n                    });\n                                   \n                    selTaxo = $(this).val();\n                });\n            }\n\n\t\t\tmodalResizer()\n\n\t\t});\n\n\t\t// destroy modal if clicking close or overlay\n\t\t//$('#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel').live('click',function(e){\n\t\tjQuery(document).on('click', '#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel', function(e){\n\t\t\te.preventDefault();\n\t\t\tdestroyModal();\n\t\t});\n\n\t\t/////////////////\n\t\t/// EXIT SETTINGS\n\t\t///////////////////\n\t\t$(document).keyup(function(e) {\n\n\t\t\tif ( 27 == e.keyCode ) {\n\n\t\t\t\tdestroyModal();\n\t\t\t}\n\n\t\t});\n\n\t\t/////////////\n\t\t// SAVE SETTINGS\n\t\t//////////////\n\t\tvar form;\n\n\t\t//$('#lasso--postsettings__form').live('submit', function(e) {\n\t\t\t\t//$('#lasso--postsettings__form').live('submit', function(e) {\n\t\tjQuery(document).on('submit','#lasso--postsettings__form',function(e) {\n\n\t\t\te.preventDefault();\n\t\t\tif ($('#lasso--custom-field-form').length ==0 || $('#lasso--custom-field-form').children().length == 0 ) {\n                $('#lasso--save').removeClass('lasso-publish-post');\n\t\t\t\t$('#lasso--save').trigger('click');\n\t\t\t}\n\n\t\t\tvar $this = $(this);\n\t\t\t\n\t\t\t/*\n\t\t\t//alternate way of setting categories, disabled for now\n\t\t\tvar cats = [];\n\t\t\t\n\t\t\t$('input[name=\"categories\"]').each(function () {\n\t\t\t\tif (this.checked) { cats.push(this.id);}\n\t\t\t});\n\t\t\tif (cats.length>0) {\n\t\t\t\t$('input[name=\"story_cats\"]').val(cats.join(','));\n\t\t\t}*/\n            \n            if (lasso_editor.supCustTaxo) {          \n                var selTaxo = $('#lasso--custom-taxo-select').val();\n                lasso_editor.postCusTaxonomies[selTaxo] = $('#lasso--custom-taxo-input').val();\n                $(this).find(\"input[name=story_custom_taxonomies]\" ).val(JSON.stringify(lasso_editor.postCusTaxonomies));\n            }\n\n\t\t\t$(this).find('input[type=\"submit\"]').val(lasso_editor.strings.saving);\n\n\t\t\t\n\t\t\tvar data2 = $this.serialize();\n\n\t\t\t/////////////\n\t\t\t//\tDO THE SAVE\n\t\t\t/////////////\n\t\t\t\t\n\t\t\tvar data = {\n\t\t\t\taction: 'editus_set_post_setting',\n\t\t\t    postid: lasso_editor.postid,\n\t\t\t\tdata: data2\n\t\t\t};\n\t\t\t\t\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n\t\t\t\tif( true == response.success ) {\n\t\t\t\t\t$('input[type=\"submit\"]').addClass('saved');\n\t\t\t\t\t$('input[type=\"submit\"]').val(lasso_editor.strings.saved);\n                    window.onbeforeunload = null;\n\t\t\t\t\t\n\t\t\t\t\tif ($('#lasso--custom-field-form').length && $('#lasso--custom-field-form').children().length) {\n\t\t\t\t\t\t$('#lasso--custom-field-form').trigger('submit');\n\t\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t  window.location.replace(response.data['link']);\n\t\t\t\t\t\t}, 1000);\n\t\t\t\t\t} else {\n                        // changing the setting can potentially change the URL of the post. In that case we need to\n                         // reload the post\n\t\t\t\t\t    window.location.replace(response.data['link']);\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\talert('error:'+response);\n\t\t\t\t\tconsole.log(response)\n\n\t\t\t\t}\n\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\t\t});\n\n\t\t/////////////\n\t\t// ADDON TABS\n\t\t//////////////\n\t\t$(document).on('click', '.lasso--modal__tabs li', function(e){\n\n\t\t\te.preventDefault()\n\n\t\t\tvar $this\t= $(this)\n\t\t\t,\tname  \t= $this.data('addon-name')\n\t\t\t,\trem \t= 'not-visible'\n\t\t\t,\tadd    \t= 'visible'\n\n\t\t\t$('.lasso--modal__tabs li').removeClass('active-tab')\n\n\t\t\t$this.addClass('active-tab')\n\n\t\t\t$('.lasso--modal__content').removeClass( add ).addClass( rem )\n\n\t\t\t$this.closest('.lasso--modal__inner').find('div[data-addon-content=\"'+name+'\"]').removeClass( rem ).addClass( add )\n\n\t\t\tmodalResizer()\n\t\t})\n\n\t});\n\n})( jQuery );"
  },
  {
    "path": "public/assets/js/source/process-gallery-opts.js",
    "content": "(function( $ ) {\n\n\t$(document).ready(function($){\n\n\t\t// this function is repeated on settings-panel.js\n\t\tvar value_check = function( value ){\n\n\t\t\tif ( 'grid' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeIn();\n\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t}\n\n\t\t\tif ( 'thumbnail' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeIn();\n\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t}\n\n\t\t\tif ( 'photoset' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeIn();\n\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t}\n\t\t\t\t\t\t\n\t\t\tif ( 'hero' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeIn();\n\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t}\n\t\t}\n\n\t\t$('.ase-gallery-type-radio').each(function(){\n\n\t\t\tif ( $(this).is(':checked') ) {\n\t\t\t\t$(this).parent().addClass('selected');\n\t\t\t\tvar value = $(this).val();\n\t  \t\t\tvalue_check(value);\n\n\t\t\t}\n\n\t\t});\n\n\t\t//$('.ase-gallery-layout-label').live('click',function(){\n\t\tjQuery(document).on('click','.ase-gallery-layout-label', function(){\n\t\t\t$('.ase-gallery-layout-label').removeClass('selected');\n\t\t\t$(this).addClass('selected');\n\t\t\tvar value = $(this).find('input').val();\n\t\t\tvalue_check(value);\n\n\t\t\t// add the type to a hidden field\n\t\t\t$('#ase_gallery_type').val( value )\n\t\t});\n\t})\n\n})( jQuery );"
  },
  {
    "path": "public/assets/js/source/process-gallery.js",
    "content": "(function( $ ) {\n\t'use strict';\n\n\t/////////////\n\t// NEW GALLERY CREATE\n\t////////////\n\t//$('#lasso--gallery__create').live('click',function(e){\n\tjQuery(document).on('click','#lasso--gallery__create',function(e){\n\n\t\te.preventDefault();\n\n\t\t$(this).closest('form').addClass('creating-gallery');\n\n\t\t$('.ase-gallery-opts--create-gallery2').fadeIn();\n\t\t$('.ase-gallery-opts--edit-gallery').fadeOut(1);\n\n\t\t$('#ase-gallery-images li').remove();\n\t\t$('#lasso--gallery__create').remove();\n\n\t\t$('.ase-gallery-opts--edit-gallery').text(lasso_editor.strings.addNewGallery);\n\t\t$('.ase-gallery-opts--edit-gallery .lasso-option-desc').text('Select new images to create a gallery with.');\n\n\n\t});\n\n\t/////////////\n\t// NEW GALLERY UPLOAD\n\t////////////\n\n\tvar file_frame;\n\tvar\tgallery = $('#ase-gallery-images');\n\n\t//$(document).on('click', '#lasso--gallery__selectImages', function( e ){\n\tjQuery(document).on('click','#lasso--gallery__selectImages',function( e ){\n\n\t    e.preventDefault();\n\n\t    // If the media frame already exists, reopen it.\n\t    if ( file_frame ) {\n\t      \tfile_frame.open();\n\t      \treturn;\n\t    }\n\n\t    // Create the media frame.\n\t    file_frame = wp.media.frames.file_frame = wp.media({\n\t      \ttitle: lasso_editor.strings.chooseImages,\n\t      \tbutton: {\n\t        \ttext: lasso_editor.strings.addImages,\n\t      \t},\n\t      \tmultiple: true  // Set to true to allow multiple files to be selected\n\t    });\n\n\t    // When an image is selected, run a callback.\n\t    file_frame.on( 'select', function() {\n\n\t      \tvar attachments = file_frame.state().get('selection');\n\n\t\t    if (!attachments) {\n\t\t        return;\n\t\t    }\n\n\t\t    // loop through and insert the new items\n\t\t    attachments.each( function( attachment ) {\n\t\t    \tvar id = attachment.id;\n\t\t    \tvar url = attachment.attributes.sizes.thumbnail.url;\n\t\t    \tase_insert_gallery_item(id, url);\n\t\t    });\n\n\t\t    // insert the new ids from new gallery\n\t\t    var ids = attachments.map( function( attachment ) {\n\n\t\t    \tvar attachment = attachment.toJSON();\n\t\t    \treturn attachment.id;\n\n\t\t    }).join(',');\n\n\t\t    // populate gallery input with ids\n\t\t    $('#ase_gallery_ids').val( ids );\n\n\t\t    // show the save button\n\t      \t$('.has-galleries > #lasso--gallery__save').fadeIn();\n\n\t      \t// remove the select images button\n\t      \t$('#lasso--gallery__selectImages').remove();\n\n\t    });\n\n\t    // Finally, open the modal\n\t    file_frame.open();\n\t});\n\n\t//////////\n\t// NEW GALLERY SWAP\n\t//////////\n\t//$('.lasso-gallery-id #aesop-generator-attr-id').live('change',function(){\n\tjQuery(document).on('change','.aesop-gallery-id #aesop-generator-attr-id',function(){\n\n\t\teditus_gallery_swap($(this).val());\n\t\t\n\t\tvar data2      = {\n\t\t\taction:    \t'process_gallery_get-images',\n\t\t\tpost_id:   \t$(this).val(),\n\t\t\tnonce: \t\tlasso_editor.getGallImgNonce\n\t\t};\n\n\t\t// post ajax response with data\n\t\t$.post( lasso_editor.ajaxurl, data2, function(response) {\n\t\t\t$('#lasso--gallery__images').html( response.data.html );\n\n\t\t\t/////////////\n\t\t\t// CALL SORTABLE ON RECIEVED IMAGES\n\t\t\t/////////////\n\t\t\tvar\tgallery = $('#ase-gallery-images');\n\n\t\t\tgallery.ready(function(){\n\n\t\t\t\tgallery.sortable({\n\t\t\t\t\tcontainment: 'parent',\n\t\t\t\t\tcursor: 'move',\n\t\t\t\t\topacity: 0.8,\n\t\t\t\t\tplaceholder: 'ase-gallery-drop-zone',\n\t\t\t\t\tforcePlaceholderSize:true,\n\t\t\t\t\tupdate: function(){\n\t\t\t\t\t\tvar imageArray = $(this).sortable('toArray');\n\t\t\t\t\t\t$('#ase_gallery_ids').val( imageArray );\n\t\t\t\t\t},\n\t\t\t\t\tcreate: function(){\n\t\t\t\t\t\tvar imageArray = $(this).sortable('toArray');\n\t\t\t\t\t\t$('#ase_gallery_ids').val( imageArray );\n\t\t\t\t\t}\n\t\t\t\t});\n                window.component.find('.lasso-component--settings__trigger').trigger('click');\n\t\t\t});\n\t\t}).fail(function(xhr, err) { \n\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t});\n\t});\n\t\n\tfunction editus_gallery_swap(galleryID){\n\t\tvar data      = {\n\t\t\tcomponentType: 'gallery',\n\t\t\tid:   \tgalleryID\n\t\t};\n\t\twindow.get_aesop_component_ajax(data);\n\t}\n\n\t///////////\n\t// EDIT GALLERY\n\t// the sortsble instat is in settingspanel.js\n\t///////////\n\n\t// deleting gallery items\n\t$(document).on('click', '.ase-gallery-image > i.dashicons-no-alt', function(){\n\t\t$(this).parent().remove();\n\t\tgallery.sortable('refresh');\n\t\tase_encode_gallery_items();\n\t});\n\n\tfunction ase_string_encode(gData){\n\t\treturn encodeURIComponent(JSON.stringify(gData));\n\t}\n\n\tfunction ase_string_decode(gData){\n\t\treturn JSON.parse(decodeURIComponent(gData));\n\t}\n\n\tfunction ase_encode_gallery_items(){\n\t\tgallery = $('#lasso--gallery__images #ase-gallery-images');\n\t\tif (gallery.length) {\n\t\t   var imageArray = gallery.sortable('toArray');\n\t  \t   $('#ase_gallery_ids').val( imageArray );\n\t\t}\n\t}\n\n\t// inserting gallery items\n\tfunction ase_insert_gallery_item(id, url){\n\n\t\tvar item_html = \"<li id='\" + id + \"' class='ase-gallery-image'><i class='dashicons dashicons-no-alt'></i><i title='Edit Image Caption' class='dashicons dashicons-edit'></i><img src='\" + url + \"'></li>\";\n\t\t$('#ase-gallery-images').append( item_html );\n\t\tgallery.sortable('refresh');\n\t\tase_encode_gallery_items();\n\t}\n\n\t// adding additiona images to existing gallery\n\n\tvar clicked_button = false;\n\n\t$(document).on('click', '#ase-gallery-add-image', function (event) {\n    \tevent.preventDefault();\n    \tvar selected_img;\n    \tclicked_button = $(this);\n\n    \tif(wp.media.frames.ase_frame) {\n\t\t\twp.media.frames.ase_frame.open();\n\t\t\treturn;\n\t\t}\n\n    \twp.media.frames.ase_frame = wp.media({\n\t\t\ttitle: lasso_editor.strings.selectGallery,\n\t\t\tmultiple: true,\n\t\t\tlibrary: {\n\t\t\t    type: 'image'\n\t\t\t},\n\t\t\tbutton: {\n\t\t\t    text: lasso_editor.strings.useSelectedImages\n\t\t\t}\n\t\t});\n\n    \tvar ase_media_set_image = function() {\n\t\t\tvar selection = wp.media.frames.ase_frame.state().get('selection');\n\n\t\t\tif (!selection) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tselection.each(function(attachment) {\n\t\t\t\tvar id = attachment.id;\n\t\t\t\tvar url = attachment.attributes.sizes.thumbnail.url;\n\t\t\t\tase_insert_gallery_item(id, url);\n\t\t\t});\n\n\t\t};\n\n    \twp.media.frames.ase_frame.on('select', ase_media_set_image);\n\t\twp.media.frames.ase_frame.open();\n\t});\n\n\n\t// editing a single image\n\tfunction ase_edit_gallery_item(id, url, editable){\n\t\tvar item_html = \"<li id='\" + id + \"' class='ase-gallery-image'><i class='dashicons dashicons-no-alt'></i><i title='Edit Image Caption' class='dashicons dashicons-edit'></i><img src='\" + url + \"'></li>\";\n\t\t$(editable).replaceWith( item_html );\n\t\tgallery.sortable('refresh');\n\t\tase_encode_gallery_items();\n\t}\n\n\t// edit single image\n\tvar ase_media_edit_init = function()  {\n\n\t    var clicked_button;\n\n\t    $(document).on('click', '.ase-gallery-image > i.dashicons-edit', function(event){\n\t\t\tevent.preventDefault();\n\t\t\tvar selected_img;\n\t\t\tclicked_button = $(this);\n\n\t\t\tif(wp.media.frames.ase_edit_frame) {\n\t\t\t\twp.media.frames.ase_edit_frame.open();\n\t\t\t\treturn;\n\t\t\t}\n\n            wp.revisions\n\n\t\t\twp.media.frames.ase_edit_frame = wp.media({\n\t\t\t\ttitle: lasso_editor.strings.editImage,\n\t\t\t\tmultiple: false,\n\t\t\t\tlibrary: {\n\t\t\t\t  \ttype: 'image'\n\t\t\t\t},\n\t\t\t\tbutton: {\n\t\t\t\t  \ttext: lasso_editor.strings.updateSelectedImg\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar ase_media_edit_image = function() {\n\t\t\t    var selection = wp.media.frames.ase_edit_frame.state().get('selection');\n\n\t\t\t    if (!selection) {\n\t\t        \treturn;\n\t\t\t    }\n\n\t\t\t    // iterate through selected elements\n\t\t\t    selection.each(function(attachment) {\n\t\t\t    \tvar id = attachment.id;\n\t\t\t    \tvar url = attachment.attributes.sizes.thumbnail.url;\n\t\t\t    \tase_edit_gallery_item(id, url, clicked_button.parent());\n\t\t\t    });\n\n\t\t\t};\n\n\t\t\t// image selection event\n\t\t\twp.media.frames.ase_edit_frame.on('select', ase_media_edit_image);\n\t\t\twp.media.frames.ase_edit_frame.on('open',function(){\n\t\t\t\t var selection = wp.media.frames.ase_edit_frame.state().get('selection');\n\t\t\t\tvar attachment = wp.media.attachment( clicked_button.parent().attr('id') );\n\t\t\t\tattachment.fetch();\n\t\t\t\tselection.add( attachment ? [ attachment ] : [] );\n\t\t\t});\n\t\t\twp.media.frames.ase_edit_frame.open();\n\t    });\n\n\t};\n\n\t//ase_media_init('#ase-gallery-add-image', 'i');\n\tase_media_edit_init();\n\tase_encode_gallery_items();\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/process-image-upload.js",
    "content": "(function( $ ) {\n\t'use strict';\n\n\t//$( '#lasso--featImgSave a' ).live('click', function(e) {\n\tjQuery(document).on('click', '#lasso--featImgSave a', function(e){\n\t\te.preventDefault();\n\n\t\tvar $this \t\t= $(this)\n\t\t,\tsaveStatus = $('#lasso--save-status')\n\n\t\tvar data = {\n\t\t\taction: 'editus_featured_img',\n\t\t\tpostid: lasso_editor.postid,\n\t\t\timage_id: $this.data('featimg-id'),\n\t\t\tnonce: \tlasso_editor.featImgNonce\n\t\t}\n\n\t\tsaveStatus.removeClass('not-visible').addClass('visible lasso--animate__spin');\n\n\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n\t\t\tif ( response ) {\n\t\t\t\tconsole.log('response')\n\t\t\t\t$('#lasso--featImgSave').css('opacity',0);\n\t\t\t\t//setTimeout(function(){\n\t\t\t\t//\tsaveStatus.removeClass('lasso--animate__spin lasso-icon-check').addClass('lasso-icon-spinner6 not-visible')\n\t\t\t\t//},500);\n\t\t\t}\n\t\t\tsaveStatus.removeClass('lasso--animate__spin lasso-icon-spinner6').addClass('lasso-icon-check');\n\n\t\t}).fail(function(xhr, err) { \n\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\tsaveStatus.removeClass('lasso--animate__spin lasso-icon-spinner6').addClass('lasso-icon-check');\n\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t});\n\n\t});\n\n\t/////////////\n\t// FILE UPLOAD\n\t////////////\n\tvar file_frame;\n\tvar className;\n\n\t$(document).on('click', '#lasso--featImgUpload > a', function( e ){\n\n\t    e.preventDefault();\n\n\t    className = e.currentTarget.parentElement.className;\n\n\t  \tvar save  = $('#lasso--featImgSave a')\n\n\t    // If the media frame already exists, reopen it.\n\t    if ( file_frame ) {\n\t      \tfile_frame.open();\n\t      \treturn;\n\t    }\n\n\t    // Create the media frame.\n\t    file_frame = wp.media.frames.file_frame = wp.media({\n\t      \ttitle: lasso_editor.strings.chooseImage,\n\t      \tbutton: {\n\t        \ttext: lasso_editor.strings.updateImage,\n\t      \t},\n\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t    });\n\n\t    // When an image is selected, run a callback.\n\t    file_frame.on( 'select', function() {\n\n\t      \tvar attachment = file_frame.state().get('selection').first().toJSON();\n\n\t      \t$('body').addClass('lasso--post-thumb-applied');\n\n\t      \t$('article').removeClass('no-post-thumbnail').addClass('has-post-thumbnail');\n\n\t      \tif ( $(lasso_editor.featImgClass).is( \"img\" ) ) {\n\t\t\t\t$(lasso_editor.featImgClass).prop(\"src\",attachment.url);\n\t\t\t\t$(lasso_editor.featImgClass).prop(\"srcset\",\"\");\n\t\t\t} else {\n\t\t\t\t$(lasso_editor.featImgClass).css({\n\t\t\t\t\t'background-image': 'url('+attachment.url+')'\n\t\t\t\t});\n\t\t\t}\n\n\t      \tsave.attr('data-featimg-id',attachment.id).trigger('click');\n\n\t      \t$('.no-post-cover-note').remove();\n\n\t    });\n\n\t    // Finally, open the modal\n\t    file_frame.open();\n\t});\n\n\t////////////\n\t// FEAT IMAGE DELETE\n\t////////////\n\t$(document).on('click', '#lasso--featImgDelete > a', function( e ){\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\tvar data = {\n\t\t\taction: 'editus_del_featured_img',\n\t\t\tpostid: lasso_editor.postid,\n\t\t\tnonce: \tlasso_editor.featImgNonce\n\t\t}\n\n\t\tswal({\n\t\t\ttitle: lasso_editor.strings.removeFeatImg,\n\t\t\ttype: \"warning\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: lasso_editor.strings.deleteYes,\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n\t\t\t\tif ( \"\" == response ) {\n\n\t\t\t\t\t// add a body class so we can do whatever with\n\t\t\t\t\t$('body').addClass('lasso--post-thumb-removed');\n\n\t\t\t\t\t$('article').removeClass('has-post-thumbnail').addClass('no-post-thumbnail');\n\n\t\t\t\t\t// add the hidden class to control shell to allow for delete button\n\t\t\t\t\t$('#lasso--featImgDelete').addClass('lasso--featImg--controlHidden');\n\t\t\t\t\t$this.closest('ul').removeClass('lasso--featImg--has-thumb');\n\n\t\t\t\t\t// remove the attr src - just a real-time update\n\t\t\t      \tif ( $(lasso_editor.featImgClass).is( \"img\" ) ) {\n\t\t\t\t\t\t$(lasso_editor.featImgClass).attr(\"src\",\"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$(lasso_editor.featImgClass).css({\n\t\t\t\t\t\t\t'background-image': 'url()'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t});\n\n\n\n\t});\n\n\t////////////\n\t// FEAT IMAGE FROM SETTINGS - @since 0.9.4\n\t////////////\n\tvar featimg_frame;\n\t$(document).on('click', '#lasso--post-thumb__add', function( e ){\n\n\t    e.preventDefault();\n\n\t    var $this = $(this)\n\t    ,\tsave  = $('#lasso--featImgSave a')\n\n\t    // If the media frame already exists, reopen it.\n\t    if ( featimg_frame ) {\n\t      \tfeatimg_frame.open();\n\t      \treturn;\n\t    }\n\n\t    // Create the media frame.\n\t    featimg_frame = wp.media.frames.featimg_frame = wp.media({\n\t      \ttitle: lasso_editor.strings.chooseImage,\n\t      \tbutton: {\n\t        \ttext: lasso_editor.strings.updateImage,\n\t      \t},\n\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t    });\n\n\t    // When an image is selected, run a callback.\n\t    featimg_frame.on( 'select', function() {\n\t      \tvar attachment = featimg_frame.state().get('selection').first().toJSON();\n\t\t\t\n\t\t\tvar pic = $this.closest('.lasso--post-thumb').find('img');\n\t\t\tpic.attr('src', attachment.url );\n\t\t\t\n\t      \tsave.attr('data-featimg-id',attachment.id).trigger('click');\n\t      \t$('#lasso--postsettings__form').removeClass('no-thumbnail').addClass('has-thumbnail');\n\t\t\tpic.removeAttr(\"srcset\");\n\t\t\tnoWarningReload = true;\n\t    });\n\n\t    // Finally, open the modal\n\t    featimg_frame.open();\n\n\n\t}).on('click', '#lasso--post-thumb__delete', function( e ){\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\tvar data = {\n\t\t\taction: 'editus_del_featured_img',\n\t\t\tpostid: lasso_editor.postid,\n\t\t\tnonce: \tlasso_editor.featImgNonce\n\t\t}\n\n\t\tswal({\n\t\t\ttitle: lasso_editor.strings.removeFeatImg,\n\t\t\ttype: \"warning\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: lasso_editor.strings.deleteYes,\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n                \n\n\t\t\t\tif ( \"\" == response ) {\n\t\t\t\t\tvar defaultImg = $this.closest('.lasso--post-thumb').data('default-thumb');\n\t\t\t      \t$this.closest('.lasso--postsettings__left').find('img').attr('src', defaultImg );\n\t\t\t\t\t$this.closest('.lasso--postsettings__left').find('img').removeAttr(\"srcset\");\n\n\t\t\t      \t$('#lasso--postsettings__form').removeClass('has-thumbnail').addClass('no-thumbnail')\n\t\t\t\t\tnoWarningReload = true;\n\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t});\n\n\t});\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/process-map.js",
    "content": "(function( $ ) {\n\n\tvar form;\n\n\t//$('#lasso--map-form').live('submit', function(e) {\n\tjQuery(document).on('submit','#lasso--map-form',function(e) {\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\t$(this).find('input[type=\"submit\"]').val('Saving...').addClass('being-saved');\n\n\t\tvar data = $this.serialize();\n\n\t\t/////////////\n\t\t//\tDO TEH SAVE\n\t\t/////////////\n\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\tif ( true == response.success ) {\n\n\t\t\t\t$this.find('input[type=\"submit\"]').val('Saved');\n\t\t\t\t$this.removeClass('being-saved').addClass('lasso--saved');\n\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t$this.find('input[type=\"submit\"]').val('Save Locations').removeClass('lasso-saved');\n\t\t\t\t},1200);\n\n\t\t\t} else {\n\t\t\t\t$this.removeClass('being-saved').addClass('lasso--error');\n\t\t\t}\n\n\n\t\t});\n\n\t});\n\n})( jQuery );"
  },
  {
    "path": "public/assets/js/source/process-new-post.js",
    "content": "(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t// method to destroy the modal\n\t\tvar destroyModal = function(){\n\t\t\t$('body').removeClass('lasso-modal-open' );\n\t\t\t$('.lasso--modal, #lasso--modal__overlay').remove();\n\t\t\tif (noWarningReload) {\n\t\t\t\tlocation.reload();\n\t\t\t}\n\t\t}\n\n\t\t// modal click\n\t\t//$('#lasso--post-new').live('click',function(e){\n\t\tjQuery(document).on('click','#lasso--post-new',function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\t// add a body class\n\t\t\t$('body').toggleClass('lasso-modal-open');\n\n\t\t\t// append teh modal markup ( lasso_editor_component_modal() )\n\t\t\t$('body').append(lasso_editor.newPostModal);\n\n\t\t    // if any changes happen then show the footer\n\t\t    $('.lasso--modal__trigger-footer').on('keyup',function(){\n\t\t\t  \t$('.lasso--postsettings__footer #lasso--postsettings-create').slideDown()\n\t\t\t});\n\n\t\t\tmodalResizer()\n\n\t\t});\n\n\t\t// destroy modal if clicking close or overlay\n\t\t//$('#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel').live('click',function(e){\n\t\tjQuery(document).on('click','#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel',function(e){\n\t\t\te.preventDefault();\n\t\t\tdestroyModal();\n\t\t});\n\t\t\n\t\tjQuery(document).on('click', '#lasso--postsettings-setnow', function(e){\n\t\t\t$('.editus_custom_date').datepicker( \"setDate\", new Date().setTime(Date.now()) );\n\t\t});\n\n\t\t/////////////////\n\t\t/// EXIT SETTINGS\n\t\t///////////////////\n\t\t$(document).keyup(function(e) {\n\n\t\t\tif ( 27 == e.keyCode ) {\n\n\t\t\t\tdestroyModal();\n\t\t\t}\n\n\t\t});\n\n\t\t/////////////\n\t\t// MAKE NEW POST OBJECT\n\t\t//////////////\n\t\tvar form;\n\n\t\t//$('#lasso--postnew__form').live('submit', function(e) {\n\t\tjQuery(document).on('submit', '#lasso--postnew__form', function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\tvar $this = $(this);\n\n\t\t\t$(this).find('input[type=\"submit\"]').val(lasso_editor.strings.adding);\n\n\t\t\t\n\t\t\tif (lasso_editor.saveusingrest) {\n                // Use REST API \n\t\t\t\tvar data2 = $this.serializeArray().reduce(function(obj, item) {\n\t\t\t\t\tobj[item.name] = item.value;\n\t\t\t\t\treturn obj;\n\t\t\t\t}, {});\n\t\t\t\tnewPostREST(data2.story_title, data2.object,lasso_editor.newObjectContent);\n\t\t\t} else {\n\t\t\t\tvar data = $this.serialize();\n\t\t\t\t/////////////\n\t\t\t\t//\tDO TEH SAVE\n\t\t\t\t/////////////\n\t\t\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\t\t\t\t\tif ( true == response.success ) {\n\t\t\t\t\t\t$('input[type=\"submit\"]').addClass('saved');\n\t\t\t\t\t\t$('input[type=\"submit\"]').val(lasso_editor.strings.added);\n\t\t\t\t\t\twindow.location.replace(response.link+'&preview=true');\n\t\t\t\t\t} else {\n\t\t\t\t\t\talert('error');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t});\n\n\t});\n\t\n\tfunction newPostREST(title_, type_,content_){\n\t\tvar data      = {\n\t\t\ttitle: title_,\n\t\t\tcontent: \tcontent_, \n\t\t\tstatus: \"draft\"\n\t\t};\n\t\t\n\t\tif (lasso_editor.currCat !== null) {\n\t\t\tdata.categories = $.map( lasso_editor.currCat, function( a ) {\n\t\t\t  return a.term_id;\n\t\t\t});\n\t\t}\n\t\t\n\t\tvar type;\n\t\tif (type_==\"post\") {\n\t\t\ttype = \"posts\";\n\t\t} else if (type_==\"page\"){\n\t\t\ttype = \"pages\";\n\t\t} else {\n\t\t\ttype = type_;\n\t\t}\n\t\t\t\n\t\t$.ajax({\n\t\t\tmethod: \"POST\",\n\t\t\turl: lasso_editor.rest_root + 'wp/v2/'+type,\n\t\t\tdata: data,\n\t\t\tbeforeSend: function ( xhr ) {\n\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t},\n\t\t\tsuccess : function( response ) {\n\t\t\t\t$('input[type=\"submit\"]').addClass('saved');\n\t\t\t\t$('input[type=\"submit\"]').val(lasso_editor.strings.added);\n\n\t\t\t\twindow.location.replace(response.link+'&preview=true');\n\t\t\t},\n\t\t\terror : function (xhr, exception) {\n\t\t\t\talert(\"AJAX Error: \"+xhr.responseText );\t\t\n\t\t\t}\n\t\t});\n\t}\n\n\t/////////////\n\t// POST OBJECT CHANGE - since 0.9.5\n\t/////////////\n\t//$('#lasso--select-type').live('change',function() {\n\tjQuery(document).on('change', '#lasso--select-type', function(){\n\n\t\tvar val = $(this).val()\n\n\t\t$('input[name=\"object\"]').val( val )\n\n\t\t$(this).closest('.story-slug-option').find('label span:not(.lasso-util--help)').text( val )\n\t});\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/process-save-component.js",
    "content": "(function( $ ) {\n\n\tvar form;\n    // get updated aesop componets through ajax calls (global function)\n\twindow.get_aesop_component_ajax = function(cdata)\n\t{\n\t\tvar data = {\n\t\t\t\taction: 'get_aesop_component',\n\t\t\t\tcode: 'aesop_'+cdata['componentType']\n\t\t};\n\t\tfor ( var index in cdata ) {\n\t\t\t\t// Don't accept componentType as a param\n\t\t\t\tif ( !cdata.hasOwnProperty(index) || index == 'componentType'  || index =='sortableItem') {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdata[index] = cdata[index];\n\t\t}\n\t\t\t\t\t\t\n\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\tif( response ){\n\t\t\t\t\tresponse = response.replace(/\\\\'/g, \"'\");\n\t\t\t\t\tvar $a = $(response);\n\t\t\t\t\twindow.component.replaceWith($a);\n\t\t\t\t\twindow.component = $a;\n\t\t\t\t\tif ($('.fotorama').length){\n\t\t\t\t\t\t$('.fotorama').fotorama();\n\t\t\t\t\t}\n\t\t\t\t\tif ($('.aesop-gallery-photoset').length){\n\t\t\t\t\t\t$(window).trigger( 'load' );\n                    }\n                    \n                    lasso_editor.wrapImg();\n                    \n\t\t\t\t\t$('.aesop-component').each(function(){\n\t\t\t\t\t\tif ($(this).css(\"height\")==\"0px\") {\n\t\t\t\t\t\t\t$(this).css(\"height\",\"auto\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if there's no toolbar present\n\t\t\t\t\t\tif ( !$(this).find('.lasso-component--toolbar').length > 0 ) {\n\t\t\t\t\t\t\t// if this is a map then we need to first wrap it so that we can drag the  map around\n\t\t\t\t\t\t\tif ( $(this).hasClass('aesop-map-component') ) {\n\n\t\t\t\t\t\t\t\tvar $this = $(this)\n\n\t\t\t\t\t\t\t\t// so wrap it with a aesop-compoentn aesop-map-component div\n\t\t\t\t\t\t\t\t// @todo - note once a map is inserted it can't be edited after saving again. a user has to delete the existin map and add a new map\n\t\t\t\t\t\t\t\t// to\n\t\t\t\t\t\t\t\t//$this.wrap('<form id=\"lasso--map-form\" class=\"aesop-component aesop-map-component lasso--map-drag-holder\" data-component-type=\"map\" >').before( lassoDragHandle ).after( lassoMapForm );\n\t\t\t\t\t\t\t\t$this.wrap('<div id=\"lasso--map-form\" class=\"aesop-component aesop-map-component lasso--map-drag-holder\" data-component-type=\"map\" >').before( lassoDragHandle );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t$(this).append( lasso_editor.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif ('video' == cdata['componentType']) {\n\t\t\t\t\t\t$('.aesop-video-component').fitVids();\t\t\t\n\t\t\t\t\t}\n\t\t\t\t\tif ('gallery' == cdata['componentType']) {\n\t\t\t\t\t\tget_aesop_options('gallery');\n\t\t\t\t\t}\n\t\t\t\t\tif ('gallery_pop' == cdata['componentType']) {\n\t\t\t\t\t\tget_aesop_options('gallery_pop');\n\t\t\t\t\t}\n                    if ('timeline_stop' == cdata['componentType']) {\n\t\t\t\t\t\tlasso_editor.timelineGoTime();\n\t\t\t\t\t}\n                                        \n                    // set some figures to uneditable\n                    $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\n\t\t\t\t\tlasso_editor.dirtyByComponent = true;\n\t\t\t\t} else {\n\t\t\t\t\talert(\"error\");\n\t\t\t}\n\t\t});\n\t}\n\t\n\t//reload aesop component options\n\tfunction get_aesop_options(comp)\n\t{\n\t\tvar data = {\n\t\t\t\taction: 'editus_get_ase_options',\n\t\t\t\tcomponent: comp\n\t\t};\n\t\t\t\t\t\t\n\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\tif( response ){\t\t\t\t\n\t\t\t\t\tlasso_editor.component_options[comp] = response;\n\t\t\t\t} else {\n\t\t\t\t\talert(\"error\");\n\t\t\t}\n\t\t});\n\t}\n\n\t//$('#lasso--component-settings-form').live('submit', function(e) {\n\t//jQuery(document).on('submit', '#lasso--component-settings-form', function(e){\n    jQuery(document).on('submit', '#aesop-generator-settings', function(e){\n\n\t\te.preventDefault();\n        e.stopImmediatePropagation();\n\n\t\t// store some atts\n\t\tvar $component \t= window.component\n\t\t,\tcdata \t\t= $component.data()\n\t\t,\tsaveInsert \t= $('#lasso-generator-insert')\n\t\t,\tform \t\t= $('#lasso--component-settings-form')\n\t\t,\t$this \t\t= $(this);\n\n\t\t// let people know something is happening\n\t\tsaveInsert.val(lasso_editor.strings.saving);\n\n\t\t// send the new settings to the component and update it's data attributes\n\t    $this.find('.lasso-generator-attr').each(function(){\n\n\t      \tvar optionName = $(this).closest('.lasso-option').data('option');\n\n\t      \t// save even if the entry is blank\n\t      \t//if ( '' !== $(this).val() ) {\n\t      \t//$component.attr( 'data-' + optionName, $(this).val() );\n            $component.prop( 'data-' + optionName, $(this).val() );\n\t      \t$component.data(optionName, $(this).val() );\n\t\t\t//}\n\n\t    });\n\n\t    // return the data attributes as field for the sortable item\n\t    var cleanFields = function( cdata ){\n\t    \tdelete cdata['sortableItem'];\n\t    \treturn cdata;\n\t    }\n\t\t\n\n\t    /**\n\t    *\n\t    *\tBuild a sequence that saves, adds a class, and removs the sidebar\n\t    *\t@param stall bool should we stall on save? typically used for all but the gallery component which runs an ajax call\n\t    *\t@param timeout int how long should we timeout before removing the settings sidebar\n\t    *\t@param gallery bool is this a gallery creation? otherwise let's mod the label\n\t    */\n\t    var saveSequence = function( stall, timeout, gallery ){\n\n\t    \t// add a saved class then change the save label to saved\n\t    \tvar saveActions = function(gallery){\n\n\t    \t\tsaveInsert.addClass('saved');\n\n\t    \t\tif ( true == gallery ) {\n\n\t\t\t\t\tsaveInsert.val(lasso_editor.strings.galleryCreated);\n\n\t    \t\t} else {\n\n\t\t\t\t\tsaveInsert.val(lasso_editor.strings.saved);\n\t\t\t\t}\n\t    \t}\n\n\t    \tif ( true == stall ) {\n\n\t\t\t\tsetTimeout( function(){ saveActions(); }, 500 );\n\n\t\t\t} else if ( true == gallery ) {\n\n\t\t\t\t//form.addClass('hide-all-fields').prepend('<div id=\"lasso--pagerefresh\">Gallery Created! Save your post and refresh the page to access this new gallery.</div>')\n\n\t\t\t\tsetTimeout( function(){ saveActions(true); }, 500 );\n\n\t    \t} else {\n\n\t\t    \tsaveActions();\n\n\t    \t}\n\n\t\t\tsetTimeout( function(){ $('body').removeClass('lasso-sidebar-open'); }, timeout );\n\t\t\tarticleMedium.makeUndoable();\n\t\t\tlasso_editor.dirtyByComponent = true;\n\n\t    }\n\n\t\t// make an ajax call to deal with gallery saving or creating only if it's a gallery\n\t\tif ( 'gallery' == cdata['componentType'] ) {\n\n\n\t\t\tvar data = {\n\t\t\t\taction: \t\t$('.ase-gallery-opts--create-gallery2').is(\":visible\") ? 'editus_create_gallery' : 'editus_update_gallery',\n\t\t\t\tpostid: \t\tcdata['id'],\n\t\t\t\tunique: \t\tcdata['unique'],\n\t\t\t\tfields: \t\tcleanFields(cdata),\n\t\t\t\tgallery_type:   $('#ase_gallery_type').val(),\n\t\t\t\tgallery_ids: \t$('#ase_gallery_ids').val(),\n\t\t\t\tnonce: \t\t\t$('#lasso-generator-nonce').val()\n\t\t\t}\n\t\t\tif ($('.ase-gallery-opts--create-gallery2').is(\":visible\")) {\n\t\t\t\tdata['edgallerytitle'] = document.getElementById(\"lasso--gallery__galleryname\").value;\n\t\t\t}\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\n                retData = JSON.parse(response);\n\t\t\t\tif ( 'gallery-created' == retData[\"message\"] ) {\n\t\t\t\t\tsaveSequence( false, 1000, true );\n\t\t\t\t\t// load the new gallery\n\t\t\t\t\tcdata['id'] = retData[\"id\"];\n\t\t\t\t} else if ( 'gallery-updated' == retData[\"message\"] ) {\n\t\t\t\t\tsaveSequence( false, 1000 );\n\t\t\t\t\tform.before(lasso_editor.refreshRequired);\n\t\t\t\t} else {\n\n\t\t\t\t\talert( 'error' );\n\n\t\t\t\t}\n\t\t\t\twindow.get_aesop_component_ajax(cdata);\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\t\t} else {\n\n\t\t\tsaveSequence( true, 1200 );\n\n\t\t}\n\t\t\n\t\tif ( 'image' == cdata['componentType'] || 'quote' == cdata['componentType'] || 'parallax' == cdata['componentType'] || 'chapter' == cdata['componentType'] || 'video' == cdata['componentType'] ||\n\t\t      'character' == cdata['componentType'] || 'collection' == cdata['componentType'] || 'audio' == cdata['componentType']) {\n\t\t\twindow.get_aesop_component_ajax(cdata);\n\t\t} else if ('content' == cdata['componentType']) {\n\t\t\tvar inner = component.find('.aesop-component-content-data');\n\n\t\t\tif ( inner.length != 0 ) {\n\t\t\t\tcdata['content_data'] = inner[0].innerHTML;\n\t\t\t}\n\t\t\twindow.get_aesop_component_ajax(cdata);\n\t\t} /*else if ('events' == cdata['componentType']) {\n\t\t\t//aesop events\n\t\t\talert(\"Save and Reload the page to see the update.\");\n\t\t}*/\n        else {\n            window.get_aesop_component_ajax(cdata);\n        }\n\t});\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/process-save-meta.js",
    "content": "(function( $ ) {\n\n\t$(document).on('submit', '#lasso--custom-field-form', function(e) {\n\n\t\te.preventDefault();\n\t\t$('#lasso--save').trigger('click');\n\n\t\tvar $this \t= $(this)\n\t\t,\tsubmit \t= $this.find('input[type=\"submit\"]')\n\t\t,\tstrings = lasso_editor.strings\n\t\t,\tdata\t= $this.serialize();\n\n\t\tsubmit.val( strings.saving );\n\n\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\tif( true == response.success ) {\n\n\t\t\t\tsubmit.val( strings.saved ).addClass('saved');\n\n\t\t\t\t/*console.log(response)\n\n\t\t\t\tsetTimeout(function(){\n\n\t\t\t\t\tsubmit.removeClass('saved');\n\t\t\t\t\tsubmit.val( strings.save );\n\n\t\t\t\t},1000);*/\n\t\t\t\tlocation.reload();\n\n\t\t\t}\n\n\t\t}).fail(function(xhr, err) { \n\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t});\n\n\t});\n\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/process-save-title.js",
    "content": "(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t/////////////\n\t\t// SAVE TITLE\n\t\t/////////////\n\n\t\t$(lasso_editor.titleClass).on('blur', function() {\n\n\t\t\tvar target = $(this);\n\n\t\t\tvar data = {\n\t\t\t\taction: \t\t'process_title-update_post',\n\t\t\t\tpostid: \t\tlasso_editor.postid,\n\t\t\t\ttitle:          $.trim( target.text() ),\n\t\t\t\tnonce: \t\t\tlasso_editor.titleNonce\n\t\t\t}\n\n\t\t\t/////////////\n\t\t\t//\tUPDATE THE TITLE\n\t\t\t/////////////\n\t\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\t\tif ( true == response.success ) {\n\n\t\t\t\t\tvar saveClass = 'lasso-title-saved';\n\n\t\t\t\t\ttarget.addClass(saveClass);\n\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\ttarget.removeClass(saveClass);\n\t\t\t\t\t},500);\n\t\t\t\t}\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\t\t});\n\n\t});\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/process-save.js",
    "content": "jQuery(document).ready(function($){\n\n\tvar ajaxurl \t=  lasso_editor.ajaxurl,\n\t\tsave    \t=  $('.lasso--controls__right a'),\n\t\teditor \t\t=  lasso_editor.editor,\n\t\tpostid \t\t=  lasso_editor.postid,\n\t\toldHtml \t=  $('#'+editor).html(),\n\t\twarnNoSave \t=  'You have unsaved changes!';\n\t\t\n\t// Set to true when we want to reload the current page without a warning message\n\tnoWarningReload = false;\n\n\t///////////////////////\n\t// 1. IF UNSAVED CHANGES STORE IN LOCAL STORAGE\n\t// @todo - need to account for component on the page this only accounts for text\n\t///////////////////////\n\t//$('#'+editor).live('change',function(){\n\tjQuery(document).on('change', '#'+editor, function(){\n\n\t\tvar $this = $(this),\n\t\t\tnewHtml = $this.html();\n\n\t\tif ( oldHtml !== newHtml ) {\n\n\t\t\tlocalStorage.setItem( 'lasso_backup_'+postid , newHtml );\n\t\t}\n\n\t});\n\n\t///////////////////////\n\t// 2. WARN THE USER IF THEY TRY TO NAVIGATE AWAY WITH UNSAVED CHANGES\n\t///////////////////////\n\twindow.onbeforeunload = function () {\n\n\t\tif ( localStorage.getItem( 'lasso_backup_'+postid ) && lasso_editor.userCanEdit ) {\n        \treturn warnNoSave;\n        \t$('#lasso--save').css('opacity',1);\n        }\n    }\n\t\n\t// but also clear the unsaved changes if the user does navigate away\n\twindow.onunload = function () {\n\t\tif ( localStorage.getItem( 'lasso_backup_'+postid ) && lasso_editor.userCanEdit ) {\n        \tlocalStorage.clear();\n        }\n    }\n    \n    /*function process_html(html, do_shortcodify) {\n        \t\n\t\t// take care of twitter widget\n\t\thtml = process_twitter(html);\n\t\t\t\n\t    // remove objects to ignore if they are not removed already\n\t\tif (lasso_editor.showIgnoredItems ) {\n\t\t\tvar $temp = $('<div></div>').html( html );\n\t\t\t$temp.find(lasso_editor.objectsNoSave).remove();\n\t\t\t$temp.find(lasso_editor.supportedNoSave).remove();\n\t\t\thtml = $temp.html();\n\t\t}\t\n\t\t\n\t\t// remove extra classes\n\t\t{\n\t\t\tvar $temp = $('<div></div>').html( html );\n\t\t\t$temp.find(\"a\").removeClass(\"lasso-link\");\n\t\t\t$temp.find(\"span\").removeClass(\"lasso-span\");\n\t\t\t$temp.find(\"h2\").removeClass(\"lasso-h2\");\n\t\t\t$temp.find(\"h3\").removeClass(\"lasso-h3\");\n\t\t\t$temp.find(\".lasso-noclass\").removeClass(\"lasso-noclass\");\n\t\t\t$temp.find(\".lasso-undeletable\").removeClass(\"lasso-undeletable\");\n\t\t\t$temp.find(\".lasso-component--controls, .aesop-events-edit\").remove();\n\t\t\t\n\t\t\t$temp.find('*[class=\"\"]').removeAttr('class');\n\t\t\t\n\t\t\thtml = $temp.html();\n\t\t}\n\t\t\n\t\t// remove all contenteditable attr\n\t\thtml = removeEditable(html);\n\t\t\n\t\t// if custom fields\n\t\tif (lasso_editor.customFields) {\n\t\t\tsaveCustomFields(html);\n\t\t}\n\t\t\n\t\t// shortcode ultimate\n\t\thtml = shortcodify_su(html);\n\t\t\n\t\t// shortcode aesop\n\t\thtml = do_shortcodify ? shortcodify(html) : html;\n\t\t\n\t\t\n\t\t\n\t\t// restore other shortcodes to the original shortcodes\n\t\thtml = replace_rendered_shortcodes( html );\n\n\t\t// avia editor\n\t\tif (lasso_editor.aviaEditor) {\n\t\t\thtml = shortcodify_avia(html);\n\t\t}\n        \n        // WordPress Block\n        if (lasso_editor.hasGutenberg) {\n            html = process_gutenberg(html);\n        }\n        \n        // if multi page\n        if (lasso_editor.multipages != \"-1\") {\n            var res = lasso_editor.post_content.split(\"<!--nextpage-->\");\n            var html2 = \"\";\n            res[parseInt(lasso_editor.multipages)] = html;\n            html = res.join(\"<!--nextpage-->\");\n        }\n        \n        // any user supplied filters\n\t\n\t\tif (lasso_editor.filterArray) {\n\t\t\t$(lasso_editor.filterArray).each(function(key, val){\n\t\t\t\thtml = val(html );\n\t\t\t});\n\t\t}\n        \n        return html\n    }*/\n\n\t///////////////////////\n\t// 3. SAVE OR PUBLISH OBJECT\n\t///////////////////////\n\t//$('.lasso--controls__right a:not(#lasso--exit)').live('click',function(e) {\n\t//jQuery(document).on('click', '.lasso--controls__right a:not(#lasso--exit)', function(e){\n\t//jQuery('.lasso--controls__right a:not(#lasso--exit)').on('click', function(e){\n\tjQuery(document).on('click','#lasso--save, #lasso--publish', function(e){\n\n\t\tvar warnNoSave = null;\n\n\t\te.preventDefault();\n\n\t\t// sore reference to this\n\t\tvar $this = $(this);\n\n\t\t// unwrap wp images\n\t\t/*$(\".lasso--wpimg__wrap\").each(function(){\n\n\t\t\t//if ( !$(this).hasClass('wp-caption') ) {\n\t\t\t//\t$(this).children().unwrap()\n\t\t\t//}\n\n\t\t\t$('.lasso-component--controls').remove();\n\t\t});\n\n\t\t// unwrap custom components\n\t\t$('.lasso-component').each(function(){\n\t\t\t$('.lasso-component--controls').remove();\n\t\t});*/\n\n\t\t// unwrap map from hits drag holder\n\t\t$('#lasso--map-form').each(function(){\n\n\t\t\tvar $this = $(this)\n\n\t\t\t$this.find('.lasso-component--controls, .lasso--map-form__footer ').remove()\n\n\t\t\t$this.children().unwrap()\n\t\t});\n\n\t\t// if tehre are any scrollnav sections we need to break them open so the editor doesnt save the html\n\t\t$('.scroll-nav__section').each(function(){\n\t\t\t$(this).children().unwrap();\n\t\t})\n\n\t\t// remove any notices\n\t\t$('#lasso--notice').remove();\n        \n        //remove any comp buttons\n        $('#lasso-side-comp-button').remove();\n\t\t\n\t\t$('.lasso--text-popup').remove();\n        \n        \n        \t\t// let user know someting is happening on click\n\t\t$(this).addClass('being-saved');\n\n\t\t// get the html from our div\n\t\tvar html = $('#'+editor).html(),\n\t\t\tpostid = lasso_editor.postid;\n\t\tif (!html) return;\n        \n        html =  process_html(html, $this.hasClass('shortcodify-enabled'));\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// gather the data\n\t\tvar data      = {\n\t\t\taction:    \t($this.hasClass('lasso-publish-post') && lasso_editor.can_publish) ? 'process_save_publish-content' : 'process_save_content',\n\t\t\tauthor:  \tlasso_editor.author,\n\t\t\tcontent: \thtml,\n\t\t\tpost_id:   \tpostid,\n\t\t\tnonce:     \tlasso_editor.nonce\n\t\t};\n\t\t\n\t\t\n\n\t\t// intercept if publish to confirm\n\t\tif ( $this.hasClass('lasso-publish-post') ) {\t\n\t\t\tif (lasso_editor.publishHandler) {\n\t\t\t\t// custom publish handler\n\t\t\t\tlasso_editor.publishHandler(data);\n\t\t\t} else {\n\t\t\t\tswal({\n\t\t\t\t\ttitle: lasso_editor.strings.publishPost,\n\t\t\t\t\ttype: \"info\",\n\t\t\t\t\ttext: false,\n\t\t\t\t\tshowCancelButton: true,\n\t\t\t\t\tconfirmButtonColor: \"#5bc0de\",\n\t\t\t\t\tconfirmButtonText: lasso_editor.strings.publishYes,\n\t\t\t\t\tcloseOnConfirm: true\n\t\t\t\t},\n\t\t\t\tfunction(){\n\t\t\t\t\trunSavePublish(true)\n\n\t\t\t\t});\n\t\t\t\t\n\t\t\t}\n\n\t\t} else {\n\n\t\t\trunSavePublish(false)\n\n\t\t}\n        \n        function process_html(html, do_shortcodify) {\n        \t\n            // take care of twitter widget\n            html = process_twitter(html);\n                \n            // remove objects to ignore if they are not removed already\n            if (lasso_editor.showIgnoredItems ) {\n                var $temp = $('<div></div>').html( html );\n                $temp.find(lasso_editor.objectsNoSave).remove();\n                $temp.find(lasso_editor.supportedNoSave).remove();\n                html = $temp.html();\n            }\t\n            \n            // remove extra classes\n            {\n                var $temp = $('<div></div>').html( html );\n                $temp.find(\"a\").removeClass(\"lasso-link\");\n                $temp.find(\"span\").removeClass(\"lasso-span\");\n                $temp.find(\"h2\").removeClass(\"lasso-h2\");\n                $temp.find(\"h3\").removeClass(\"lasso-h3\");\n                $temp.find(\".lasso-noclass\").removeClass(\"lasso-noclass\");\n                $temp.find(\".editus-firstp\").removeClass(\"editus-firstp\");\n                $temp.find(\".lasso-undeletable\").removeClass(\"lasso-undeletable\");\n                $temp.find(\".lasso-component--controls, .aesop-events-edit\").remove();\n                \n                $temp.find('*[class=\"\"]').removeAttr('class');\n                //process <!--more-->\n                $temp.find(\"span#more-\"+lasso_editor.postid).replaceWith( \"<!--more-->\" );\n                \n                html = $temp.html();\n            }\n            \n            // remove all contenteditable attr\n            html = removeEditable(html);\n            \n            // if custom fields\n            if (lasso_editor.customFields) {\n                saveCustomFields(html);\n            }\n            \n            // WordPress Block\n            if (lasso_editor.hasGutenberg) {\n\t\t\t\tconst reg = /<p[^>]*><!--/;\n\t\t\t\thtml = html.replace(reg,\"<!--\").replace(\"--></p>\",\"-->\");\n                html = process_gutenberg(html);\n            }\n\t\t\t\n\t\t\t//shortcodes\n\t\t\t{\n                // shortcode ultimate\n                //html = shortcodify_su(html);\n                \n                // restore other shortcodes to the original shortcodes\n                html = replace_rendered_shortcodes( html );\n                \n                // shortcode aesop\n                html = do_shortcodify ? shortcodify(html) : html;\t\n\n                // avia editor\n                if (lasso_editor.aviaEditor) {\n                    html = shortcodify_avia(html);\n                }\n            }\n            \n            // if multi page\n            if (lasso_editor.multipages != \"-1\") {\n                var res = lasso_editor.post_content.split(\"<!--nextpage-->\");\n                var html2 = \"\";\n                res[parseInt(lasso_editor.multipages)] = html;\n                html = res.join(\"<!--nextpage-->\");\n            }\n            \n            // any user supplied filters\n        \n            if (lasso_editor.filterArray) {\n                $(lasso_editor.filterArray).each(function(key, val){\n                    html = val(html );\n                });\n            }\n            \n            return html\n        }\n\n\t\t\n\t\tfunction removeComment(content) {\n\t\t\treturn content.replace(/<!--[\\s\\S]*?-->/g, \"\");\n\t\t}\n\t\t\n\t\tfunction removeEditable(content) \n\t\t{\t\n\t\t\treturn content.replace(/contenteditable=\"(false|true)\"/g, \"\");\n\t\t}\n\t\t\n\t\t// gather the custom field data and save to lasso_editor.cftosave\n\n\t\tfunction saveCustomFields(content) {\n\t\t\tvar data ={};\n\t\t\tvar customFields = lasso_editor.customFields;\n\t\t\tfor (var key in customFields) {\n\t\t\t\tvar selector ='';\n\t\t\t\tvar html = false;\n\t\t\t\tvar isimgurl = false;\n\t\t\t\tif (typeof(lasso_editor.customFields[key]) == 'object') {\n\t\t\t\t\tselector = customFields[key]['selector'];\n\t\t\t\t\thtml = customFields[key]['html'];\n\t\t\t\t\tisimgurl = customFields[key]['imgurl'];\n\t\t\t\t} else {\n\t\t\t\t\tselector =customFields[key];\n\t\t\t\t}\n\t\t\t\tvar arr = $(document).find(selector);\n\t\t\t\tif (arr.length) {\n\t\t\t\t\tif (html) {\n\t\t\t\t\t\tdata[key] = arr[0].innerHTML.replace(/[\\n\\r]/g, '');;\n\t\t\t\t\t} else if (isimgurl) {\n\t\t\t\t\t\tdata[key] = $(arr[0]).attr('src');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdata[key] = arr[0].innerText;//.replace(/[\\n\\r]/g, '');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tlasso_editor.cftosave = data;\n\t\t}\n\n\t\t/**\n\t\t \t* Turn content html into shortcodes\n\t\t \t* @param  {[type]} content  [description]\n\t\t \t* @param  {[type]} selector [description]\n\t\t \t* @return {[type]}          [description]\n\t\t*/\n\t\tfunction shortcodify(content,selector){\n\n\t\t\t// Convert the html into a series of jQuery objects\n\t\t\tvar j = $.parseHTML(content);\n\t\t\tvar processed = '';\n\t\t\tif (j == null) {\n\t\t\t\treturn content;\n\t\t\t}\n\n\t\t\t// Iterate through the array of dom objects\n\t\t\tfor (var i = 0; i < j.length; i++) {\n\n\t    \t\tvar component = $(j[i]);\n\n\t    \t\t// If it's not a component, move along\n\t    \t\tif ( !component.hasClass('aesop-component') ) {\n\t\t\t\t\t\n\t\t\t\t\tif(component.find('.aesop-component').length !== 0) {\n\t\t\t\t\t\t// if there is an aesop component in a child, recursively process it\n\t\t\t\t\t\tvar comp_content = component.html();\n\t\t\t\t\t\tcomp_content = shortcodify(comp_content);\n\t\t\t\t\t\tcomponent.html(comp_content);\n\t\t\t\t\t\tprocessed += component.clone().wrap('<p>').parent().html();;\n\t\t\t\t\t} else   \t\t\t// Let's test what kind of object it is\n                    if ( component.context && component.context.nodeType == 3 ) {\n\t    \t\t\t\t// Text only object without dom\n\t    \t\t\t\tprocessed += j[i].data;\n\t    \t\t\t} else if ( (component.context && component.context.nodeType == 8)  || j[i].nodeType==8) {\n\t    \t\t\t\tprocessed += '<!--' + j[i].data + '-->';\n\t    \t\t\t} else {\n\t    \t\t\t\t// DOM object\n                        if (j[i].outerHTML) {\n                            processed += j[i].outerHTML;\n                        } else if (j[i].data){\n                            processed += j[i].data;\n                        }\n\t    \t\t\t}\n\t    \t\t\tcontinue;\n\t    \t\t}\n\n\t    \t\tvar data = component.data();\n\t    \t\tvar params = '';\n\n\t    \t\t// It's a component, let's check to make sure it's defined properly\n\t\t\t\tif ( data.hasOwnProperty('componentType') ) {\n                    if (data.componentType ==\"wpimg\") \n                        continue;\n\n\t\t\t\t\tfor ( var index in data ) {\n\n\t\t\t\t\t\t// Don't accept componentType as a param\n\t\t\t\t\t\tif ( !data.hasOwnProperty(index) || index == 'componentType' ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Build the params string out of the data attributes\n\t\t\t\t\t\tparams += \" \" + index + '=\"' + data[index] + '\"';\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar sc = '[aesop_' + data.componentType + params + ']';\n\n\t\t\t\t\t// Let's check to see if it's a \"full\" shortcode\n\t\t\t\t\tvar inner = component.find('.aesop-component-content-data');\n\n\t\t\t\t\tif ( inner.length != 0 ) {\n\t\t\t\t\t\tsc += inner[0].innerHTML + \"[/aesop_\" + data.componentType + \"]\";\n\t\t\t\t\t}\n\n\t\t\t\t\tprocessed += sc;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn processed;\n\n\t\t}\n\t\t\n\t\tfunction process_twitter(html)\n\t\t{\n\t\t\t// if twitter widget doesn't exist return\n\t\t\tif (!html) return null;\n\t\t\tif (html.indexOf(\"twitterwidget\") ==-1) return html;\n\t\t\tvar t = $('#'+editor).clone();\n\t\t\tvar t1 = t.find('twitterwidget');\n\t\t\tvar t2 = $('#'+editor).find('twitterwidget');\n\t\t\tvar i;\n\t\t\tfor (i = 0; i<t1.length; i++) {\n\t\t\t\tvar t5 = $('<div></div>').html(t2[i].shadowRoot.innerHTML).find('.EmbeddedTweet').data('click-to-open-target');\n\t\t\t\t$(t1[i]).replaceWith(t5);\n\t\t\t}\n\t\t\t\n\t\t\tvar html2 = t.html();\n\t\t\treturn html2;\n\t\t}\n\t\t\n\t\t//shortcode ultimates\n\t\tfunction shortcodify_su(content,selector){\n\n\t\t\t// Convert the html into a series of jQuery objects\n\t\t\tvar j = $.parseHTML(content);\n\t\t\tvar processed = '';\n\n\t\t\t// Iterate through the array of dom objects\n\t\t\tfor (var i = 0; i < j.length; i++) {\n\n\t    \t\tvar component = $(j[i]);\n\n\t    \t\t// If it's not a component, move along\n\t    \t\tif ( !component.hasClass('su-box') &&  !component.hasClass('su-note') && !component.hasClass('su-document') && !component.hasClass('su-spoiler')) {\n\n\t    \t\t\t// Let's test what kind of object it is\n\t    \t\t\tif ( component.context.nodeType == 3 ) {\n\t    \t\t\t\t// Text only object without dom\n\t    \t\t\t\tprocessed += j[i].data;\n\t    \t\t\t} else if ( component.context.nodeType == 8 ) {\n\t    \t\t\t\tprocessed += '<!--' + j[i].data + '-->';\n\t    \t\t\t} else {\n\t    \t\t\t\t// DOM object\n\t    \t\t\t\tprocessed += j[i].outerHTML;\n\t    \t\t\t}\n\t    \t\t\tcontinue;\n\t    \t\t}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\tif ( component.hasClass('su-box')) {\n\t\t\t\t\tvar box_title = component.find('.su-box-title')[0].innerHTML;\n\t\t\t\t\tvar box_content = component.find('.su-box-content')[0].innerHTML;\n\t\t\t\t\tvar box_color = component.find('.su-box-title')[0].style.backgroundColor;\n\t\t\t\t\tvar sc = '[su_box title=\"'+box_title+'\"'+' box_color=\"' +box_color+'\"]' + box_content+'[/su_box]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('su-note')) {\n\t\t\t\t\tvar note_content = component.find('.su-note-inner')[0].innerHTML;\n\t\t\t\t\tnote_content = shortcodify_su(note_content);\n\t\t\t\t\tvar note_color = component.find('.su-note-inner')[0].style.backgroundColor;\n\t\t\t\t\tvar text_color = component.find('.su-note-inner')[0].style.color;\n\t\t\t\t\tvar sc = '[su_note note_color=\"'+ note_color + '\" text_color=\"'+text_color +'\"]' + note_content+'[/su_note]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('su-document')) {\n\t\t\t\t\t\n\t\t\t\t\tvar ifr = component.find('iframe.su-document')[0];\n\t\t\t\t\tvar url = getParameterByName(\"url\",ifr.src);\n\t\t\t\t\tvar width = ifr.width;\n\t\t\t\t\tvar height = ifr.height;\n\t\t\t\t\tvar sc = '[su_document url=\"'+ url + '\" width=\"'+ width +'\" height=\"' + height+'\"]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('su-spoiler')) {\n\t\t\t\t\tvar spoiler_content = component.find('.su-spoiler-content')[0].innerHTML;\n\t\t\t\t\tspoiler_content = shortcodify_su(spoiler_content);\n\t\t\t\t\tvar title = component.find('.su-spoiler-title')[0].textContent;\n\t\t\t\t\t\n\t\t\t\t\tvar sc = '[su_spoiler title=\"'+ title + '\" style=\"fancy\" open=\"no\"]' + spoiler_content+'[/su_spoiler]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t}\t\t\n\n\t\t\t}\n\n\t\t\treturn processed;\n\t\t}\n        \n        function process_gutenberg(content){\n\t\t\t// Convert the html into a series of jQuery objects\n\t\t\tvar k = $.parseHTML(content);\n\t\t\tvar processed = '';\n\t\t\tif (k == null) {\n\t\t\t\treturn content;\n\t\t\t}\n            \n            j =  $('<div>').append($(k).clone());\n            //ul\n            $(j).find(\"ul\").before('<!-- wp:list -->' ).after('<!-- /wp:list -->');\n            $(j).find(\"ol\").before('<!-- wp:list {\"ordered\":true} -->' ).after('<!-- /wp:list -->');\n            \n            \n            // columns\n            $(j).find(\".wp-block-column\").each( function(index ) {\n                var data = {};\n                if ($(this).hasClass('is-vertically-aligned-center')) {\n                    data[\"verticalAlignment\"]= \"center\";\n                }\n                if ($(this).css(\"flex-basis\")!= \"\") {\n                    data[\"width\"] = $(this).css(\"flex-basis\");\n                }\n                blockCode = \"<!-- wp:column \" + JSON.stringify(data) + \" -->\";\n    \n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:column -->\" );\n            });\n\n            $(j).find(\".wp-block-columns\").each( function(index ) {\n                var data = {};\n                if ($(this).hasClass('are-vertically-aligned-center')) {\n                    data[\"verticalAlignment\"]= \"center\";\n                }\n                blockCode = \"<!-- wp:columns \" + JSON.stringify(data) + \" -->\";\n    \n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:columns -->\" );\n            });\n            \n            //paragraph\n            $(j).find(\"p\").each( function(index ) {\n                var data = {};\n                 if ($(this).hasClass('has-text-align-center')) {\n                    data[\"align\"]= \"center\";\n                }\n                \n                blockCode = \"<!-- wp:paragraph \" + JSON.stringify(data) + \" -->\";\n    \n                $(this).before(blockCode).after(\"<!-- /wp:paragraph -->\" );\n            });\n            \n            //gallery\n            $(j).find(\".wp-block-gallery\").each( function(index ) {\n                debugger;\n                var data = {};\n                 if ($(this).hasClass('aligncenter')) {\n                    data[\"align\"]= \"center\";\n                }\n                var classes = $(this).attr('class').split(\" \");\n                for (i = 0; i < classes.length; ++i) {\n                    if (classes[i].indexOf('columns-') == 0) {\n                        data[\"columns\"] = parseInt(classes[i].substr(8));\n                    }\n                } \n                var ids = [];\n                $(this).find(\"img\").each( function(index ) {\n                    ids[index] = $(this).data('id');\n                });\n                data[\"ids\"]= ids;\n                if ($(this).find(\"a\").length ==0) {\n                    data[\"linkTo\"] = \"none\";\n                } else {\n                    data[\"linkTo\"] = \"file\";\n                }\n                blockCode = \"<!-- wp:gallery \" + JSON.stringify(data) + \" -->\";\n    \n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:gallery -->\" );\n            });\n            \n            //heading\n            $(j).find(\"h1\").before('<!-- wp:heading {\"level\":1} -->' );\n            $(j).find(\"h2\").before('<!-- wp:heading {\"level\":2} -->' );\n            $(j).find(\"h3\").before('<!-- wp:heading {\"level\":3} -->' );\n            $(j).find(\"h4\").before('<!-- wp:heading {\"level\":4} -->' );\n            $(j).find(\"h5\").before('<!-- wp:heading {\"level\":5} -->' );\n            $(j).find(\"h1,h2,h3,h4,h5\").after(\"<!-- /wp:heading -->\" );\n            \n            //table\n            $(j).find(\".wp-block-table\").before(\"<!-- wp:table -->\" ).after(\"<!-- /wp:table -->\" );\n            \n            //button\n            $(j).find(\".wp-block-button\").before(\"<!-- wp:button -->\" );\n            $(j).find(\".wp-block-button\").after(\"<!-- /wp:button -->\" );\n            $(j).find(\".wp-block-buttons\").each( function(index ) {\n                var blockCode = \"<!-- wp:buttons \";\n                var data = {};\n                if ($(this).hasClass('is-content-justification-center')) {\n                    data[\"contentJustification\"]= \"center\";\n                }\n                blockCode = blockCode + JSON.stringify(data) + \" -->\";\n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:buttons -->\" );\n            });\n              \n            //group\n            $(j).find(\".wp-block-group\").each( function(index ) {\n                var data = {};\n                if ($(this).hasClass('alignfull')) {\n                    data[\"align\"]= \"full\";\n                }\n                var blockCode = \"<!-- wp:group \" + JSON.stringify(data) + \" -->\";\n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:group -->\" );\n            });\n            \n            // spacer\n            $(j).find(\".wp-block-spacer\").before(\"<!-- wp:spacer -->\" ).after(\"<!-- /wp:spacer -->\" );\n            \n            // separator\n            $(j).find(\".wp-block-separator\").before(\"<!-- wp:separator  -->\" ).after(\"<!-- /wp:separator  -->\" );\n            \n            // image\n\t\t\t$(j).find(\".wp-block-image\").each( function(index ) {\n                $(this).removeAttr('data-component-type');\n                var data = {};\n                if ($(this).find(\"img\").length == 0) {\n                    return;\n                }\n                \n\t\t\t\tvar blockCode = \"<!-- wp:image \";\n\t\t\t\t\n\t\t\t\tvar classes = $(this).find(\"img\").attr('class').split(\" \");\n\t\t\t\t\n\t\t\t\t$(this).removeAttr('width').removeAttr('height').removeAttr('readonly');\n\t\t\t\t$(this).find(\"img\").removeAttr('width').removeAttr('height').removeAttr('srcset').removeAttr('sizes').removeAttr('loading');\n\t\t\t\tvar i;\n                for (i = 0; i < classes.length; ++i) {\n                    if (classes[i].indexOf('wp-image-') == 0) {\n                        data[\"id\"] = parseInt(classes[i].substr(9));\n                    }\n                } \n\t\t\t\tif ($(this).hasClass(\"size-large\") || $(this).find('figure').hasClass(\"size-large\")) {\n\t\t\t\t\tdata[\"sizeSlug\"] = \"large\";\n\t\t\t\t}\n                if ($(this).hasClass(\"size-full\") || $(this).find('figure').hasClass(\"size-full\")) {\n\t\t\t\t\tdata[\"sizeSlug\"] = \"full\";\n\t\t\t\t}\n                 if ($(this).find(\".aligncenter\").length>0) {\n                    data[\"align\"]=\"center\";\n                }\n                if ($(this).hasClass(\"is-style-default\")) {\n\t\t\t\t\tdata[\"className\"] = \"is-style-default\";\n\t\t\t\t}\n                if ($(this).hasClass(\"is-style-rounded\")) {\n\t\t\t\t\tdata[\"className\"] = \"is-style-rounded\";\n\t\t\t\t}\n                if ($(this).find(\".alignright\").length>0) {\n                    data[\"align\"] = \"right\";\n                }\n                if ($(this).find(\".alignleft\").length>0) {\n                    data[\"align\"] = \"left\";\n                }\n         \n                blockCode = blockCode + JSON.stringify(data) + \" -->\";\n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:image -->\" );\n            });\n            \n            // cover\n\t\t\t$(j).find(\".wp-block-cover\").each( function(index ) {\n                $(this).removeAttr('data-component-type');\n\t\t\t\tvar blockCode = \"<!-- wp:cover \";\n                var data = {};\n                \n                if ($(this).find(\"img\").length > 0) {\n\t\t\t\t    data['url'] = $(this).find(\"img\").attr('src');\n                    var classes = $(this).find(\"img\").attr('class').split(\" \");\n                    $(this).removeAttr('width').removeAttr('height');\n                    if ($(this).css(\"min-height\") == \"100vh\") {\n                        data[\"minHeight\"] =100;\n                        data[\"minHeightUnit\"] = \"vh\";\n                    }\n                    $(this).find(\"img\").removeAttr('width').removeAttr('height').removeAttr('srcset').removeAttr('sizes').removeAttr('loading');\n                    var i;\n                    for (i = 0; i < classes.length; ++i) {\n                        if (classes[i] == 'alignfull') {\n                            data['align'] = \"full\";\n                        }\n                        if (classes[i].indexOf('wp-image-') == 0) {\n                            data[\"id\"] = parseInt(classes[i].substr(9));\n                        }\n                        \n                    } \n                } else {\n                    var bg = $(this).css('background-image');\n                    bg = bg.replace('url(','').replace(')','').replace(/\\\"/gi, \"\");\n                    data['url'] = bg;\n                    var classes = $(this).attr('class').split(\" \");\n                    var i;\n                    for (i = 0; i < classes.length; ++i) {\n                        if (classes[i]=='has-parallax') {\n                             data[\"hasParallax\"] = true;\n                        }\n                        else if (classes[i]=='is-repeated') {\n                             data[\"className\"] = \"is-repeated\";\n                        }\n                    } \n                }\n\t\t\t\n                blockCode = blockCode + JSON.stringify(data) + \" -->\";\n                $(this).before(blockCode);\n                $(this).after(\"<!-- /wp:cover -->\" );\n            });\n            \n            //aesop components\n            $(j).find(\".aesop-component\").each( function(index ) {\n                var d = $(this).data();\n\t\t\t\tif (d['componentType'] == 'timeline_stop') d['componentType'] = 'timeline';\n\n                var blockCode = \"<!-- wp:ase/\"+d['componentType']+\" {\";\n                var index = 0;\n                $.each(d,function(key, value){\n                    if (key=='componentType') return;\n                    if (index>0) blockCode += \",\";\n                    blockCode+= '\"'+key+'\":\"'+value+'\" ';\n                    index++;\n                });\n                blockCode+=\"} /-->\";\n                $(this).before(blockCode);\n                $(this).remove();\n            });\n            \n            var html = $(j).html(); \n            html = html.replace(\" {} -->\",\" -->\");\n            return html;\n        }\n\t\t\n\t\t//shortcode avia layout editor\n\t\tfunction shortcodify_avia(content,selector){\n\t\t\t// Convert the html into a series of jQuery objects\n\t\t\tvar j = $.parseHTML(content);\n\t\t\tvar processed = '';\n\n\t\t\t// Iterate through the array of dom objects\n\t\t\tfor (var i = 0; i < j.length; i++) {\n\n\t    \t\tvar component = $(j[i]);\n\n\t    \t\t// If it's not a component, move along\n\t    \t\tif ( !component.hasClass('av_textblock_section') && !component.hasClass('av_toggle_section') && !component.hasClass('togglecontainer')) {\n\n\t    \t\t\t// Let's test what kind of object it is\n\t    \t\t\tif ( component.context.nodeType == 3 ) {\n\t    \t\t\t\t// Text only object without dom\n\t    \t\t\t\tprocessed += j[i].data;\n\t    \t\t\t} else if ( component.context.nodeType == 8 ) {\n\t    \t\t\t\tprocessed += '<!--' + j[i].data + '-->';\n\t    \t\t\t} else {\n\t    \t\t\t\t// DOM object\n\t    \t\t\t\tprocessed += j[i].outerHTML;\n\t    \t\t\t}\n\t    \t\t\tcontinue;\n\t    \t\t}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\tif ( component.hasClass('av_textblock_section')) {\n\t\t\t\t\tvar box_text = component.find('.avia_textblock')[0].innerHTML;\n\t\t\t\t\tvar sc = '[av_textblock]' + box_text+'[/av_textblock]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('togglecontainer')) {\n\t\t\t\t\t\n\t\t\t\t\tvar content = component[0].innerHTML;\n\t\t\t\t\tvar mode =\"accordion\";\n\t\t\t\t\tcontent = shortcodify_avia(content);\n\t\t\t\t\tif (component[0].hasClass('enable_toggles')) {\n\t\t\t\t\t\tmode = \"toggle\";\n\t\t\t\t\t}\n\t\t\t\t\tvar sc = \"[av_toggle_container mode='\"+mode+\"']\" + content+'[/av_toggle_container]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t} else if ( component.hasClass('av_toggle_section')) {\n\t\t\t\t\tvar toggle_title = component.find('.toggler')[0].innerText;\n\t\t\t\t\tvar toggle_content = component.find('.toggle_content')[0].innerHTML;\n\t\t\t\t\tvar sc = '[av_toggle title=\"'+toggle_title+'\"]' + toggle_content+'[/av_toggle]';\n\t\t\t\t\tprocessed += sc;\n\t\t\t\t\t\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn processed;\n\t\t}\n\t\t\n\t\tfunction replace_rendered_shortcodes( content ) {\n\t\t\t// also remove scripts\n\t\t\tcontent = content.replace(/<script.*>.*<\\/script>/g, \" \");\n\t\t\t\n\t\t\tif ( content.indexOf('--EDITUS_OTHER_SHORTCODE_START|' ) == -1) {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t\t\n\t\t\t/*var k = $.parseHTML(content);\n\t\t\tif (k != null) {\n\t\t\t\tj =  $('<div>').append($(k).clone());\n\t\t\t\t\n\t\t\t\t$(j).find('.editus_shortcode').each(function(){\n\t\t\t\t    var oldComment = this.previousElementSibling.innerHTML;\n\t\t\t\t\tvar re = /<!--EDITUS_OTHER_SHORTCODE_START\\|\\[(.*)\\]-->/g.exec(oldComment) ;\n\t\t\t\t\tvar cont = this.dataset.shortcode;\n\t\t\t\t\tif (cont && re && re.size>1) {\n\t\t\t\t\t\tthis.previousElementSibling.innerHTML = oldComment.replace(re[1], cont);\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\tcontent = $(j).html(); \n\t\t\t}*/\n\n\t\t\tvar re = /<!--EDITUS_OTHER_SHORTCODE_START\\|\\[([\\s\\S]*?)\\]-->([\\s\\S]*?)<!--EDITUS_OTHER_SHORTCODE_END-->/g ;\n\t\t\tif (lasso_editor.hasGutenberg) {\n\t\t\t\tcontent = content.replace(re,'<!-- wp:shortcode -->$1<!-- /wp:shortcode -->');\n\t\t\t} else {\n\t\t\t\tcontent = content.replace(re,'$1');\n\t\t\t}\n\t\t\t\n\t\t\treturn content;\n\t\t}\n\t\t\n\t\t// Save post using REST API V2\n\t\tfunction savePublishREST(postid, title, subtitle, content_, type_,status_,forcePublish){\n\t\t\t\n\t\t\tvar data      = {\n\t\t\t\tcontent: \tcontent_,\n\t\t\t\tstatus: status_\n\t\t\t};\n\t\t\tif (lasso_editor.aviaEditor) {\n\t\t\t\tdata['content'] =\"\";\n\t\t\t\tdata['metadata'] = { '_aviaLayoutBuilderCleanData': content_};\n\t\t\t}\n\t\t\t\n\t\t\t//custom fields to save\n\t\t\tif (lasso_editor.cftosave) {\n\t\t\t\tif (!data['metadata']) {\n\t\t\t\t\tdata['metadata']=  lasso_editor.cftosave;\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(data['metadata'], lasso_editor.cftosave);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tvar type;\n\t\t\tif (type_==\"post\") {\n\t\t\t\ttype = \"posts\";\n\t\t\t} else if (type_==\"page\"){\n\t\t\t\ttype = \"pages\";\n\t\t\t} else {\n\t\t\t\ttype = type_;\n\t\t\t}\n\t\t\tif (title.length>0) {\n\t\t\t\tdata['title'] = title;\n\t\t\t}\n\t\t\tif (subtitle.length>0) {\n\t\t\t\tdata['metadata'] = { '_subtitle': subtitle};\n\t\t\t}\n\t\t\t\n\t\t\tif (lasso_editor.disableSavePost == 'on') {\n\t\t\t\tdelete data['content'];\n\t\t\t}\n\t\t\t\n\t\t\t$.ajax({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\turl: lasso_editor.rest_root + 'wp/v2/'+type+'/'+postid,\n\t\t\t\tdata: data,\n\t\t\t\tbeforeSend: function ( xhr ) {\n\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce );\n\t\t\t\t},\n\t\t\t\tsuccess : function( response ) {\n\t\t\t\t\tsaveSuccess();\n                    if (forcePublish) {\n                        var data = {\n                            action: \t\t'editus_publish_post',\n                            postid: \t\tlasso_editor.postid\n                        }\n\n                        $.post( lasso_editor.ajaxurl2, data);\n                    }\n\t\t\t\t},\n\t\t\t\terror : function (xhr, exception) {\n\t\t\t\t\tconsole.log( xhr );\n\t\t\t\t\talert(\"AJAX Error: \"+xhr.responseText );\n\t\t\t\t\t$('#lasso--save').removeClass('being-saved').addClass('lasso--error');\t\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t\n\t\t// code to run when post saving is successful\n\t\tfunction saveSuccess() {\n\t\t\t// change button class to saved\n\t\t\t$('#lasso--save').removeClass('being-saved').addClass('lasso--saved');\n\n\t\t\t// if this is being published then remove the publish button afterwards\n\t\t\tif ( $this.hasClass('lasso-publish-post') ) {\n\t\t\t\t$this.remove();\n\t\t\t}\n\n\t\t\t// wait a bit then remvoe the button class so they can save again\n\t\t\tsetTimeout(function(){\n\t\t\t\t$('#lasso--save').removeClass('lasso--saved');\n\n\t\t\t\tif ( $this.hasClass('lasso-publish-post') ) {\n\t\t\t\t\tlocation.reload()\n\t\t\t\t}\n\n\t\t\t},1200);\n\n\t\t\t// then remove this copy from local stoarge\n\t\t\tlocalStorage.removeItem( 'lasso_backup_'+postid );\n\t\t\tlasso_editor.dirtyByComponent = false;\n\t\t\tarticleMedium.dirty = false;\n\t\t\tif (lasso_editor.saveSuccessHookArray) {\n\t\t\t\t$(lasso_editor.saveSuccessHookArray).each(function(key, val){\n\t\t\t\t\tval();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t\n\n\t\t// make the actual ajax call to save or publish\n\t\tfunction runSavePublish(forcePublish){\n\t\t\tif (lasso_editor.saveusingrest) {\n\t\t\t\t// get the status of the post (published/draft)\n\t\t\t\tvar status_ = $('.lasso--controls__right').data( \"status\" );\n\t\t\t\tvar title=\"\";\n\t\t\t\tif ($(lasso_editor.titleClass).length>0) {\n\t\t\t\t\ttitle = $(lasso_editor.titleClass)[0].innerText;\n\t\t\t\t}\n\t\t\t\tvar subtitle=\"\";\n\t\t\t\tif ($(lasso_editor.subtitleClass).length>0) {\n\t\t\t\t\tsubtitle = $(lasso_editor.subtitleClass)[0].innerText;\n\t\t\t\t}\n\t\t\t\tif (forcePublish) {\n\t\t\t\t\tstatus_ = \"publish\";\t\t\t\t\n\t\t\t\t\tif (!lasso_editor.can_publish) {\n\t\t\t\t\t\tstatus_ = \"pending\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsavePublishREST(lasso_editor.postid, title, subtitle, data.content, $('.lasso--controls__right').data( \"posttype\" ), status_, forcePublish);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\t$.post( ajaxurl, data, function(response) {\n\n\t\t\t\tif( true == response.success ) {\n\t\t\t\t\tsaveSuccess();\n\t\t\t\t} else {\n\t\t\t\t\t$('#lasso--save').removeClass('being-saved').addClass('lasso--error');\n\t\t\t\t}\n\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t\t$('#lasso--save').removeClass('being-saved').addClass('lasso--error');\t\t\t\t\n\t\t\t});\n\t\t}\n\n\t});\n\t\n\t\n\tjQuery(document).on('click','#lasso--post-delete', function(e){\n\t\te.preventDefault();\n\t\tvar $this = $(this);\n\t\tswal({\n\t\t\ttitle: lasso_editor.strings.deletePost,\n\t\t\ttype: \"error\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: lasso_editor.strings.deleteYes,\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\tvar data = {\n\t\t\t\taction: \t\t'editus_delete_post',\n\t\t\t\tpostid: \t\tlasso_editor.postid,\n\t\t\t\tnonce: \t\t\tlasso_editor.deletePost\n\t\t\t}\n\n\t\t\t$.post( lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\t//load home page after deleting the post\n\t\t\t\twindow.location.assign(lasso_editor.siteUrl);\n\t\t\t}).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n\n\t\t});\n\t});\n});\n\nfunction EditusFormatAJAXErrorMessage(jqXHR, exception) {\n\tif (jqXHR.status === 0) {\n\t\treturn ('AJAX Error: Not connected.\\nPlease verify your network connection.');\n\t} else if (jqXHR.status == 404) {\n\t\treturn ('AJAX Error: The requested page not found. [404]');\n\t} else if (jqXHR.status == 500) {\n\t\treturn ('AJAX Error: Internal Server Error [500].');\n\t} else if (exception === 'parsererror') {\n\t\treturn ('AJAX Error: Requested JSON parse failed.');\n\t} else if (exception === 'timeout') {\n\t\treturn ('AJAX Error: Time out error.');\n\t} else if (exception === 'abort') {\n\t\treturn ('AJAX Error: Ajax request aborted.');\n\t} else {\n\t\treturn ('AJAX Error: Uncaught Error.\\n' + jqXHR.responseText);\n\t}\n}\n"
  },
  {
    "path": "public/assets/js/source/process-wpimg.js",
    "content": "(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t// get the attachment id from teh class wp-image-XXX, where XXX is the id of the attached iamge\n\t\t// this oly works if the image was inserted from within the wordpress post editor\n\t\tvar ase_edit_frame;\n\t\tvar className;\n\n\t\t$(document).on('click', '.lasso--wpimg-edit',function(e){\n\n\t\t\te.preventDefault();\n            \n            if ($(this).parent().parent().find('img').length==0) {\n                return;\n            }\n            var id ='';\n\t\t\tvar selected_img\n\t\t\t, \tclicked = $(this)\n\t\t\t, \tcls \t\t= $(this).parent().next('img').attr('class');\n            if (cls) {\n                id = cls.match(/\\d+/);\n            }\n\n\t\t    className = e.currentTarget.parentElement.className;\n\n\t\t    // create frame\n\t\t    ase_edit_frame = wp.media.frames.ase_edit_frame = wp.media({\n\t\t      \ttitle: lasso_editor.strings.selectImage,\n\t\t      \tbutton: {\n\t\t        \ttext: lasso_editor.strings.insertImage,\n\t\t      \t},\n\t\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t\t    });\n\n\t\t    // open frame\n\t\t\tase_edit_frame.on('open',function(){\n\t\t\t\tvar selection = ase_edit_frame.state().get('selection');\n                if (id) {\n\t\t\t\t\tvar attachment = wp.media.attachment( id );\n\t\t\t\t\tattachment.fetch();\n\t\t\t\t\tselection.add( attachment ? [ attachment ] : [] );\n                }\n\t\t\t});\n\n\t\t    // update image on select\n\t\t    ase_edit_frame.on( 'select', function() {\n                // here after simple wpimg image select\n\n\t\t      \tvar attachment = ase_edit_frame.state().get('selection').first().toJSON()\n\t\t      \t,\timageURL   = undefined === attachment.sizes.large ? attachment.sizes.full.url : attachment.sizes.large.url\n\n\t\t      \t$(clicked).parent().parent().find('img').prop({\n\t\t      \t\t'src': imageURL,\n                    'srcset' :\"\",\n\t\t      \t\t'alt': attachment.alt,\n\t\t      \t\t'class': 'aligncenter size-large wp-image-'+attachment.id+''\n\t\t      \t});\n\t\t\t\t//$(\"html\").scrollTop(lasso_editor.scrollTop);\n                $('#lasso-side-comp-button,.lasso--text-popup').remove();\n                // set some figures to uneditable\n                $(\"figure.wp-block-image, figure.lasso--wpimg__wrap\").attr('contenteditable',false).attr('readonly',true);\n\n\t\t    });\n\n\t\t\tlasso_editor.scrollTop = $(window).scrollTop();\n\t\t    // Finally, open the modal\n\t\t    ase_edit_frame.open();\n\n\t\t})\n\t});\n\n})( jQuery );"
  },
  {
    "path": "public/assets/js/source/revisions.js",
    "content": "(function( $ ) {\n\n    $(document).ready(function(){\n\n        var vars \t\t= lasso_editor\n        ,\trevisions\n        , \trevision_id = 0\n        , \tnext\n        , \tprevious\n       \t, \ttotal\n\n       \trevisionList = $('#lasso--revision-list');\n\n        // method to destroy the modal\n        var destroyModal = function(){\n            $('body').removeClass('lasso-modal-open');\n            $('#lasso--revision__modal').remove();\n            $('#lasso--post-revisions').show();\n        };\n\n        // destroy loader\n\t\tfunction destroyLoader(){\n\t\t\t$('#lasso--loading').remove();\n\t\t}\n\n        //Update title/post content for a revision\n        var restoreRevision = function( revision_id ) {\n\n            if( revision_id in revisions ){\n                revision = revisions[ revision_id ];\n                $( vars.titleClass ).html( revision.post_title );\n                $( vars.article_object ).html( revision.post_content );\n                $('body').attr('data-revision', revision_id );\n\n            }\n        };\n\t\t\n\n        // modal click\n        $('#lasso--post-revisions').on('click',function(e){\n\n            e.preventDefault();\n\n            // preent double clicking and opening\n            $(this).hide();\n\n            // append revision modal\n            $('body').append(vars.revisionModal);\n\n            innerModal = $('#lasso--revision__modal .lasso--modal__inner');\n\n            // make the modal draggable\n            innerModal.draggable({ cursor:'move', opacity:0.8 });\n\n            data = {\n                action : 'process_revision_get',\n                postid : vars.postid,\n                nonce : vars.nonce\n            };\n\n            $.post( vars.ajaxurl, data, function(response) {\n\n            \t// do we have a response\n                if ( true == response.success ) {\n\n                \trevisionList = $('#lasso--revision-list');\n                \tslider       = $('#lasso--slider');\n                \tlassoHide    = $('#lasso--hide');\n\n                \t// remove any count classes\n                \tremoveRevisionCount();\n\n                \t// desroy the loader\n                \tdestroyLoader();\n\n                \t// show the button and slider\n                \tlassoHide.show();\n\n                \t// if we have revisions\n                    if ( 'object' == typeof response.data && response.data.length ) {\n\n                        revisions = response.data;\n\n                        var total = revisions.length == 1 ? 1 : revisions.length -1;\n\n                        if ( revisions.length !== 1 ) {\n\n\t                        $.each( revisions, function( i, post )  {\n\n\t                            revisionList.append( '<li class=\"lasso--jump-revision\" data-revision=\"'+i+'\"><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"'+post.modified_date+'\">' + post.modified_time + '</span></li>' )\n\n\t                        });\n\n\t\t\t\t\t\t\t// init slider and restore on slide\n\t\t\t\t\t\t    slider.slider({\n\t\t\t\t\t\t      \tmin: 0,\n\t\t\t\t\t\t      \tmax: total,\n\t\t\t\t\t\t      \tanimate:'fast',\n\t\t\t\t\t\t      \tvalue: 0,\n\t\t\t\t\t\t      \tzindex:999,\n\t\t\t\t\t\t\t    slide: function( event, ui ) {\n\t\t\t\t\t\t\t        restoreRevision( ui.value )\n\t\t\t\t\t\t\t    }\n\n\t\t\t\t\t\t    });\n\n\t\t\t\t\t\t    // restore revision and sync slider on click\n\t\t\t\t\t\t    $('.lasso--jump-revision').on('click',function(e){\n\n\t\t\t\t\t\t    \te.preventDefault();\n\n\t\t\t\t\t\t    \tvar val = $(this).data('revision');\n\n\t\t\t\t\t\t    \tslider.slider( 'value', val );\n\n\t\t\t\t\t\t    \trestoreRevision( val );\n\t\t\t\t\t\t    })\n\n\t\t\t\t\t\t    revisionList.attr('data-count', total + 1 ) // because we start at 0\n\n\t\t\t\t\t\t} else {\n\n                        \tlassoHide.hide();\n                        \tinnerModal.append( vars.noRevisionsDiv );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t    $('body').addClass('lasso--revision-count-'+revisions.length );\n\n\t\t\t\t\t    maybeRestoreCurrent();\n\n                        modalResizer();\n\n                    }else{\n                    \t$('#lasso--hide').hide()\n                       \tinnerModal.append( vars.noRevisionsDiv );\n                       \tmodalResizer();\n                    }\n\n                } else {\n\n                    alert('error');\n\n                }\n\n\n            }).fail(function(xhr, err) { \n\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t});\n\n            modalResizer();\n\n        });\n\n\t\t// select a revision and start editing\n\t\t$(document).on('click', '#lasso--select-revision', function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\tdestroyModal();\n\n\t\t\t$('#lasso--edit').trigger('click');\n\n\t\t\taddBackupNotice();\n\n\t\t}).on('click','#lasso--close-modal',function(e){\n\n\t\t\te.preventDefault();\n\t\t\tdestroyModal();\n\n\t\t});\n\n        /////////////////\n        /// EXIT SETTINGS\n        ///////////////////\n        $(document).keyup(function(e) {\n\n            if ( 27 == e.keyCode ) {\n\n                destroyModal();\n            }\n\n        });\n\n        // restore teh current revision but only if a user is editing one\n        function maybeRestoreCurrent(){\n\n        \tif( $('body').data('revision') ) {\n\n        \t\tslider.slider('value', $('body').data('revision') )\n\n        \t}\n        }\n\n        // add a backup notice if we're editing a backukp\n        function addBackupNotice(){\n\n        \tif ( !$('#lasso--notice').length ) {\n\n\t\t\t\t$(vars.article_object).before('<div id=\"lasso--notice\" class=\"lasso--notice lasso--notice-warning\">'+vars.strings.editingBackup+'</div>');\n\t\t\t}\n        }\n\n        // remove/reset revisino count\n        function removeRevisionCount(){\n\n\t        $('body').removeClass (function (index, css) {\n\t\t\t    return (css.match (/(^|\\s)lasso--revision-count-\\S+/g) || []).join(' ');\n\t\t\t});\n        }\n\n    });\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/settings-live-editing.js",
    "content": "(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t/////////////\n\t\t// LIVE EDITING COMPONENTS\n\t\t// @todo - this is hella dirty and needs to be cleaned up\n\t\t// @todo - move this mess to it's own file\n\t\t////////////\n\n\t\t$(document).on('click', '.lasso-component--settings__trigger', function(){\n\n\t\t\tvar settings \t= $('#lasso--component__settings')\n\n\t\t\t// QUOTE LIVE EDIT ///////////////////\n\t\t\t//settings.find('#aesop-generator-attr-background').live('change',function(){\n\t\t\tsettings.find('#aesop-generator-attr-background').on('change',function(){\n\t\t\t  \tcomponent.css({'background-color': $(this).val()});\n\t\t\t});\n\t\t\t//settings.find('#aesop-generator-attr-text').live('change',function(){\n\t\t\tsettings.find('#aesop-generator-attr-text').on('change',function(){\n\t\t\t  \tcomponent.css({'color': $(this).val()});\n\t\t\t});\n\t\t\tsettings.find('#aesop-generator-attr-quote').on('keyup',function(){\n\t\t\t  \tcomponent.find('blockquote span').text( $(this).val() );\n\t\t\t});\n\t\t\tsettings.find('#aesop-generator-attr-cite').on('keyup',function(){\n\n\t\t\t\tvar t = component.find('blockquote cite');\n\n\t\t\t\tif ( 0 == t.length ) {\n\n\t\t\t\t\tcomponent.find('blockquote').append( '<cite class=\"aesop-quote-component-cite\">'+$(this).val()+'</cite>' );\n\n\t\t\t\t} else {\n\t\t\t  \t\tcomponent.find('blockquote cite').text( $(this).val() );\n\t\t\t\t}\n\t\t\t});\n\t\t\tsettings.find('.aesop-quote-width > #aesop-generator-attr-width').on('keyup',function(){\n\t\t\t\tcomponent.css('width', $(this).val() );\n\t\t\t});\n\t\t\tsettings.find('.aesop-quote-type #aesop-generator-attr-type').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'pull' == value ) {\n\t\t\t\t\tcomponent.css('background-color','transparent')\n\t\t\t\t}\n\n\t\t\t\tcomponent.removeClass('aesop-quote-type-block aesop-quote-type-pull')\n\n\t\t\t\tcomponent.addClass('aesop-quote-type-'+$(this).val()+' ')\n\t\t\t});\n\n\t\t\tsettings.find('.aesop-quote-align #aesop-generator-attr-align').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'left' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-right aesop-component-align-center')\n\t\t\t\t\tcomponent.find('blockquote').removeClass('aesop-component-align-right aesop-component-align-center')\n\n\t\t\t\t} else if ( 'right' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-left aesop-component-align-center')\n\t\t\t\t\tcomponent.find('blockquote').removeClass('aesop-component-align-left aesop-component-align-center')\n\n\t\t\t\t} else if ( 'center' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-left aesop-component-align-right')\n\t\t\t\t\tcomponent.find('blockquote').removeClass('aesop-component-align-left aesop-component-align-right')\n\n\t\t\t\t}\n\t\t\t\tcomponent.addClass('aesop-component-align-'+$(this).val()+' ')\n\t\t\t\tcomponent.find('blockquote').addClass('aesop-component-align-'+$(this).val()+' ')\n\t\t\t});\n\n\t\t\t// PARALLAX LIVE EDIT ///////////////////\n\t\t\tsettings.find('.aesop-parallax-caption > #aesop-generator-attr-caption').on('keyup',function(){\n\n\n\t\t\t\tvar t = component.find('.aesop-parallax-sc-caption-wrap')\n\n\t\t\t\tif ( 0 == t.length ) {\n\n\t\t\t\t\tcomponent.find('img').after( '<figcaption class=\"aesop-parallax-sc-caption-wrap bottom-left\">'+$(this).val()+'</figcaption>' );\n\n\t\t\t\t} else {\n\t\t\t  \t\tcomponent.find('.aesop-parallax-sc-caption-wrap').text( $(this).val() );\n\t\t\t\t}\n\t\t\t})\n\t\t\tsettings.find('.aesop-parallax-captionposition > #aesop-generator-attr-captionposition').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'bottom-left' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right top-left top-right')\n\n\t\t\t\t} else if ( 'bottom-right' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-left top-left top-right')\n\n\t\t\t\t} else if ( 'top-left' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right top-right bottom-left')\n\n\t\t\t\t} else if ( 'top-right' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right bottom-left top-left')\n\n\t\t\t\t}\n\n\t\t\t\tcomponent.find('.aesop-parallax-sc-caption-wrap').addClass( value );\n\n\t\t\t})\n\n\t\t\t// IMAGE LIVE EDIT ///////////////////\n\t\t\tsettings.find('.aesop-image-caption > #aesop-generator-attr-caption').on('keyup',function(){\n\n\t\t\t\tvar t = component.find('.aesop-image-component-caption');\n\n\t\t\t\tif ( 0 == t.length ) {\n\n\t\t\t\t\tcomponent.find('img').after( '<p class=\"aesop-image-component-caption\">'+$(this).val()+'</p>' );\n\n\t\t\t\t} else {\n\t\t\t\t\tcomponent.find('.aesop-image-component-caption').text( $(this).val() );\n\t\t\t\t}\n\n\t\t\t})\n\t\t\tsettings.find('.aesop-image-imgwidth > #aesop-generator-attr-imgwidth').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-image-component-image').css('max-width', $(this).val() );\n\t\t\t})\n\t\t\tsettings.find('.aesop-image-align > #aesop-generator-attr-align').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'left' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-component-align-right aesop-component-align-center')\n\n\t\t\t\t} else if ( 'right' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-component-align-left aesop-component-align-center')\n\n\t\t\t\t} else if ( 'center' == value ) {\n\n\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-component-align-left aesop-component-align-right')\n\n\t\t\t\t}\n\n\t\t\t\tcomponent.find('.aesop-image-component-image').addClass('aesop-component-align-'+$(this).val()+' ')\n\n\t\t\t})\n\t\t\t\tsettings.find('.aesop-image-captionposition > #aesop-generator-attr-captionposition').on('change',function(){\n\n\t\t\t\t\tvar value = $(this).val();\n\n\t\t\t\t\tif ( 'left' == value ) {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-right aesop-image-component-caption-center')\n\n\t\t\t\t\t} else if ( 'right' == value ) {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-left aesop-image-component-caption-center')\n\n\t\t\t\t\t} else if ( 'center' == value ) {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-left aesop-image-component-caption-right')\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcomponent.find('.lasso-image-component-image').addClass('lasso-image-component-caption-'+value+' ');\n\t\t\t\t});\n\t\t\t\tsettings.find('.aesop-image-offset > #aesop-generator-attr-offset').on('keyup',function(){\n\n\t\t\t\t\tvar value = $(this).val();\n\n\t\t\t\t\tif ( component.find('.aesop-image-component-image').hasClass('aesop-component-align-left') ) {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').css('margin-left', $(this).val() );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tcomponent.find('.aesop-image-component-image').css('margin-right', $(this).val() );\n\t\t\t\t\t}\n\n\t\t\t\t});\n\n\n\t\t\t// CHARACTER LIVE EDIT ///////////////////\n\t\t\tsettings.find('.aesop-character-name > #aesop-generator-attr-name').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-character-title').text( $(this).val() );\n\t\t\t})\n\t\t\tsettings.find('.aesop-character-caption > #aesop-generator-attr-caption').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-character-cap').text( $(this).val() );\n\t\t\t})\n\t\t\tsettings.find('.aesop-character-align > #aesop-generator-attr-align').on('change',function(){\n\n\t\t\t\tvar value = $(this).val()\n\n\t\t\t\tif ( 'left' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-right aesop-component-align-center');\n\n\t\t\t\t} else if ( 'center' == value ) {\n\n\t\t\t\t\tcomponent.removeClass('aesop-component-align-left aesop-component-align-right');\n\n\t\t\t\t}\n\n\t\t\t\tcomponent.addClass('aesop-component-align-'+$(this).val()+' ');\n\n\t\t\t});\n\n\t\t\t// CHAPTER LIVE EDIT ///////////////////\n\t\t\tsettings.find('.aesop-chapter-title > #aesop-generator-attr-title').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-cover-title span').text( $(this).val() );\n\t\t\t})\n\t\t\tsettings.find('.aesop-chapter-subtitle > #aesop-generator-attr-subtitle').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-cover-title small').text( $(this).val() );\n\t\t\t})\n\n\t\t\t// VIDEO LIVE EDITOR /////////////////////\n\t\t\t//settings.find('.lasso-video-src > #aesop-generator-attr-src').live('change blur',function(){\n\t\t\tsettings.find('.aesop-video-src > #aesop-generator-attr-src').on('change blur',function(){\n\n\t\t\t\tval = $(this).val()\n\n\t\t\t\tif ( 'vimeo' == val ) {\n\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//player.vimeo.com/video/'+val+' ')\n\n\t\t\t\t\tinitVideoProvider( settings, component, 'vimeo' );\n\n\t\t\t\t} else if ( 'youtube' == val ) {\n\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//www.youtube.com/embed/'+val+'?rel=0&wmode=transparent')\n\n\t\t\t\t\tinitVideoProvider( settings, component, 'youtube' );\n\t\t\t\t}\n\n\t\t\t});\n\t\t\tsettings.find('.aesop-video-id > #aesop-generator-attr-id').on('keyup',function(){\n\t\t\t\tt = $('.aesop-video-src > #aesop-generator-attr-src').val();\n\t\t\t\tval = $(this).val();\n\t\t\t\tif ( 'vimeo' == t ) {\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//player.vimeo.com/video/'+val+' ')\n\t\t\t\t} else if ( 'youtube' == t ) {\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//www.youtube.com/embed/'+val+'?rel=0&wmode=transparent')\n\t\t\t\t}\n\t\t\t});\n\t\t\tsettings.find('.aesop-video-width > #aesop-generator-attr-width').on('keyup',function(){\n\t\t\t\tcomponent.find('.aesop-video-container').css('max-width', $(this).val() );\n\t\t\t});\n\n\t\t\t// CONTENT COMPONENT LIVE EDIT /////\n\t\t\t//settings.find('.lasso-content-background > #aesop-generator-attr-background').live('change',function(){\n\t\t\tsettings.find('.lasso-content-background > #aesop-generator-attr-background').on('change',function(){\n\t\t\t  \tcomponent.find('.aesop-content-comp-wrap').css({'background-color': $(this).val()});\n\t\t\t});\n\t\t\t\t//settings.find('.lasso-content-color > #aesop-generator-attr-color').live('change',function(){\n\t\t\t\tsettings.find('.aesop-content-color > #aesop-generator-attr-color').on('change',function(){\n\t\t\t\t  \tcomponent.find('.aesop-content-comp-wrap').css({'color': $(this).val()});\n\t\t\t\t});\n\t\t\t\t//settings.find('.lasso-content-height > #aesop-generator-attr-height').live('keyup',function(){\n\t\t\t\tsettings.find('.aesop-content-height > #aesop-generator-attr-height').on('keyup',function(){\n\n\t\t\t\t\tval = $(this).val()\n\n\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').css({'min-height': $(this).val()});\n\n\t\t\t\t});\n\t\t\t\t//settings.find('.lasso-content-columns > #aesop-generator-attr-columns').live('change',function(){\n\t\t\t\tsettings.find('.aesop-content-columns > #aesop-generator-attr-columns').on('change',function(){\n\n\t\t\t\t\tval = $(this).val()\n\n\t\t\t\t\tif ( '1' == val ) {\n\t\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-2 aesop-content-comp-columns-3 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-1')\n\t\t\t\t\t} else if ( '2' == val ) {\n\t\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-3 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-2')\n\t\t\t\t\t} else if ( '3' == val ) {\n\t\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-2 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-3')\n\t\t\t\t\t} else if ( '4' == val ) {\n\t\t\t\t\t\tcomponent.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-2 aesop-content-comp-columns-3').addClass('aesop-content-comp-columns-4')\n\t\t\t\t\t}\n\n\n\t\t\t\t});\n\t\t});\n\n\t\t/**\n\t\t*\n\t\t*\tSwap the video player with the correct id\n\t\t*\t@param object the global settings for this component\n\t\t*\t@param object the component we're editing\n\t\t*\t@param type string the type of video (vimeo, youtube)\n\t\t*\t@since 0.9.7\n\t\t*/\n\t\tfunction initVideoProvider( settings, component, type ){\n\n\t\t\t//settings.find('.lasso-video-id > #aesop-generator-attr-id').live('change',function(){\n\t\t\tsettings.find('.lasso-video-id > #aesop-generator-attr-id').on('change',function(){\n\n\t\t\t\tvideo_id = $(this).val()\n\n\t\t\t\tif ( 'vimeo' == type ) {\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//player.vimeo.com/video/'+video_id+' ')\n\t\t\t\t} else if ( 'youtube' == type ) {\n\t\t\t\t\tcomponent.find('iframe').attr('src', '//www.youtube.com/embed/'+video_id+'?rel=0&wmode=transparent')\n\t\t\t\t}\n\n\t\t\t})\n\t\t}\n\n\n\t});\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/settings-panel.js",
    "content": "(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\t// helper to dstry the sidebar\n\t\tvar destroySidebar = function(){\n\t\t\t$('body').removeClass('lasso-sidebar-open');\n\t\t}\n\n\t\t// close the sidebar when clicking outside of it\n\t\t$('body').on('click', '#'+lasso_editor.editor, function(){\n             //lets not for now\n\t\t\t//destroySidebar()\n\t\t});\n\n\t\t// helper to set the height of the settings panel\n\t\tvar settingsHeight = function(){\n\n\t\t\tvar settings = $('#lasso--component__settings');\n\n\t\t\tsettings.height( $(window).height() );\n\n\t\t\t$(window).resize(function(){\n\t\t\t\tsettings.height( $(window).height() );\n\t\t\t\t//$('#lasso--component__settings').perfectScrollbar('update');\n\t\t\t});\n\t\t}\n\n\t\tvar component, data;\n\n\t\t/////////////\n\t\t// OPEN COMPONENT SETTINGS\n\t\t////////////\n\t\t$(document).on('click','.lasso-component--settings__trigger',function(){\n\n\t\t\tvar settings \t= $('#lasso--component__settings')\n\t\t\tvar click       = $(this)\n\n\t\t\t// let's set our globals\n\t\t\tif ( $(this).parent().parent().hasClass('aesop-map-component') ) {\n\t\t\t\tcomponent = $(this).parent().parent().find('.aesop-component');\n\t\t\t} else {\n\t\t\t\tcomponent = $(this).closest('.aesop-component,.lasso-component,.wp-block-image,.wp-block-cover');\n\t\t\t}\n            \n            data = component.data();\n            if (!data) { return;}\n\n\t\t\t// let's force globalize this until we refactor the js\n\t\t\twindow.component = component;\n\t\t\twindow.componentClone = component.clone();\n\t\t\t\n            if (data['componentType'] == 'wpimg') {\n                if ($(component).find('figure.lasso-component').length) {\n                    data = $(component).find('figure.lasso-component').data();//'.wp-image.lasso-component').data();\n                } else if ($(component).find('img').length) {\n                    data['img'] =$(component).find('img').attr('src');\n                }\n            }\n            \n            if (data['componentType'] == 'wpimg-block') {\n\t\t\t\tif ($(component).find('img').length) {\n\t\t\t\t\tvar $img = $(component).find('img');\n                    data['img'] =$img.attr('src');\n\t\t\t\t\tdata['alt'] =$img.attr('alt');\n\t\t\t\t\tvar c = $img.attr('class');\n                    \n                    var $fig = $(component).find('figure');\n                    if ($fig.hasClass('alignright')) {\n                        data['align']='right';\n                    } else if ($fig.hasClass('aligncenter')) {\n                        data['align']='center';\n                    } else if ($fig.hasClass('alignleft')) {\n                        data['align']='left';\n                    }\n\t\t\t\t\n\t\t\t\t\tif (c && c.indexOf('wp-image-') == 0) {\n\t\t\t\t\t\tdata['id'] = c.substr(9);\n\t\t\t\t\t}\n                    if ($(component).find('figcaption').length) {\n                        data['caption'] = $(component).find('figcaption').text();\n                    }\n                    if ($(component).find('a').length) {\n                        data['link'] = $(component).find('a').attr(\"href\");\n                    }\n                }\n\t\t\t}\n            \n            if (data['componentType'] == 'wpcover-block') {\n\t\t\t\tif ($(component).find('img').length) {\n\t\t\t\t\tvar $img = $(component).find('img');\n                    data['img'] =$img.attr('src');\n                }\n\t\t\t}\n            \n            if (data['componentType'] =='wpquote') { return;}\n            \n            if (!lasso_editor.component_options) return;\n\t\t\t// special case for hero gallery\n\t\t\tif ( $(this).parent().parent().hasClass('aesop-hero-gallery-wrapper') ) {\n\t\t\t    jQuery.extend(data, $(component).find(\".fotorama\").data());\n\t\t\t}\n\n\t\t\t// add a body class\n\t\t\t$('body').toggleClass('lasso-sidebar-open');\n\n\t\t\tsettings.find('input[name=\"unique\"]').val( data['unique'] );\n\n\t\t\t// set up settings panel\n\t\t\tsettingsHeight();\n\t\t\tsettings.html( lasso_editor.component_options[data.componentType] );\n\n\t\t\t// add the type as a value in a hidden field in settings\n\t\t\tsettings.find('.component_type').val( data.componentType );\n\n\t\t\t// fade in save controls\n\t\t\t$('.lasso-buttoninsert-wrap').fadeIn(600);\n\n\t\t\t// initialize scrolbar\n\t\t\tsettings.perfectScrollbar('destroy');\n\t\t\tsettings.perfectScrollbar();\n\n\t\t\t// map the settings from the data attributes on components into appropriate settings in settings panel\n\t\t\tsettings.find('.lasso-option').each(function(){\n\n\t\t\t\tvar option = $(this).data('option');\n\t\t\t\tvar field = $(this).find('.lasso-generator-attr');\n\n\t\t\t\t// if it's a gallery data attribute map the cehcekd attribute to the right place\n\t\t\t\t// @todo - account for map stuff\n\t\t\t\tif ( 'gallery-type' == option ) {\n\n\t\t\t\t\t// this function is repeated on process-gallery-opts line 4\n\t\t\t\t\tvar value_check = function( value ){\n\n\t\t\t\t\t\tif ( 'grid' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeIn();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( 'thumbnail' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeIn();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( 'photoset' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeIn();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tif ( 'hero' == value ) {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--grid').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--thumb').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--photoset').fadeOut();\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeIn();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('.ase-gallery-opts--hero').fadeOut();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$(field).each(function(){\n\n\t\t\t\t\t\tif ( $(this).val() == data.galleryType ) {\n\n\t\t\t\t\t\t\t$(this).parent().addClass('selected')\n\t\t\t\t\t\t\t$(this).prop('checked',true);\n\n\t\t\t\t\t\t\tvalue_check( $(this).val() );\n\n\t\t\t\t\t\t\t// add the type to a hidden field\n\t\t\t\t\t\t\t$('#ase_gallery_type').val( $(this).val() )\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t});\n\n\t\t\t\t} else {\n\n\t\t\t\t\t$( field[0] ).val(data[option]);\n\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t\t////////////\n\t\t\t// SMOOTH SLIDE TO COMPONENT - @since 0.9.5\n\t\t\t///////////\n\n\t\t\t// if its a content component\n\t\t\tif ( component.hasClass('aesop-content-component') ) {\n\n\t\t\t\tvar target = component.find('.aesop-content-comp-wrap').attr('id')\n\t\t\t\t, \titem = $('#'+target)\n\n\t\t\t} else {\n\n\t\t\t\tvar item = $('#'+component.attr('id') )\n\t\t\t}\n\n            if (item.length) {\n                //$('html, body').animate({ scrollTop: item.offset().top - 50  }, 400);\n            }\n\n\t\t\t/////////////\n\t\t\t// GET GALLERY IMAGES IF ITS A GALLERY\n\t\t\t/////////////\n\n\t\t\t//if ( $(this).parent().parent().hasClass('empty-gallery') ) {\n\t\t\t\t//settings.addClass('gallery-no-images')\n\t\t\t//}\n\n\t\t\tif ( $(this).parent().parent().hasClass('aesop-gallery-component') ) {\n\n\t\t\t\tvar $this \t\t= $(this)\n\t\t\t\t,\tajaxurl \t= lasso_editor.ajaxurl\n\t\t\t\t,\tform \t\t= $('#lasso--component-settings-form.gallery')\n\t\t\t\t,\tnonce \t\t= lasso_editor.getGallImgNonce\n\t\t\t\t,\tgall_id \t= data['id']\n\n\t\t\t\tvar data      = {\n\t\t\t\t\taction:    \t'process_gallery_get-images',\n\t\t\t\t\tpost_id:   \tgall_id,\n\t\t\t\t\tnonce: \t\tnonce\n\t\t\t\t};\n\n\t\t\t\t// post ajax response with data\n\t\t\t\t$.post( ajaxurl, data, function(response) {\n\n\t\t\t\t\t$('#lasso--gallery__images').html( response.data.html );\n\n\t\t\t\t\t/////////////\n\t\t\t\t\t// CALL SORTABLE ON RECIEVED IMAGES\n\t\t\t\t\t/////////////\n\t\t\t\t\tvar\tgallery = $('#ase-gallery-images');\n\n\t\t\t\t\tgallery.ready(function(){\n\n\t\t\t\t\t\tgallery.sortable({\n\t\t\t\t\t\t\tcontainment: 'parent',\n\t\t\t\t\t\t\tcursor: 'move',\n\t\t\t\t\t\t\topacity: 0.8,\n\t\t\t\t\t\t\tplaceholder: 'ase-gallery-drop-zone',\n\t\t\t\t\t\t\tforcePlaceholderSize:true,\n\t\t\t\t\t\t\tupdate: function(){\n\t\t\t\t\t\t\t\tvar imageArray = $(this).sortable('toArray');\n\t\t\t\t\t\t  \t\t$('#ase_gallery_ids').val( imageArray );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcreate: function(){\n\t\t\t\t\t\t\t\tvar imageArray = $(this).sortable('toArray');\n\t\t\t\t\t\t  \t\t$('#ase_gallery_ids').val( imageArray );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}).fail(function(xhr, err) { \n\t\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t\t});;\n\n\t\t\t}\n\n\t\t}).on('click', '#lasso-upload-img', function( e ){\n\n\t\t    e.preventDefault();\n\n\t\t    className = e.currentTarget.parentElement.className;\n\n\t\t    var type   = $('input[name=\"component_type\"]').val()\n\n\t\t    // If the media frame already exists, reopen it.\n\t\t\tif ( typeof lasso_file_frame != 'undefined' ) {\n\t\t\t\tlasso_file_frame.close();\n\t\t\t}\n\n\t\t    // Create the media frame.\n\t\t    lasso_file_frame = wp.media.frames.file_frame = wp.media({\n\t\t      \ttitle: 'Select Image',\n\t\t      \tbutton: {\n\t\t        \ttext: 'Insert Image',\n\t\t      \t},\n\t\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n\t\t    });\n\n\t\t    // When an image is selected, run a callback.\n\t\t    lasso_file_frame.on( 'select', function() {\n\n\t\t      \tvar attachment = lasso_file_frame.state().get('selection').first().toJSON();\n\n\t\t      \t$('.aesop-generator-attr-media_upload').prop('value',attachment.url);\n\n\t\t\t\t/////////////\n\t\t\t\t// START LIVE IMAGE EDITING COMPONENTS\n\t\t\t\t// @todo - this was going to be taken care of in above but it seems we have to bind this to the file upload here?\n\t\t\t\t////////////\n\t\t      \tif ( 'parallax' == type ) {\n\n\t\t\t\t  \tcomponent.find('.aesop-parallax-sc-img').prop('src', attachment.url )\n\n\t\t      \t} else if ( 'quote' == type ) {\n\n\t\t\t\t  \tcomponent.css({\n\t\t\t\t  \t\t'background-image': 'url('+ attachment.url +')'\n\t\t\t\t  \t});\n\n\t\t      \t} else if ( 'image' == type ) {\n                    $(\"#aesop-generator-attr-img\").val(attachment.url);\n\t\t\t\t  \tcomponent.find('.aesop-image-component-image > img').prop('src', attachment.url);\n\t\t\t\t\t// new addition for panorama images\n\t\t\t\t\tcomponent.find('.paver__pano').css({'background-image': 'url('+ attachment.url +')'});\n\n\t\t      \t} else if ( 'character' == type ) {\n\n\t\t\t\t  \tcomponent.find('.aesop-character-avatar').prop('src', attachment.url)\n\n\t\t      \t} else if ( 'chapter' == type ) {\n\n\t\t      \t\tcomponent.find('.aesop-article-chapter').css({\n\t\t\t\t  \t\t'background-image': 'url('+ attachment.url +')'\n\t\t\t\t  \t});\n\n\t\t      \t}else if ( 'wpimg' == type ) {\n                    var img = window.component.find('img');\n                    if (img.length>0) {\n\t\t      \t\t   img.prop('src', attachment.url );\n                       img.prop(\"srcset\",\"\");\n                    }\n\t\t      \t}\n                else if ( 'wpimg-block' == type ) {\n                    var img = window.component.find('img');\n                    if (img.length >0) {\n\t\t      \t\t   img.prop('src', attachment.url );\n                       img.prop(\"srcset\",\"\");\n\t\t\t\t\t   if (attachment.id) {\n                           img.removeClass();\n\t\t\t\t\t\t   img.addClass(\"wp-image-\"+attachment.id);\n                           window.component.data( 'id', \"\"+attachment.id);\n\t\t\t\t\t   }\n                    }\n\t\t      \t}\n                else if ( 'wpcover-block' == type ) {\n                    var img = window.component.find('img');\n                    if (img.length >0) {\n\t\t      \t\t   img.prop('src', attachment.url );\n                       img.prop(\"srcset\",\"\");\n                       img.removeClass();\n                       img.addClass(\"wp-block-cover__image-background\");\n\t\t\t\t\t   if (attachment.id) {\n\t\t\t\t\t\t   img.addClass(\"wp-image-\"+attachment.id);\n\t\t\t\t\t   }\n                    } else {\n                       window.component.css('background-image', \"url(\"+attachment.url+\")\");\n                    }\n\n\t\t      \t}\n\t\t\t\t/////////////\n\t\t\t\t// EDN LIVE IMAGE EDITING COMPONENTS\n\t\t\t\t////////////\n\n\t\t    });\n\n\t\t    // Finally, open the modal\n\t\t\tlasso_file_frame.open();\n\t\t});\n\n\t\t// destroy panel if clicking close or overlay\n\t\t//$('#lasso--sidebar__close').live('click',function(e){\n\t\t// cancel \n\t\tjQuery(document).on('click','#lasso--sidebar__close',function(e){\n\t\t\te.preventDefault();\n\t\t\twindow.component.replaceWith(window.componentClone); //restore the state before editing\n\t\t\tdestroySidebar();\n\t\t\t$('#lasso--component__settings').perfectScrollbar('destroy');\n\t\t});\n\n});\n\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/toolbar.js",
    "content": "jQuery(function( $ ) {\n\n\tfunction saveSelection() {\n\t    if (window.getSelection) {\n\t        sel = window.getSelection();\n\t        if (sel.getRangeAt && sel.rangeCount) {\n\t            return sel.getRangeAt(0);\n\t        }\n\t    } else if (document.selection && document.selection.createRange) {\n\t        return document.selection.createRange();\n\t    }\n\t    return null;\n\t}\n\n\tfunction restoreSelection(range) {\n\t    if (range) {\n\t        if (window.getSelection) {\n\t            sel = window.getSelection();\n\t            sel.removeAllRanges();\n\t            sel.addRange(range);\n\t        } else if (document.selection && range.select) {\n\t            range.select();\n\t        }\n\t    } else {\n            if (window.getSelection) {\n    \t        sel = window.getSelection();\n    \t        if (sel.getRangeAt && sel.rangeCount) {\n    \t            window.selRange =  sel.getRangeAt(0);\n    \t        }\n            }\n\t    }\n\t}\n\t\n\t\n\t\n\tlasso_editor.checkSelection = function (saveSel) {\n\t\t/*var saveSel = saveSelection;\n\t\tif (saveSel == undefined) { \n\t\t\tsaveSel =  false;\n\t\t} */\n\t\tif (saveSel == true) {\n\t\t\twindow.selRange = saveSelection();\n\t\t}\n\n\t\tif (!window.selRange || window.selRange.collapsed) {\n\t\t\tswal({\n\t\t\t\t    title:\"\",\n\t\t\t\t\ttext: lasso_editor.strings.selectText,\n\t\t\t\t\tcloseOnConfirm: true\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tvar ifSmallWidth = function(){\n\n\t\treturn 600 <= $(window).width() ? true : false;\n\t}\n\n\tvar dropClass = function() {\n\n\t\treturn \"up\";//ifSmallWidth() ? 'up' : 'down';\n\n\t}\n\t\n\t\n\n\t/////////////\n\t/// DROP UP\n\t/////////////\n\t$(document).on('click', '#lasso-toolbar--components', function(e){\n\n\t\t$(this).toggleClass('toolbar--drop-'+dropClass() );\n        // show and hide the component list \n\t\tvar dropUp \t\t\t= $(this).find('ul');\n\t\tif ($(this).hasClass( 'toolbar--drop-'+dropClass() )) {\n\t\t\t$(dropUp).show();\n\t\t} else {\n\t\t\t$(dropUp).hide();\n\t\t}\n        var components = $(dropUp).find(\"li\").length;\n        if (components<7) {\n            $(dropUp).css('width',''+(components*42+8)+'px');\n            $(dropUp).css('left','-'+((components*42+8)/2-20)+'px');\n        }   \n\t\trestoreSelection(window.selRange);\n\t\t$('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() );\n\t\tif( !lasso_editor.isMobile) {\n\t\t\t// get the height of the list of components\n\t\t\t\n\t\t\tvar\tdropUpHeight \t= $(dropUp).height(),\n\t\t\t\tcaretSpacing  \t= 15; // this is the height of the caret\n\n\t\t\t// and adjust the drop up position as necessary\n\t\t\tif ( true == ifSmallWidth() ) {\n\n\t\t\t\t$(dropUp).css({\n\t\t\t\t\tdropUp: dropUpHeight,\n\t\t\t\t\ttop: -(dropUpHeight + caretSpacing)\n\t\t\t\t});\n\n\t\t\t}\n\t\t} else {\n\t\t\t/*$(dropUp).css({\n\t\t\t\t\tdropUp: dropUpHeight,\n\t\t\t\t\ttop: 40\n\t\t\t\t});*/\n\t\t}\n\n\n\t});\n\t\n\t\n\t\n\t// if we the side component button feature is on\n\tif (lasso_editor.buttonOnEmptyP) {\n\t\tjQuery(document).on('click', '#lasso--content p', function(e){\n\t\t\t//if the user click on a paragraph\n\t\t\tif ($(this).find(\"#lasso-side-comp-button\").length == 0) {\n\t\t\t\tlasso_editor.addComponentButton();\n\t\t\t}\n\t\t});\n\t}\n\t\n\t\n\t\n\tjQuery(document).on('mousedown', '#lasso-side-comp-button', function(){\t\n\t\t// side component button handler\n\t\twindow.selRange = saveSelection();\n\t\t$(this).toggleClass('toolbar--side' );\n        // show and hide the component list \n\t\tvar drop\t\t\t= $('#lasso-side-comp-button #lasso-toolbar--components__list');\n\t\tif (drop.length ==0) {\n\t\t\tdrop \t\t\t= $('#lasso-toolbar--components__list').clone();\n\t\t\t$(this).append(drop);\n\t\t\t\n\t\t}\n\t\t\n\t\tif ($(this).hasClass( 'toolbar--side')) {\n\t\t\t$(drop).show();\n\t\t} else {\n\t\t\t$(drop).hide();\n\t\t}\n\t\t$('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() );\n\t\t\n\t\t$(drop).css({\n\t\t\t\tleft: '30px',\n\t\t\t\ttop:'0px'\n\t\t\t});\n            \n        if ($(this).find(\"li\").length<7) {\n            $(this).find(\"ul\").css('column-count',''+$(this).find(\"ul li\").length);\n            $(this).find(\"ul\").css('width','auto');\n        }       \n\t\n\t});\n\n\t/////////////\n\t/// HTML DROP UP\n\t/////////////\n\n\t//$('#lasso-toolbar--html').live('mousedown',function(){\n\t/*jQuery(document).on('mousedown', '#lasso-toolbar--html,#lasso-toolbar--components,#lasso-toolbar--link', function(){\n\t\tif( ! $(this).hasClass('html--drop-'+dropClass() ) ) {\n\t\t\tvar article = document.getElementById(lasso_editor.editor);\n\t\t\tarticle.highlight();\n\t\t\twindow.selRange = saveSelection();\n\t\t\tif( typeof window.selRange === 'undefined' || null == window.selRange ) {\n\t\t\t\twindow.selRange = saveSelection();\n\t\t\t}\n\t\t}\n\t});*/\n\n\t//$('#lasso-toolbar--html__inner').live('focusout',function(){\n\tjQuery(document).on('focusout', '#lasso-toolbar--html__inner', function(){\n\t\trestoreSelection(window.selRange);\n\t});\n\n\t//$('#lasso-toolbar--html__inner').live('focus',function(){\n\tjQuery(document).on('focus', '#lasso-toolbar--html__inner', function(){\n\t\tvar savedSelect = saveSelection();\n\t\tif ( savedSelect && $(savedSelect.commonAncestorContainer).parents('#lasso--content').length != 0 ) {\n\t\t\twindow.selRange = saveSelection();\n\t\t}\n\t});\n\n\t$(document).on('click', '#lasso-toolbar--html', function(e){\n\n\t\t$(this).toggleClass('html--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--components').removeClass('toolbar--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() );\n\n\t\t// prevent dropup from closing\n\t\t//$('#lasso-toolbar--html__wrap').live('click',function(){\n\t\tjQuery(document).on('click', '#lasso-toolbar--html__wrap', function(){\n\t\t\treturn false;\n\t\t});\n\n\t\t$(this).find('#lasso-toolbar--html__inner').focus();\n\n\t});\n\n\t//$('.lasso-toolbar--html__cancel').live('click',function(){\n\tjQuery(document).on('click', '.lasso-toolbar--html__cancel', function(){\n\n\t\t$(this).closest('li').removeClass('html--drop-'+dropClass() );\n\n\t});\n\n\t//////////////////\n\t// HTML FORMATTING IN HTML DROP UP MENU\n\t//////////////////\n\tvar htmlItemInsert = function(markup){\n\n\t\treturn $('#lasso-toolbar--html__inner').text(markup);\n\n\t}\n\t//$('#lasso-html--h2').live('click',function(e){\n\tjQuery(document).on('click', '#lasso-html--h2', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert('<h2>H2 Heading</h2>');\n\t});\n\t//$('#lasso-html--h3').live('click',function(e){\n\tjQuery(document).on('click', '#lasso-html--h3', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert('<h3>H3 Heading</h3>');\n\t});\n\t//$('#lasso-html--ul').live('click',function(e){\n\tjQuery(document).on('click', '#lasso-html--ul', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert('<ul><li>Item</li></ul>');\n\t});\n\t//$('#lasso-html--ol').live('click',function(e){\n\tjQuery(document).on('click', '#lasso-html--ol', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert('<ol><li>Item</li></ol>');\n\t});\n\tjQuery(document).on('click', '#lasso-html--table', function(e){\n\t\te.preventDefault();\n\t\thtmlItemInsert(lasso_editor.tableCode);//'<table><tr><th>Cell 1</th><th>Cell 2</th></tr><tr><td>Cell 3</td><td>Cell 4</td></tr></table>');\n\t});\n\n\t////////////\n\t/// LINK DROP UIP\n\t////////////\n\t//$('#lasso-toolbar--link').live('mousedown',function(){\n\tjQuery(document).on('mousedown', '#lasso-toolbar--link', function(){\n\t\t$('#lasso-toolbar--components').removeClass('toolbar--drop-'+dropClass() );\n\t\t$('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() );\n\t});\n\n\t//$('#lasso-toolbar--link__inner').live('focusout',function(){\n\tjQuery(document).on('focusout', '#lasso-toolbar--link__inner', function(){\n\t\trestoreSelection(window.selRange);\n\t});\n\n\t//$('#lasso-toolbar--link__inner').live('focus',function(){\n\tjQuery(document).on('focus', '#lasso-toolbar--link__inner', function(){\n\t\tvar savedSelect = saveSelection();\n\t\tif ( savedSelect && $(savedSelect.commonAncestorContainer).parents('#lasso--content').length != 0 ) {\n\t\t\twindow.selRange = saveSelection();\n\t\t}\n\t});\n\n\t$(document).on('click', '#lasso-toolbar--link', function(e){\n\n\t\t // exit if nothing is selected\n\t\tif (!lasso_editor.checkSelection()) return false;\n\n\t\t$(this).toggleClass('link--drop-'+dropClass());\n\t\t\n\n\t\t$('#aesop-toolbar--link_newtab').unbind('mousedown').mousedown(function() {\n\t\t\t$(this).prop(\"checked\", !$(this).prop(\"checked\"));\n\t\t\treturn;\n\t\t});\n\n\t\t// prevent dropup from closing\n\t\tjQuery(document).on('click', '#lasso-toolbar--link__wrap', function(){\n\t\t\treturn false;\n\t\t});\n\n\t\t$(this).find('#lasso-toolbar--link__inner').focus();\n        if (window.selRange.startContainer.parentNode.tagName == 'A') {\n            $('#lasso-toolbar--link__inner').text(window.selRange.startContainer.parentNode.href);\n        }\n\t});\n\n\t// RESTORING LINK SELECTION\n\t//$('.lasso-editing .lasso-link').live('click',function(e){\n\tjQuery(document).on('click', '.lasso-editing .lasso-link', function(e){\n\n\t\te.preventDefault();\n\n\t\t// prevent dropup from closing\n\t\t//$('#lasso-toolbar--link__wrap').live('click',function(){\n\t\tjQuery(document).on('click', '#lasso-toolbar--link__wrap', function(){\n\t\t\treturn false;\n\t\t});\n\n\t\tvar link = $(this).attr('href');\n\n\t\t$('#lasso-toolbar--link').addClass('link--drop-'+dropClass());\n\t\t$('#lasso-toolbar--link__inner').text(link);\n\t});\n\n\t/////////////\n\t/// DELETING\n\t/////////////\n\t//$('.lasso-delete').live('click',function(e) {\n\tjQuery(document).on('click', '.lasso-delete', function(e){\n\n\t\te.preventDefault();\n\n\t\tvar $this = $(this);\n\n\t\tswal({\n\t\t\ttitle: \"Delete this component?\",\n\t\t\ttype: \"warning\",\n\t\t\ttext: false,\n\t\t\tshowCancelButton: true,\n\t\t\tconfirmButtonColor: \"#d9534f\",\n\t\t\tconfirmButtonText: \"Yes, delete it!\",\n\t\t\tcloseOnConfirm: true\n\t\t},\n\t\tfunction(){\n\n\t\t\t// remove component\n\t\t\t$this.closest('.aesop-component').remove();\n\n\t\t\t// remove wp image if its a wp image\n\t\t\t$this.closest('.lasso-component').remove();\n            \n            if ($this.parent().parent().hasClass('wp-block-image')) {\n                //$this.closest('.wp-block-image').remove();\n                $this.parent().parent().remove();\n            }\n\n\t\t});\n\n\t});\n\n\t/////////////\n\t/// CLONING\n\t/////////////\n\t//$('.lasso-clone').live('click',function(e) {\n\tjQuery(document).on('click', '.lasso-clone', function(e){\n\n\t\t// sore reference to this\n\t\tvar $this = $(this);\n\n\t\te.preventDefault();\n\n\t\t$this.closest('.aesop-component').clone().insertAfter( $(this).parent().parent() ).hide().fadeIn()\n\t\t$this.closest('.lasso-component').clone().insertAfter( $(this).parent().parent() ).hide().fadeIn()\n\n\t});\n\n});"
  },
  {
    "path": "public/assets/js/source/tour.js",
    "content": "(function( $ ) {\n\n\t$(document).ready(function(){\n\n\t\tdestroyModal = function(){\n\t\t\t$('body').removeClass('lasso-modal-open');\n\t\t\t$('#lasso--tour__modal,#lasso--all-posts__modal,#lasso--modal__overlay').remove();\n\t\t}\n\n\t\t//$('#lasso--tour__modal input[type=\"submit\"]').live('click', function(e) {\n\t\tjQuery(document).on('click', '#lasso--tour__modal input[type=\"submit\"]', function(e){\n\n\t\t\te.preventDefault();\n\n\t\t\tvar target = $(this);\n\n\t\t\tif ( !$('#hide_tour').is(':checked') ) {\n\n\t\t\t\tdestroyModal()\n\n\t\t\t} else {\n\t\t\t\tif (lasso_editor.saveusingrest) {\n\t\t\t\t\tvar data = {\n\t\t\t\t\t\taction: \t\t'process_tour_hide',\n\t\t\t\t\t\tnonce: \t\t\t$(this).data('nonce')\n\t\t\t\t\t}\n\n\t\t\t\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\t\t\t\tif ( true == response.success ) {\n\n\t\t\t\t\t\t\tdestroyModal();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}).fail(function(xhr, err) { \n\t\t\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tvar data = {\n\t\t\t\t\t\taction: \t\t'process_tour_hide',\n\t\t\t\t\t\tnonce: \t\t\t$(this).data('nonce')\n\t\t\t\t\t}\n\n\t\t\t\t\t$.post( lasso_editor.ajaxurl, data, function(response) {\n\n\t\t\t\t\t\tif ( true == response.success ) {\n\n\t\t\t\t\t\t\tdestroyModal();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}).fail(function(xhr, err) { \n\t\t\t\t\t\tvar responseTitle= $(xhr.responseText).filter('title').get(0);\n\t\t\t\t\t\talert($(responseTitle).text() + \"\\n\" + EditusFormatAJAXErrorMessage(xhr, err) );\n\t\t\t\t\t});\t\t\t\t\n\t\t\t\t}\n\t\t\t}\n\n\t\t});\n\n\t});\n\n})( jQuery );\n\n(function( $ ) {\n\tjQuery(document).ready(function($){\n\t\tif ( $( \"#lasso--tour__slides\" ).length ) {\n\n\t\t\t$('body').addClass('lasso-modal-open');\n\n\t\t\t$('.lasso--loading').remove();\n\t\t\t$('#lasso--tour__slides').hide().fadeIn()\n\n\t\t\t$('#lasso--tour__slides').unslider({\n\t\t\t\tdots: true,\n\t\t\t\tdelay:7000\n\t\t\t});\n\t\t}\n\t});\n})( jQuery );\n"
  },
  {
    "path": "public/assets/js/source/util--color-picker.js",
    "content": "//color picker\n(function(global) {\n\n  // @todo: bind in as a build step, so css is readable\n  var basicCSS = '.vanilla-color-picker { display: inline-block; position: absolute; padding: 5px; background-color: #fff; box-shadow: 1px 1px 2px 1px rgba(0,0,0,0.3) } .vanilla-color-picker-single-color { display: inline-block; width: 20px; height: 20px; margin: 1px; border-radius: 2px; z-index: 100 }';\n  function singleColorTpl(color, index, picked) {\n    var pickedClass = picked ? \"vanilla-color-picker-single-color-picked\" : '';\n    return '<div class=\"vanilla-color-picker-single-color ' + pickedClass + '\" tabindex=\"' + index + '\" data-color=\"' + color + '\" style=\"background-color:' + color + '\"></div>';\n  }\n  var DEFAULT_COLORS = ['red', 'yellow', 'green'];\n\n  function addBasicStyling() {\n    if (document.getElementById('vanilla-color-picker-style')) {\n      return;\n    }\n    var style = document.createElement('style');\n    style.setAttribute('type', 'text/css');\n    style.setAttribute('id', 'vanilla-color-picker-style');\n    style.innerHTML = basicCSS;\n    var firstInHead = global.document.head.children[0];\n    if (firstInHead) {\n      global.document.head.insertBefore(style, firstInHead);\n    } else {\n      global.document.head.appendChild(style);\n    }\n    \n  }\n\n  function MessageMediator() {\n    this.subscribers = {};\n    this.on = function(eventName, callback) {\n      this.subscribers[eventName] = this.subscribers[eventName] || [];\n      this.subscribers[eventName].push(callback);\n      return this;\n    };\n\n    this.emit = function(eventName) {\n      var arguments_ = arguments;\n      (this.subscribers[eventName] || []).forEach(function(callback) {\n        callback.apply(null, Array.prototype.splice.call(arguments_, 1));\n      });\n    };\n  }\n\n  function SinglePicker(elem, colors, className) {\n    MessageMediator.apply(this);\n    this.targetElem = elem;\n    this.elem = null;\n    var this_ = this;\n\n    this._initialize = function() {\n      this._createPickerElement();\n\n      this._positionPickerElement();\n      this._addEventListeners();\n    };\n\n    this.destroy = function() {\n      try {\n        this.elem.parentNode.removeChild(this.elem);\n      }\n      catch (e) {\n        // http://stackoverflow.com/a/22934552\n      }\n    };\n\n    this._positionPickerElement = function() {\n      var left = this.targetElem.offsetLeft;\n      var top = this.targetElem.offsetTop;\n      var height = this.targetElem.offsetHeight;\n      this.elem.style.left = left + 'px';\n      this.elem.style.top = (top - this.elem.offsetHeight-5) + 'px';\n\t  //this.elem.style.bottom = (this.targetElem.offsetBottom) + 'px';\n    };\n\n    this._onFocusLost = function() {\n      setTimeout(function() {\n        if (this_.elem.contains(document.activeElement)) {\n          // because blur is not propagating\n          document.activeElement.addEventListener('blur', this_._onFocusLost);\n        } else {\n          this_.emit('lostFocus');\n        }\n      }, 1);\n    };\n\n    this._createPickerElement = function() {\n      this.elem = document.createElement('div');\n      this.elem.classList.add('vanilla-color-picker');\n      if (className) {\n        this.elem.classList.add(className);\n      }\n\n      var currentlyChosenColorIndex = colors.indexOf(this.targetElem.dataset.vanillaPickerColor);\n\n      for (var i = 0; i < colors.length; i++) {\n        this.elem.innerHTML += singleColorTpl(colors[i], i + 1, i == currentlyChosenColorIndex);\n      }\n      this.targetElem.parentNode.appendChild(this.elem);\n      this.elem.setAttribute('tabindex', 1);\n\n      var toFocus = currentlyChosenColorIndex > -1 ? currentlyChosenColorIndex : 0;\n\n      this.elem.children[toFocus].focus();\n      this.elem.children[toFocus].addEventListener('blur', this_._onFocusLost);\n    };\n\n    this._addEventListeners = function() {\n      var _this = this;\n      this.elem.addEventListener('click', function(e) {\n        if (e.target.classList.contains('vanilla-color-picker-single-color')) {\n          _this.emit('colorChosen', e.target.dataset.color); \n        }\n      });\n      this.elem.addEventListener('keydown', function(e) {\n        var ENTER = 13;\n        var ESC = 27;\n        var keyCode = e.which || e.keyCode;\n        if (keyCode == ENTER) {\n          _this.emit('colorChosen', e.target.dataset.color); \n        }\n        if(keyCode == ESC) {\n          _this.emit('lostFocus');\n        }\n      });\n    };\n\n    this._initialize();\n  }\n\n  function PickerHolder(elem) {\n    MessageMediator.apply(this);\n    // an alias for more intuitivity\n    this.set = this.emit;\n\n    this.colors = DEFAULT_COLORS;\n    this.className = '';\n    this.elem = elem;\n    this.currentPicker = null;\n    var this_ = this;\n\n    this._initialize = function() {\n      this._addEventListeners();\n    };\n\n    this._addEventListeners = function() {\n      this.elem.addEventListener('click', this.openPicker);\n      this.elem.addEventListener('focus', this.openPicker);\n      this.on('customColors', function(colors) {\n        if (!(colors instanceof Array)) {\n          throw new Error('Colors must be an array');\n        }\n        this_.colors = colors;\n      });\n      this.on('defaultColor', function(color) {\n        if (!this_.elem.dataset.vanillaPickerColor) {\n          this_._updateElemState(color);\n          this_.emit('colorChosen', color, this_.elem);\n        }\n      });\n      this.on('className', function(className) {\n        this_.className = className;\n      });\n    };\n\n    this._updateElemState = function(color) {\n      this.elem.dataset.vanillaPickerColor = color;\n      this.elem.value = color;\n    };\n\n    this.destroyPicker = function() {\n      if (!this_.currentPicker){\n        return;\n      }\n      this_.currentPicker.destroy();\n      this_.currentPicker = null;\n      this_.emit('pickerClosed');\n    };\n\n    this.openPicker = function() {\n      if (this_.currentPicker) {\n        return;\n      }\n      this_.currentPicker = new SinglePicker(this_.elem, this_.colors, this_.className);\n      this_.currentPicker.on('colorChosen', function(color) {\n        this_._updateElemState(color);\n        this_.destroyPicker();\n        this_.emit('colorChosen', color, this_.elem);\n      });\n      this_.currentPicker.on('lostFocus', function() {\n        this_.destroyPicker();\n      });\n      this_.emit('pickerCreated');\n    };\n\n    this._initialize();\n  }\n\n  function vanillaColorPicker(element, options) {\n    // @todo: move from here\n    addBasicStyling();\n    return new PickerHolder(element, options);\n  }\n\n  if (global.define && global.define.amd) {\n    define([], function() {\n      return vanillaColorPicker;\n    });\n  } else {\n    global.vanillaColorPicker = vanillaColorPicker;\n  }\n})(this || window);\n"
  },
  {
    "path": "public/assets/js/source/util--content-editable.js",
    "content": "/*\n * Medium.js\n *\n * Copyright 2013, Jacob Kelley - http://jakiestfu.com/\n * Released under the MIT Licence\n * http://opensource.org/licenses/MIT\n *\n * Github:  http://github.com/jakiestfu/Medium.js/\n * Version: 1.0\n */\n\n(function (w, d) {\n\t'use strict';\n\t\n\t// check if the selection contains noneditable element\n\tfunction checkNonEditable(e, selRange) {\n\t\tvar i =0;\n\t\tvar nodes = selRange.cloneContents().querySelectorAll(\"[contenteditable='false']\");\n\t\tfor (i =0; i< nodes.length; i++) {\n\t\t\tif (nodes[i].tagName !=\"A\") {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\t\n\tfunction checkBackspaceForNoEditable(elem)\n\t{\n\t\tvar elem = elem.previousElementSibling;\n\t\twhile (elem) {\n\t\t   if ((elem.contentEditable == \"false\" || elem.readonly == \"true\" || elem.classList.contains('lasso-undeletable')) && elem.tagName !=\"A\") {\n\t\t\t   return true;\n\t\t   }\n\t\t   if (elem.innerHTML.includes(\"<!--\") || jQuery.trim( elem.innerHTML)==\"\"){\n\t\t\t   elem = elem.previousElementSibling;\n\t\t   } else {\n\t\t\t   return false;\n\t\t   }\n\t\t};\n\t\treturn false;\n\t}\n\t\n\tfunction checkDeleteForNoEditable(elem)\n\t{\n\t\tvar elem = elem.nextElementSibling;\n\t\twhile (elem) {\n\t\t   if ((elem.contentEditable == \"false\" || elem.readonly == \"true\" || elem.classList.contains('lasso-undeletable')) && elem.tagName !=\"A\"){\n\t\t\t   return true;\n\t\t   }\n\t\t   if (elem.innerHTML.includes(\"<!--\") || jQuery.trim( elem.innerHTML)==\"\"){\n\t\t\t   elem = elem.nextElementSibling;\n\t\t   } else {\n\t\t\t   return false;\n\t\t   }\n\t\t};\n\t\treturn false;\n\t}\n\t\n\tvar Medium = (function () {\n\t\t\n\t\tvar trim = function (string) {\n\t\t\t\treturn string.replace(/^\\s+|\\s+$/g, '');\n\t\t\t},\n\t\t\tarrayContains = function (array, variable) {\n\t\t\t\tvar i = array.length;\n\t\t\t\twhile (i--) {\n\t\t\t\t\tif (array[i] === variable) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t    //two modes, wild (native) or domesticated (rangy + undo.js)\n\t\t\trangy = w['rangy'] || null,\n\t\t\tundo = w['Undo'] || null,\n\t\t\twild = (!rangy || !undo),\n\t\t\tdomesticated = (!wild),\n\t\t\tkey = w.Key = {\n\t\t\t\t'backspace': 8,\n\t\t\t\t'tab': 9,\n\t\t\t\t'enter': 13,\n\t\t\t\t'shift': 16,\n\t\t\t\t'ctrl': 17,\n\t\t\t\t'alt': 18,\n\t\t\t\t'pause': 19,\n\t\t\t\t'capsLock': 20,\n\t\t\t\t'escape': 27,\n\t\t\t\t'pageUp': 33,\n\t\t\t\t'pageDown': 34,\n\t\t\t\t'end': 35,\n\t\t\t\t'home': 36,\n\t\t\t\t'leftArrow': 37,\n\t\t\t\t'upArrow': 38,\n\t\t\t\t'rightArrow': 39,\n\t\t\t\t'downArrow': 40,\n\t\t\t\t'insert': 45,\n\t\t\t\t'delete': 46,\n\t\t\t\t'0': 48,\n\t\t\t\t'1': 49,\n\t\t\t\t'2': 50,\n\t\t\t\t'3': 51,\n\t\t\t\t'4': 52,\n\t\t\t\t'5': 53,\n\t\t\t\t'6': 54,\n\t\t\t\t'7': 55,\n\t\t\t\t'8': 56,\n\t\t\t\t'9': 57,\n\t\t\t\t'a': 65,\n\t\t\t\t'b': 66,\n\t\t\t\t'c': 67,\n\t\t\t\t'd': 68,\n\t\t\t\t'e': 69,\n\t\t\t\t'f': 70,\n\t\t\t\t'g': 71,\n\t\t\t\t'h': 72,\n\t\t\t\t'i': 73,\n\t\t\t\t'j': 74,\n\t\t\t\t'k': 75,\n\t\t\t\t'l': 76,\n\t\t\t\t'm': 77,\n\t\t\t\t'n': 78,\n\t\t\t\t'o': 79,\n\t\t\t\t'p': 80,\n\t\t\t\t'q': 81,\n\t\t\t\t'r': 82,\n\t\t\t\t's': 83,\n\t\t\t\t't': 84,\n\t\t\t\t'u': 85,\n\t\t\t\t'v': 86,\n\t\t\t\t'w': 87,\n\t\t\t\t'x': 88,\n\t\t\t\t'y': 89,\n\t\t\t\t'z': 90,\n\t\t\t\t'leftWindow': 91,\n\t\t\t\t'rightWindowKey': 92,\n\t\t\t\t'select': 93,\n\t\t\t\t'numpad0': 96,\n\t\t\t\t'numpad1': 97,\n\t\t\t\t'numpad2': 98,\n\t\t\t\t'numpad3': 99,\n\t\t\t\t'numpad4': 100,\n\t\t\t\t'numpad5': 101,\n\t\t\t\t'numpad6': 102,\n\t\t\t\t'numpad7': 103,\n\t\t\t\t'numpad8': 104,\n\t\t\t\t'numpad9': 105,\n\t\t\t\t'multiply': 106,\n\t\t\t\t'add': 107,\n\t\t\t\t'subtract': 109,\n\t\t\t\t'decimalPoint': 110,\n\t\t\t\t'divide': 111,\n\t\t\t\t'f1': 112,\n\t\t\t\t'f2': 113,\n\t\t\t\t'f3': 114,\n\t\t\t\t'f4': 115,\n\t\t\t\t'f5': 116,\n\t\t\t\t'f6': 117,\n\t\t\t\t'f7': 118,\n\t\t\t\t'f8': 119,\n\t\t\t\t'f9': 120,\n\t\t\t\t'f10': 121,\n\t\t\t\t'f11': 122,\n\t\t\t\t'f12': 123,\n\t\t\t\t'numLock': 144,\n\t\t\t\t'scrollLock': 145,\n\t\t\t\t'semiColon': 186,\n\t\t\t\t'equalSign': 187,\n\t\t\t\t'comma': 188,\n\t\t\t\t'dash': 189,\n\t\t\t\t'period': 190,\n\t\t\t\t'forwardSlash': 191,\n\t\t\t\t'graveAccent': 192,\n\t\t\t\t'openBracket': 219,\n\t\t\t\t'backSlash': 220,\n\t\t\t\t'closeBraket': 221,\n\t\t\t\t'singleQuote': 222\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Medium.js - Taking control of content editable\n\t\t\t * @constructor\n\t\t\t * @param {Object} [userSettings] user options\n\t\t\t */\n\t\t\tMedium = function (userSettings) {\n\t\t\t\tvar medium = this,\n\t\t\t\t\taction = new Medium.Action(),\n\t\t\t\t\tcache = new Medium.Cache(),\n\t\t\t\t\tcursor = new Medium.Cursor(),\n\t\t\t\t\thtml = new Medium.HtmlAssistant(),\n\t\t\t\t\tutils = new Medium.Utilities(),\n\t\t\t\t\tselection = new Medium.Selection(),\n\t\t\t\t\tintercept = {\n\t\t\t\t\t\tfocus: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\t\t\t\t\t\t\tMedium.activeElement = el;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tblur: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\t\t\t\t\t\t\tif (Medium.activeElement === el) {\n\t\t\t\t\t\t\t\tMedium.activeElement = null;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\thtml.placeholders();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdown: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\n\t\t\t\t\t\t\tvar keepEvent = true;\n\n\t\t\t\t\t\t\t//in Chrome it sends out this event before every regular event, not sure why\n\t\t\t\t\t\t\tif (e.keyCode === 229) return;\n\n\t\t\t\t\t\t\tutils.isCommand(e, function () {\n\t\t\t\t\t\t\t\tcache.cmd = true;\n\t\t\t\t\t\t\t}, function () {\n\t\t\t\t\t\t\t\tcache.cmd = false;\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tutils.isShift(e, function () {\n\t\t\t\t\t\t\t\tcache.shift = true;\n\t\t\t\t\t\t\t}, function () {\n\t\t\t\t\t\t\t\tcache.shift = false;\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tutils.isModifier(e, function (cmd) {\n\t\t\t\t\t\t\t\tif (cache.cmd) {\n\n\t\t\t\t\t\t\t\t\tif (( (settings.mode === Medium.inlineMode) || (settings.mode === Medium.partialMode) ) && cmd !== \"paste\") {\n\t\t\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tvar cmdType = typeof cmd,\n\t\t\t\t\t\t\t\t\t\tfn = null;\n\n\t\t\t\t\t\t\t\t\tif (cmdType === \"function\") {\n\t\t\t\t\t\t\t\t\t\tfn = cmd;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tfn = intercept.command[cmd];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tkeepEvent = fn.call(medium, e);\n\n\t\t\t\t\t\t\t\t\tif (keepEvent === false) {\n\t\t\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t\t\tutils.stopPropagation(e);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (settings.maxLength !== -1) {\n\t\t\t\t\t\t\t\tvar len = html.text().length,\n\t\t\t\t\t\t\t\t\thasSelection = false,\n\t\t\t\t\t\t\t\t\tselection = w.getSelection();\n\n\t\t\t\t\t\t\t\tif (selection) {\n\t\t\t\t\t\t\t\t\thasSelection = !selection.isCollapsed;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (len >= settings.maxLength && !utils.isSpecial(e) && !utils.isNavigational(e) && !hasSelection) {\n\t\t\t\t\t\t\t\t\treturn utils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tswitch (e.keyCode) {\n\t\t\t\t\t\t\t\tcase key['enter']:\n                                    //disable enter inside FIGURE\n                                    var sel = w.getSelection();\n\t\t\t\t\t\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\t\t\t\t\t\tvar selRange = sel.getRangeAt(0);\n                                        if (window.getSelection().isCollapsed) {\n                                            var container = selRange.endContainer;\n                                            if (container.nodeName==\"FIGURE\") {\n\n                                                e.preventDefault();\n                                                break;\n                                            }\n                                        }\n                                    }\n\t\t\t\t\t\t\t\t\tintercept.enterKey(e);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase key['backspace']:\n\t\t\t\t\t\t\t\tcase key['delete']:\n\t\t\t\t\t\t\t\t    // we do this to prevent non editable elments being deleted\n\t\t\t\t\t\t\t\t\tif (lasso_editor.readOnlyExists) {\n\t\t\t\t\t\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\t\t\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\t\t\t\t\t\t\tvar selRange = sel.getRangeAt(0);\n\t\t\t\t\t\t\t\t\t\t\tif (window.getSelection().isCollapsed) {\n\t\t\t\t\t\t\t\t\t\t\t\tvar container = selRange.endContainer;\n\t\t\t\t\t\t\t\t\t\t\t\tvar container1 = container;\n\t\t\t\t\t\t\t\t\t\t\t\twhile (container && container.parentNode !== articleMedium.element) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tvar nodes = container.parentNode.querySelectorAll(\"[contenteditable='false']\");\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (nodes.length >0) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer = container.parentNode;\n\t\t\t\t\t\t\t\t\t\t\t\t} \t\n\t\t\t\t\t\t\t\t\t\t\t\tif (container.contentEditable == \"false\") {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\tif (e.keyCode == key['backspace'] && checkBackspaceForNoEditable(container)){\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (sel.focusOffset == 0 ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (container1.length == sel.focusOffset && container1.length == 1) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer1.data = \"\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t} else if (e.keyCode == key['delete'] &&  checkDeleteForNoEditable(container)) {\n\t\t\t\t\t\t\t\t\t\t\t\t    if (sel.focusOffset == sel.focusNode.length || sel.focusNode.length === undefined) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (container1.length == 1 && sel.focusOffset == 0){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer1.data = \"\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t// check if the selection contains noneditable element\n\t\t\t\t\t\t\t\t\t\t\t\tif (checkNonEditable(e,selRange)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t   break;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// the undeletable elements can be edited unlike the readonly elements, but should not be deleted\n\t\t\t\t\t\t\t\t\t// they are marked with class lasso-undeletable\n\t\t\t\t\t\t\t\t\tif (lasso_editor.undeletableExists) {\n\t\t\t\t\t\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\t\t\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\t\t\t\t\t\t\tvar selRange = sel.getRangeAt(0);\n\t\t\t\t\t\t\t\t\t\t\tif (window.getSelection().isCollapsed) {\n\t\t\t\t\t\t\t\t\t\t\t\tvar container1 = selRange.endContainer;\n\t\t\t\t\t\t\t\t\t\t\t\tvar container = container1.parentNode;\n\t\t\t\t\t\t\t\t\t\t\t\twhile (container !== articleMedium.element) {\t\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (container.classList.contains('lasso-undeletable')) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (e.keyCode == key['backspace']) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (sel.focusOffset == 0 ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (container1.length == sel.focusOffset && container1.length == 1) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer1.data = \"\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (e.keyCode == key['delete']) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (sel.focusOffset == sel.focusNode.length || sel.focusNode.length === undefined) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else if (container1.length == 1 && sel.focusOffset == 0){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer1.data = \"\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontainer = container.parentNode;\n\t\t\t\t\t\t\t\t\t\t\t\t} \t\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t// check if the selection contains non deletable element\n\t\t\t\t\t\t\t\t\t\t\t\tvar nodes = selRange.cloneContents().querySelectorAll(\".lasso-undeletable\");\n\t\t\t\t\t\t\t\t\t\t\t\tif (nodes.length) {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tintercept.backspaceOrDeleteKey(e);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tdefault: \n\t\t\t\t\t\t\t\t\tif (lasso_editor.readOnlyExists || lasso_editor.undeletableExists) {\n\t\t\t\t\t\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\t\t\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\t\t\t\t\t\t\tvar selRange = sel.getRangeAt(0);\n\t\t\t\t\t\t\t\t\t\t\tif (!window.getSelection().isCollapsed) {\n\t\t\t\t\t\t\t\t\t\t\t\tif (checkNonEditable(e, selRange)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\t\t}\t\n\t\t\t\t\t\t\t\t\t\t\t\t// check if the selection contains non deletable element\n\t\t\t\t\t\t\t\t\t\t\t\tvar nodes = selRange.cloneContents().querySelectorAll(\".lasso-undeletable\");\n\t\t\t\t\t\t\t\t\t\t\t\tif (nodes.length) {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn keepEvent;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tup: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\t\t\t\t\t\t\tutils.isCommand(e, function () {\n\t\t\t\t\t\t\t\tcache.cmd = false;\n\t\t\t\t\t\t\t}, function () {\n\t\t\t\t\t\t\t\tcache.cmd = true;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\thtml.placeholders();\n\n\t\t\t\t\t\t\t//here we have a key context, so if you need to create your own object within a specific context it is doable\n\t\t\t\t\t\t\tvar keyContext;\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tsettings.keyContext !== null\n\t\t\t\t\t\t\t\t&& ( keyContext = settings.keyContext[e.keyCode] )\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tvar el = cursor.parent();\n\n\t\t\t\t\t\t\t\tif (el) {\n\t\t\t\t\t\t\t\t\tkeyContext.call(medium, e, el);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n                            \n                            lasso_editor.checkForPopup();\n\n\t\t\t\t\t\t\taction.preserveElementFocus();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcommand: {\n\t\t\t\t\t\t\tbold: function (e) {\n\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t// IE uses strong instead of b\n\t\t\t\t\t\t\t\t(new Medium.Element(medium, 'bold'))\n\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t.invoke(settings.beforeInvokeElement);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tunderline: function (e) {\n\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t(new Medium.Element(medium, 'underline'))\n\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t.invoke(settings.beforeInvokeElement);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\titalicize: function (e) {\n\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\t(new Medium.Element(medium, 'italic'))\n\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t.invoke(settings.beforeInvokeElement);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tquote: function (e) {\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tpaste: function (e) {\n\t\t\t\t\t\t\t\tmedium.makeUndoable();\n\t\t\t\t\t\t\t\t/*if (settings.pasteAsText) {\n\t\t\t\t\t\t\t\t\tvar sel = utils.selection.saveSelection();\n\t\t\t\t\t\t\t\t\tutils.pasteHook(function (text) {\n\t\t\t\t\t\t\t\t\t\tutils.selection.restoreSelection(sel);\n\n\t\t\t\t\t\t\t\t\t\ttext = text.replace(/\\n/g, '<br>');\n\n\t\t\t\t\t\t\t\t\t\t(new Medium.Html(medium, text))\n\t\t\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t\t\t.insert(settings.beforeInsertHtml, true);\n\n\t\t\t\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\t\t\t\thtml.placeholders();\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\t\t\thtml.placeholders();\n\t\t\t\t\t\t\t\t}*/\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tenterKey: function (e) {\n\t\t\t\t\t\t\tif (settings.mode === Medium.inlineMode) {\n\t\t\t\t\t\t\t\treturn utils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!cache.shift) {\n\n\t\t\t\t\t\t\t\tvar focusedElement = html.atCaret() || {},\n\t\t\t\t\t\t\t\t\tchildren = el.children,\n\t\t\t\t\t\t\t\t\tlastChild = focusedElement === el.lastChild ? el.lastChild : null,\n\t\t\t\t\t\t\t\t\tmakeHR,\n\t\t\t\t\t\t\t\t\tsecondToLast,\n\t\t\t\t\t\t\t\t\tparagraph;\n\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tlastChild\n\t\t\t\t\t\t\t\t\t&& lastChild !== el.firstChild\n\t\t\t\t\t\t\t\t\t&& settings.autoHR\n\t\t\t\t\t\t\t\t\t&& settings.mode !== 'partial'\n\t\t\t\t\t\t\t\t\t&& settings.tags.horizontalRule\n\t\t\t\t\t\t\t\t) {\n\n\t\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\n\t\t\t\t\t\t\t\t\tmakeHR =\n\t\t\t\t\t\t\t\t\t\thtml.text(lastChild) === \"\"\n\t\t\t\t\t\t\t\t\t\t&& lastChild.nodeName.toLowerCase() === settings.tags.paragraph;\n\n\t\t\t\t\t\t\t\t\tif (makeHR && children.length >= 2) {\n\t\t\t\t\t\t\t\t\t\tsecondToLast = children[children.length - 2];\n\n\t\t\t\t\t\t\t\t\t\tif (secondToLast.nodeName.toLowerCase() === settings.tags.horizontalRule) {\n\t\t\t\t\t\t\t\t\t\t\tmakeHR = false;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (makeHR) {\n\t\t\t\t\t\t\t\t\t\thtml.addTag(settings.tags.horizontalRule, false, true, focusedElement);\n\t\t\t\t\t\t\t\t\t\tfocusedElement = focusedElement.nextSibling;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ((paragraph = html.addTag(settings.tags.paragraph, true, null, focusedElement)) !== null) {\n\t\t\t\t\t\t\t\t\t\tparagraph.innerHTML = '';\n\t\t\t\t\t\t\t\t\t\tcursor.set(0, paragraph);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbackspaceOrDeleteKey: function (e) {\n\t\t\t\t\t\t\tif (el.lastChild === null) return;\n\n\t\t\t\t\t\t\tvar lastChild = el.lastChild,\n\t\t\t\t\t\t\t\tbeforeLastChild = lastChild.previousSibling;\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tlastChild\n\t\t\t\t\t\t\t\t&& settings.tags.horizontalRule\n\t\t\t\t\t\t\t\t&& lastChild.nodeName.toLocaleLowerCase() === settings.tags.horizontalRule\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tel.removeChild(lastChild);\n\t\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\t\tlastChild\n\t\t\t\t\t\t\t\t&& beforeLastChild\n\t\t\t\t\t\t\t\t&& utils.html.text(lastChild).length < 1\n\n\t\t\t\t\t\t\t\t&& beforeLastChild.nodeName.toLowerCase() === settings.tags.horizontalRule\n\t\t\t\t\t\t\t\t&& lastChild.nodeName.toLowerCase() === settings.tags.paragraph\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tel.removeChild(lastChild);\n\t\t\t\t\t\t\t\tel.removeChild(beforeLastChild);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tdefaultSettings = {\n\t\t\t\t\t\telement: null,\n\t\t\t\t\t\tmodifier: 'auto',\n\t\t\t\t\t\tplaceholder: \"\",\n\t\t\t\t\t\tautofocus: false,\n\t\t\t\t\t\tautoHR: true,\n\t\t\t\t\t\tmode: Medium.richMode,\n\t\t\t\t\t\tmaxLength: -1,\n\t\t\t\t\t\tmodifiers: {\n\t\t\t\t\t\t\t'b': 'bold',\n\t\t\t\t\t\t\t'i': 'italicize',\n\t\t\t\t\t\t\t'u': 'underline',\n\t\t\t\t\t\t\t'v': 'paste'\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttags: {\n\t\t\t\t\t\t\t'break': 'br',\n\t\t\t\t\t\t\t'horizontalRule': 'hr',\n\t\t\t\t\t\t\t'paragraph': 'p',\n\t\t\t\t\t\t\t'outerLevel': ['pre', 'blockquote', 'figure'],\n\t\t\t\t\t\t\t'innerLevel': ['a', 'b', 'u', 'i', 'img', 'strong']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcssClasses: {\n\t\t\t\t\t\t\teditor: 'Medium',\n\t\t\t\t\t\t\tpasteHook: 'Medium-paste-hook',\n\t\t\t\t\t\t\tplaceholder: 'Medium-placeholder',\n\t\t\t\t\t\t\tclear: 'Medium-clear'\n\t\t\t\t\t\t},\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\tremove: ['style', 'class']\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpasteAsText: true,\n\t\t\t\t\t\tbeforeInvokeElement: function () {\n\t\t\t\t\t\t\t//this = Medium.Element\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbeforeInsertHtml: function () {\n\t\t\t\t\t\t\t//this = Medium.Html\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbeforeAddTag: function (tag, shouldFocus, isEditable, afterElement) {\n\t\t\t\t\t\t},\n\t\t\t\t\t\tkeyContext: null,\n\t\t\t\t\t\tpasteEventHandler: function (e) {\n\t\t\t\t\t\t\te = e || w.event;\n\t\t\t\t\t\t\tmedium.makeUndoable();\n\t\t\t\t\t\t\tvar length = medium.value().length;\n\n\t\t\t\t\t\t\tif (settings.pasteAsText) {\n\t\t\t\t\t\t\t\tvar t = e.clipboardData.getData('text/html');\n\t\t\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\t\t\tif (t.length ==0 )\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tt = e.clipboardData.getData('text/plain');\n\t\t\t\t\t\t\t\t\tt = t.replace(/\\n/g, '<br>');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t\t\tsel = utils.selection.saveSelection(),\n\t\t\t\t\t\t\t\t\ttext = t;//prompt(Medium.Messages.pastHere) || '';\n\n\t\t\t\t\t\t\t\tel.focus();\n\t\t\t\t\t\t\t\tMedium.activeElement = el;\n\t\t\t\t\t\t\t\tutils.selection.restoreSelection(sel);\n\t\t\t\t\t\t\t\tif (text.match(/microsoft-com/)) {\n\t\t\t\t\t\t\t\t\t// if the source is ms word\n\t\t\t\t\t\t\t\t\ttext = e.clipboardData.getData('text/plain');\n\t\t\t\t\t\t\t\t\ttext = text.replace(/\\n/g, '<br>');\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t//limit its length\n\t\t\t\t\t\t\t\t\t//totalLength = text.length + length;\n\t\t\t\t\t\t\t\t\t//if (settings.maxLength > 0 && totalLength > settings.maxLength) {\n\t\t\t\t\t\t\t\t\t//\ttext = text.substring(0, settings.maxLength - length);\n\t\t\t\t\t\t\t\t\t//}\n\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\ttext = text.replace(/<\\/p>/g, '<br>');\n\t\t\t\t\t\t\t\t\tvar regex = /<(?=(?!\\/a))(?=(?!a ))(?=(?!br))([^>]+)>/ig;\n\t\t\t\t\t\t\t\t\ttext = text.replace(regex, \"\");\n\t\t\t\t\t\t\t\t\tregex = /style=\\\"[^\\\"]+\\\"/ig;\n\t\t\t\t\t\t\t\t\ttext = text.replace(regex, \"\");\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t} \n\t\t\t\t\t\t\t\t(new Medium.Html(medium, text))\n\t\t\t\t\t\t\t\t\t\t.setClean(false)\n\t\t\t\t\t\t\t\t\t\t.insert(settings.beforeInsertHtml, true);\n\n\t\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\t\thtml.placeholders();\n\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\t\t\thtml.clean();\n\t\t\t\t\t\t\t\t\thtml.placeholders();\n\t\t\t\t\t\t\t\t}, 20);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tsettings = utils.deepExtend(defaultSettings, userSettings),\n\t\t\t\t\tel,\n\t\t\t\t\tnewVal,\n\t\t\t\t\ti,\n\t\t\t\t\tbridge = {};\n\n\t\t\t\tfor (i in defaultSettings) {\n\t\t\t\t\t// Override defaults with data-attributes\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof defaultSettings[i] !== 'object'\n\t\t\t\t\t\t&& defaultSettings.hasOwnProperty(i)\n\t\t\t\t\t\t&& settings.element.getAttribute('data-medium-' + key)\n\t\t\t\t\t) {\n\t\t\t\t\t\tnewVal = settings.element.getAttribute('data-medium-' + key);\n\n\t\t\t\t\t\tif (newVal.toLowerCase() === \"false\" || newVal.toLowerCase() === \"true\") {\n\t\t\t\t\t\t\tnewVal = newVal.toLowerCase() === \"true\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsettings[i] = newVal;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (settings.modifiers) {\n\t\t\t\t\tfor (i in settings.modifiers) {\n\t\t\t\t\t\tif (typeof(key[i]) !== 'undefined') {\n\t\t\t\t\t\t\tsettings.modifiers[key[i]] = settings.modifiers[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (settings.keyContext) {\n\t\t\t\t\tfor (i in settings.keyContext) {\n\t\t\t\t\t\tif (typeof(key[i]) !== 'undefined') {\n\t\t\t\t\t\t\tsettings.keyContext[key[i]] = settings.keyContext[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Extend Settings\n\t\t\t\tel = settings.element;\n\n\t\t\t\t// Editable, \n\t\t\t\t//set all editable elements to explicitly editable\n\t\t\t\tvar y = el.children;\n\t\t\t\tvar i;\n\t\t\t\tfor (i = 0; i < y.length; i++) {\n\t\t\t\t\tif (y[i].contentEditable != false) {\n\t\t\t\t\t   y[i].contentEditable = true;\n\t\t\t\t\t} \n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tel.contentEditable = true;\n\t\t\t\tel.className\n\t\t\t\t\t+= (' ' + settings.cssClasses.editor)\n\t\t\t\t+ (' ' + settings.cssClasses.editor + '-' + settings.mode);\n\n\t\t\t\tsettings.tags = (settings.tags || {});\n\t\t\t\tif (settings.tags.outerLevel) {\n\t\t\t\t\tsettings.tags.outerLevel = settings.tags.outerLevel.concat([settings.tags.paragraph, settings.tags.horizontalRule]);\n\t\t\t\t}\n\n\t\t\t\tthis.settings = settings;\n\t\t\t\tthis.element = el;\n\t\t\t\tthis.intercept = intercept;\n\n\t\t\t\tthis.action = action;\n\t\t\t\tthis.cache = cache;\n\t\t\t\tthis.cursor = cursor;\n\t\t\t\tthis.html = html;\n\t\t\t\tthis.utils = utils;\n\t\t\t\tthis.selection = selection;\n\n\t\t\t\tbridge.element = el;\n\t\t\t\tbridge.medium = this;\n\t\t\t\tbridge.settings = settings;\n\n\t\t\t\tbridge.action = action;\n\t\t\t\tbridge.cache = cache;\n\t\t\t\tbridge.cursor = cursor;\n\t\t\t\tbridge.html = html;\n\t\t\t\tbridge.intercept = intercept;\n\t\t\t\tbridge.utils = utils;\n\t\t\t\tbridge.selection = selection;\n\n\t\t\t\taction.setBridge(bridge);\n\t\t\t\tcache.setBridge(bridge);\n\t\t\t\tcursor.setBridge(bridge);\n\t\t\t\thtml.setBridge(bridge);\n\t\t\t\tutils.setBridge(bridge);\n\t\t\t\tselection.setBridge(bridge);\n\n\t\t\t\t// Initialize editor\n\t\t\t\thtml.clean();\n\t\t\t\thtml.placeholders();\n\t\t\t\taction.preserveElementFocus();\n\n\t\t\t\t// Capture Events\n\t\t\t\taction.listen();\n\n\t\t\t\tif (wild) {\n\t\t\t\t\tthis.makeUndoable = function () {\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tthis.dirty = false;\n\t\t\t\t\tthis.undoable = new Medium.Undoable(this);\n\t\t\t\t\tthis.undo = this.undoable.undo;\n\t\t\t\t\tthis.redo = this.undoable.redo;\n\t\t\t\t\tthis.makeUndoable = this.undoable.makeUndoable;\n\t\t\t\t}\n\n\t\t\t\tel.medium = this;\n\n\t\t\t\t// Set as initialized\n\t\t\t\tcache.initialized = true;\n\t\t\t};\n\n\t\tMedium.prototype = {\n\t\t\t/**\n\t\t\t *\n\t\t\t * @param {String|Object} html\n\t\t\t * @param {Function} [callback]\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tinsertHtml: function (html, callback) {\n\t\t\t\tvar result = (new Medium.Html(this, html))\n\t\t\t\t\t.insert(this.settings.beforeInsertHtml);\n\n\t\t\t\tthis.utils.triggerEvent(this.element, \"change\");\n\n\t\t\t\tif (callback) {\n\t\t\t\t\tcallback.apply(result);\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t *\n\t\t\t * @param {String} tagName\n\t\t\t * @param {Object} [attributes]\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tinvokeElement: function (tagName, attributes) {\n\t\t\t\tvar settings = this.settings,\n\t\t\t\t\tattributes = attributes || {},\n\t\t\t\t\tremove = attributes.remove || [];\n\n\t\t\t\tswitch (settings.mode) {\n\t\t\t\t\tcase Medium.inlineMode:\n\t\t\t\t\tcase Medium.partialMode:\n\t\t\t\t\t\treturn this;\n\t\t\t\t\tdefault:\n\t\t\t\t}\n\n\t\t\t\t//invoke works off class, so if it isn't there, we just add it\n\t\t\t\tif (remove.length > 0) {\n\t\t\t\t\tif (!arrayContains(settings, 'class')) {\n\t\t\t\t\t\tremove.push('class');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t(new Medium.Element(this, tagName, attributes))\n\t\t\t\t\t.invoke(this.settings.beforeInvokeElement);\n\n\t\t\t\tthis.utils.triggerEvent(this.element, \"change\");\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\tbehavior: function () {\n\t\t\t\treturn (wild ? 'wild' : 'domesticated');\n\t\t\t},\n\n\t\t\t/**\n\t\t\t *\n\t\t\t * @param value\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tvalue: function (value) {\n\t\t\t\tif (typeof value !== 'undefined') {\n\t\t\t\t\tthis.element.innerHTML = value;\n\n\t\t\t\t\tthis.html.clean();\n\t\t\t\t\tthis.html.placeholders();\n\t\t\t\t} else {\n\t\t\t\t\treturn this.element.innerHTML;\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Focus on element\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tfocus: function () {\n\t\t\t\tvar el = this.element;\n\t\t\t\tel.focus();\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Select all text\n\t\t\t * @returns {Medium}\n\t\t\t */\n\t\t\tselect: function () {\n\t\t\t\tvar el = this.element,\n\t\t\t\t\trange,\n\t\t\t\t\tselection;\n\n\t\t\t\tel.focus();\n\n\t\t\t\tif (d.body.createTextRange) {\n\t\t\t\t\trange = d.body.createTextRange();\n\t\t\t\t\trange.moveToElementText(el);\n\t\t\t\t\trange.select();\n\t\t\t\t} else if (w.getSelection) {\n\t\t\t\t\tselection = w.getSelection();\n\t\t\t\t\trange = d.createRange();\n\t\t\t\t\trange.selectNodeContents(el);\n\t\t\t\t\tselection.removeAllRanges();\n\t\t\t\t\tselection.addRange(range);\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\tisActive: function () {\n\t\t\t\treturn (Medium.activeElement === this.element);\n\t\t\t},\n\n\t\t\tdestroy: function () {\n\t\t\t\tvar el = this.element,\n\t\t\t\t\tintercept = this.intercept,\n\t\t\t\t\tsettings = this.settings,\n\t\t\t\t\tplaceholder = this.placeholder || null;\n\n\t\t\t\tif (placeholder !== null && placeholder.setup) {\n\t\t\t\t\t//remove placeholder\n\t\t\t\t\tplaceholder.parentNode.removeChild(placeholder);\n\t\t\t\t\tdelete el.placeHolderActive;\n\t\t\t\t}\n\n\t\t\t\t//remove contenteditable\n\t\t\t\tel.removeAttribute('contenteditable');\n\n\t\t\t\t//remove classes\n\t\t\t\tel.className = trim(el.className\n\t\t\t\t\t.replace(settings.cssClasses.editor, '')\n\t\t\t\t\t.replace(settings.cssClasses.clear, '')\n\t\t\t\t\t.replace(settings.cssClasses.editor + '-' + settings.mode, ''));\n\n\t\t\t\t//remove events\n\t\t\t\tthis.utils\n\t\t\t\t\t.removeEvent(el, 'keyup', intercept.up)\n\t\t\t\t\t.removeEvent(el, 'keydown', intercept.down)\n\t\t\t\t\t.removeEvent(el, 'focus', intercept.focus)\n\t\t\t\t\t.removeEvent(el, 'blur', intercept.focus)\n\t\t\t\t\t.removeEvent(el, 'paste', settings.pasteEventHandler);\n\t\t\t},\n\n\t\t\t// Clears the element and restores the placeholder\n\t\t\tclear: function () {\n\t\t\t\tthis.element.innerHTML = '';\n\t\t\t\tthis.html.placeholders();\n\t\t\t}\n\t\t};\n\n\t\t/**\n\t\t * @param {Medium} medium\n\t\t * @param {String} tagName\n\t\t * @param {Object} [attributes]\n\t\t * @constructor\n\t\t */\n\t\tMedium.Element = function (medium, tagName, attributes) {\n\t\t\tthis.medium = medium;\n\t\t\tthis.element = medium.settings.element;\n\t\t\tif (wild) {\n\t\t\t\tthis.tagName = tagName;\n\t\t\t} else {\n\t\t\t\tswitch (tagName.toLowerCase()) {\n\t\t\t\t\tcase 'bold':\n\t\t\t\t\t\tthis.tagName = 'b';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'italic':\n\t\t\t\t\t\tthis.tagName = 'i';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'underline':\n\t\t\t\t\t\tthis.tagName = 'u';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.tagName = tagName;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.attributes = attributes || {};\n\t\t\tthis.clean = true;\n\t\t};\n\n\n\t\t/**\n\t\t * @constructor\n\t\t * @param {Medium} medium\n\t\t * @param {String|HtmlElement} html\n\t\t */\n\t\tMedium.Html = function (medium, html) {\n\t\t\tthis.medium = medium;\n\t\t\tthis.element = medium.settings.element;\n\t\t\tthis.html = html;\n\t\t\tthis.clean = true;\n\t\t};\n\n\t\t/**\n\t\t *\n\t\t * @constructor\n\t\t */\n\t\tMedium.Injector = function () {\n\t\t};\n\n\t\tif (wild) {\n\t\t\tMedium.Element.prototype = {\n\t\t\t\t/**\n\t\t\t\t * @methodOf Medium.Element\n\t\t\t\t * @param {Function} [fn]\n\t\t\t\t */\n\t\t\t\tinvoke: function (fn) {\n\t\t\t\t\tif (Medium.activeElement === this.element) {\n\t\t\t\t\t\tif (fn) {\n\t\t\t\t\t\t\tfn.apply(this);\n\t\t\t\t\t\t}\n\t\t\t\t\t\td.execCommand(this.tagName, false);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tsetClean: function () {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tMedium.Injector.prototype = {\n\t\t\t\t/**\n\t\t\t\t * @methodOf Medium.Injector\n\t\t\t\t * @param {String|HtmlElement} htmlRaw\n\t\t\t\t * @param {Boolean} [selectInserted]\n\t\t\t\t * @returns {null}\n\t\t\t\t */\n\t\t\t\tinject: function (htmlRaw, selectInserted) {\n\t\t\t\t\tthis.insertHTML(htmlRaw, selectInserted);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t/**\n\t\t\t *\n\t\t\t * @constructor\n\t\t\t */\n\t\t\tMedium.Undoable = function () {\n\t\t\t};\n\t\t}\n\n\t\t//if medium is domesticated (ie, not wild)\n\t\telse {\n\t\t\trangy.rangePrototype.insertNodeAtEnd = function (node) {\n\t\t\t\tvar range = this.cloneRange();\n\t\t\t\trange.collapse(false);\n\t\t\t\trange.insertNode(node);\n\t\t\t\trange.detach();\n\t\t\t\tthis.setEndAfter(node);\n\t\t\t};\n\n\t\t\tMedium.Element.prototype = {\n\t\t\t\t/**\n\t\t\t\t * @methodOf Medium.Element\n\t\t\t\t * @param {Function} [fn]\n\t\t\t\t */\n\t\t\t\tinvoke: function (fn) {\n\t\t\t\t\tif (Medium.activeElement === this.element) {\n\t\t\t\t\t\tif (fn) {\n\t\t\t\t\t\t\tfn.apply(this);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\tattr = this.attributes,\n\t\t\t\t\t\t\ttagName = this.tagName.toLowerCase(),\n\t\t\t\t\t\t\tapplier,\n\t\t\t\t\t\t\tcl;\n\n\t\t\t\t\t\tif (attr.className !== undefined) {\n\t\t\t\t\t\t\tcl = (attr.className.split[' '] || [attr.className]).shift();\n\t\t\t\t\t\t\tdelete attr.className;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcl = 'lasso-noclass';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tapplier = rangy.createClassApplier(cl, {\n\t\t\t\t\t\t\telementTagName: tagName,\n\t\t\t\t\t\t\telementAttributes: this.attributes\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t//this.medium.makeUndoable();\n\n\t\t\t\t\t\tapplier.toggleSelection(w);\n\n\t\t\t\t\t\tif (this.clean) {\n\t\t\t\t\t\t\t//cleanup\n\t\t\t\t\t\t\tthis.medium.html.clean();\n\t\t\t\t\t\t\tthis.medium.html.placeholders();\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t *\n\t\t\t\t * @param {Boolean} clean\n\t\t\t\t * @returns {Medium.Element}\n\t\t\t\t */\n\t\t\t\tsetClean: function (clean) {\n\t\t\t\t\tthis.clean = clean;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tMedium.Injector.prototype = {\n\t\t\t\t/**\n\t\t\t\t * @methodOf Medium.Injector\n\t\t\t\t * @param {String|HtmlElement} htmlRaw\n\t\t\t\t * @returns {HtmlElement}\n\t\t\t\t */\n\t\t\t\tinject: function (htmlRaw) {\n\t\t\t\t\tvar html, isConverted = false;\n\t\t\t\t\tif (typeof htmlRaw === 'string') {\n\t\t\t\t\t\tvar htmlConverter = d.createElement('div');\n\t\t\t\t\t\thtmlConverter.innerHTML = htmlRaw;\n\t\t\t\t\t\thtml = htmlConverter.childNodes;\n\t\t\t\t\t\tisConverted = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thtml = htmlRaw;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.insertHTML('<span id=\"wedge\"></span>');\n\n\t\t\t\t\tvar wedge = d.getElementById('wedge'),\n\t\t\t\t\t\tparent = wedge.parentNode,\n\t\t\t\t\t\ti = 0;\n\t\t\t\t\twedge.removeAttribute('id');\n\n\t\t\t\t\tif (isConverted) {\n\t\t\t\t\t\twhile (i < html.length) {\n\t\t\t\t\t\t\tparent.insertBefore(html[i], wedge);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparent.insertBefore(html, wedge);\n\t\t\t\t\t}\n\t\t\t\t\tparent.removeChild(wedge);\n\t\t\t\t\twedge = null;\n\n\t\t\t\t\treturn html;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * @param {Medium} medium\n\t\t\t * @constructor\n\t\t\t */\n\t\t\tMedium.Undoable = function (medium) {\n\t\t\t\tvar me = this,\n\t\t\t\t\telement = medium.settings.element,\n\t\t\t\t\tutils = medium.utils,\n\t\t\t\t\taddEvent = utils.addEvent,\n\t\t\t\t\tstartValue = element.innerHTML,\n\t\t\t\t\ttimer,\n\t\t\t\t\tstack = new Undo.Stack(),\n\t\t\t\t\tEditCommand = Undo.Command.extend({\n\t\t\t\t\t\tconstructor: function (oldValue, newValue) {\n\t\t\t\t\t\t\tthis.oldValue = oldValue;\n\t\t\t\t\t\t\tthis.newValue = newValue;\n\t\t\t\t\t\t},\n\t\t\t\t\t\texecute: function () {\n\t\t\t\t\t\t},\n\t\t\t\t\t\tundo: function () {\n\t\t\t\t\t\t\telement.innerHTML = this.oldValue;\n\t\t\t\t\t\t\tstartValue = this.oldValue;\n\t\t\t\t\t\t\tmedium.canUndo = stack.canUndo();\n\t\t\t\t\t\t\tmedium.canRedo = stack.canRedo();\n\t\t\t\t\t\t\tmedium.dirty = stack.dirty();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tredo: function () {\n\t\t\t\t\t\t\telement.innerHTML = this.newValue;\n\t\t\t\t\t\t\tmedium.canUndo = stack.canUndo();\n\t\t\t\t\t\t\tmedium.canRedo = stack.canRedo();\n\t\t\t\t\t\t\tmedium.dirty = stack.dirty();\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tmakeUndoable = function () {\n\t\t\t\t\t\tvar newValue = element.innerHTML;\n\t\t\t\t\t\t// ignore meta key presses\n\t\t\t\t\t\tif (newValue != startValue) {\n\n\t\t\t\t\t\t\tif (!me.movingThroughStack) {\n\t\t\t\t\t\t\t\t// this could try and make a diff instead of storing snapshots\n\t\t\t\t\t\t\t\tstack.execute(new EditCommand(startValue, newValue));\n\t\t\t\t\t\t\t\tstartValue = newValue;\n\t\t\t\t\t\t\t\tmedium.dirty = stack.dirty();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tutils.triggerEvent(medium.settings.element, \"change\");\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\tthis.medium = medium;\n\t\t\t\tthis.timer = timer;\n\t\t\t\tthis.stack = stack;\n\t\t\t\tthis.makeUndoable = makeUndoable;\n\t\t\t\tthis.EditCommand = EditCommand;\n\t\t\t\tthis.movingThroughStack = false;\n\n\t\t\t\taddEvent(element, 'keyup', function (e) {\n\t\t\t\t\tif (e.ctrlKey || e.keyCode === key.z) {\n\t\t\t\t\t\tutils.preventDefaultEvent(e);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// a way too simple algorithm in place of single-character undo\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\ttimer = setTimeout(function () {\n\t\t\t\t\t\tmakeUndoable();\n\t\t\t\t\t\t// check if we need to add the component button\n\t\t\t\t\t\tlasso_editor.addComponentButton();\n\t\t\t\t\t}, 250);\n\t\t\t\t});\n\n\t\t\t\taddEvent(element, 'keydown', function (e) {\n\t\t\t\t\tif (!e.ctrlKey || e.keyCode !== key.z) {\n\t\t\t\t\t\tme.movingThroughStack = false;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tutils.preventDefaultEvent(e);\n\n\t\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\t\tme.movingThroughStack = true;\n\t\t\t\t\t\tstack.canRedo() && stack.redo()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tme.movingThroughStack = true;\n\t\t\t\t\t\tstack.canUndo() && stack.undo();\n\t\t\t\t\t}\n\t\t\t\t\tme.movingThroughStack = false;\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\t//Thank you Tim Down (super uber genius): http://stackoverflow.com/questions/6690752/insert-html-at-caret-in-a-contenteditable-div/6691294#6691294\n\t\tMedium.Injector.prototype.insertHTML = function (html, selectPastedContent) {\n\t\t\tvar sel, range;\n\t\t\tif (window.getSelection) {\n\t\t\t\t// IE9 and non-IE\n\t\t\t\tsel = window.getSelection();\n\t\t\t\tif (sel.getRangeAt && sel.rangeCount) {\n\t\t\t\t\trange = sel.getRangeAt(0);\n\t\t\t\t\trange.deleteContents();\n\n\t\t\t\t\t// Range.createContextualFragment() would be useful here but is\n\t\t\t\t\t// only relatively recently standardized and is not supported in\n\t\t\t\t\t// some browsers (IE9, for one)\n\t\t\t\t\tvar el = d.createElement(\"div\");\n\t\t\t\t\tel.innerHTML = html;\n\t\t\t\t\tvar frag = d.createDocumentFragment(), node, lastNode;\n\t\t\t\t\twhile ((node = el.firstChild)) {\n\t\t\t\t\t\tlastNode = frag.appendChild(node);\n\t\t\t\t\t}\n\t\t\t\t\tvar firstNode = frag.firstChild;\n\t\t\t\t\trange.insertNode(frag);\n\n\t\t\t\t\t// Preserve the selection\n\t\t\t\t\tif (lastNode) {\n\t\t\t\t\t\trange = range.cloneRange();\n\t\t\t\t\t\trange.setStartAfter(lastNode);\n\t\t\t\t\t\tif (selectPastedContent) {\n\t\t\t\t\t\t\trange.setStartBefore(firstNode);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\trange.collapse(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsel.removeAllRanges();\n\t\t\t\t\t\tsel.addRange(range);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ((sel = d.selection) && sel.type != \"Control\") {\n\t\t\t\t// IE < 9\n\t\t\t\tvar originalRange = sel.createRange();\n\t\t\t\toriginalRange.collapse(true);\n\t\t\t\tsel.createRange().pasteHTML(html);\n\t\t\t\tif (selectPastedContent) {\n\t\t\t\t\trange = sel.createRange();\n\t\t\t\t\trange.setEndPoint(\"StartToStart\", originalRange);\n\t\t\t\t\trange.select();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tMedium.Html.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\t/**\n\t\t\t * @methodOf Medium.Html\n\t\t\t * @param {Function} [fn]\n\t\t\t * @param {Boolean} [selectInserted]\n\t\t\t * @returns {HtmlElement}\n\t\t\t */\n\t\t\tinsert: function (fn, selectInserted) {\n\t\t\t\tif (Medium.activeElement === this.element) {\n\t\t\t\t\tif (fn) {\n\t\t\t\t\t\tfn.apply(this);\n\t\t\t\t\t}\n\n\t\t\t\t\tvar inserted = this.injector.inject(this.html, selectInserted);\n\n\t\t\t\t\tif (this.clean) {\n\t\t\t\t\t\t//cleanup\n\t\t\t\t\t\tthis.medium.html.clean();\n\t\t\t\t\t\tthis.medium.html.placeholders();\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.medium.makeUndoable();\n\n\t\t\t\t\treturn inserted;\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @attributeOf {Medium.Injector} Medium.Html\n\t\t\t */\n\t\t\tinjector: new Medium.Injector(),\n\n\t\t\t/**\n\t\t\t * @methodOf Medium.Html\n\t\t\t * @param clean\n\t\t\t * @returns {Medium.Html}\n\t\t\t */\n\t\t\tsetClean: function (clean) {\n\t\t\t\tthis.clean = clean;\n\t\t\t\treturn this;\n\t\t\t}\n\t\t};\n\n\t\tMedium.Utilities = function () {\n\t\t};\n\t\tMedium.Utilities.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\t/*\n\t\t\t * Keyboard Interface events\n\t\t\t */\n\t\t\tisCommand: function (e, fnTrue, fnFalse) {\n\t\t\t\tvar s = this.settings;\n\t\t\t\tif ((s.modifier === 'ctrl' && e.ctrlKey ) ||\n\t\t\t\t\t(s.modifier === 'cmd' && e.metaKey ) ||\n\t\t\t\t\t(s.modifier === 'auto' && (e.ctrlKey || e.metaKey) )\n\t\t\t\t) {\n\t\t\t\t\treturn fnTrue.call();\n\t\t\t\t} else {\n\t\t\t\t\treturn fnFalse.call();\n\t\t\t\t}\n\t\t\t},\n\t\t\tisShift: function (e, fnTrue, fnFalse) {\n\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\treturn fnTrue.call();\n\t\t\t\t} else {\n\t\t\t\t\treturn fnFalse.call();\n\t\t\t\t}\n\t\t\t},\n\t\t\tisModifier: function (e, fn) {\n\t\t\t\tvar cmd = this.settings.modifiers[e.keyCode];\n\t\t\t\tif (cmd) {\n\t\t\t\t\treturn fn.call(null, cmd);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tspecial: (function () {\n\t\t\t\tvar special = {};\n\n\t\t\t\tspecial[key['backspace']] = true;\n\t\t\t\tspecial[key['shift']] = true;\n\t\t\t\tspecial[key['ctrl']] = true;\n\t\t\t\tspecial[key['alt']] = true;\n\t\t\t\tspecial[key['delete']] = true;\n\t\t\t\tspecial[key['cmd']] = true;\n\n\t\t\t\treturn special;\n\t\t\t})(),\n\t\t\tisSpecial: function (e) {\n\n\t\t\t\tif (this.cache.cmd) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn typeof this.special[e.keyCode] !== 'undefined';\n\t\t\t},\n\t\t\tnavigational: (function () {\n\t\t\t\tvar navigational = {};\n\n\t\t\t\tnavigational[key['upArrow']] = true;\n\t\t\t\tnavigational[key['downArrow']] = true;\n\t\t\t\tnavigational[key['leftArrow']] = true;\n\t\t\t\tnavigational[key['rightArrow']] = true;\n\n\t\t\t\treturn navigational;\n\t\t\t})(),\n\t\t\tisNavigational: function (e) {\n\t\t\t\treturn typeof this.navigational[e.keyCode] !== 'undefined';\n\t\t\t},\n\n\t\t\t/*\n\t\t\t * Handle Events\n\t\t\t */\n\t\t\taddEvent: function addEvent(element, eventName, func) {\n\t\t\t\tif (element.addEventListener) {\n\t\t\t\t\telement.addEventListener(eventName, func, false);\n\t\t\t\t} else if (element.attachEvent) {\n\t\t\t\t\telement.attachEvent(\"on\" + eventName, func);\n\t\t\t\t} else {\n\t\t\t\t\telement['on' + eventName] = func;\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tremoveEvent: function removeEvent(element, eventName, func) {\n\t\t\t\tif (element.removeEventListener) {\n\t\t\t\t\telement.removeEventListener(eventName, func, false);\n\t\t\t\t} else if (element.detachEvent) {\n\t\t\t\t\telement.detachEvent(\"on\" + eventName, func);\n\t\t\t\t} else {\n\t\t\t\t\telement['on' + eventName] = null;\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tpreventDefaultEvent: function (e) {\n\t\t\t\tif (e.preventDefault) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t} else {\n\t\t\t\t\te.returnValue = false;\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tstopPropagation: function (e) {\n\t\t\t\te = e || window.event;\n\t\t\t\te.cancelBubble = true;\n\n\t\t\t\tif (e.stopPropagation !== undefined) {\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t}\n\t\t\t},\n\t\t\ttriggerEvent: function (element, eventName) {\n\t\t\t\tvar e;\n\t\t\t\tif (d.createEvent) {\n\t\t\t\t\te = d.createEvent(\"HTMLEvents\");\n\t\t\t\t\te.initEvent(eventName, true, true);\n\t\t\t\t\te.eventName = eventName;\n\t\t\t\t\telement.dispatchEvent(e);\n\t\t\t\t} else {\n\t\t\t\t\te = d.createEventObject();\n\t\t\t\t\telement.fireEvent(\"on\" + eventName, e);\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\tdeepExtend: function (destination, source) {\n\t\t\t\tfor (var property in source) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tsource[property]\n\t\t\t\t\t\t&& source[property].constructor\n\t\t\t\t\t\t&& source[property].constructor === Object\n\t\t\t\t\t) {\n\t\t\t\t\t\tdestination[property] = destination[property] || {};\n\t\t\t\t\t\tthis.deepExtend(destination[property], source[property]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdestination[property] = source[property];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn destination;\n\t\t\t},\n\t\t\t/*\n\t\t\t * This is a Paste Hook. When the user pastes\n\t\t\t * content, this ultimately converts it into\n\t\t\t * plain text before inserting the data.\n\t\t\t */\n\t\t\tpasteHook: function (fn) {\n\t\t\t\t/*var textarea = d.createElement('textarea'),\n\t\t\t\t\tel = this.element,\n\t\t\t\t\texistingValue,\n\t\t\t\t\texistingLength,\n\t\t\t\t\toverallLength,\n\t\t\t\t\ts = this.settings,\n\t\t\t\t\tmedium = this.medium,\n\t\t\t\t\thtml = this.html;\n\n\t\t\t\ttextarea.className = s.cssClasses.pasteHook;\n\n\t\t\t\tel.parentNode.appendChild(textarea);\n\n\t\t\t\t//textarea.focus();\n\n\t\t\t\tif (!wild) {\n\t\t\t\t\tmedium.makeUndoable();\n\t\t\t\t}\n\t\t\t\tsetTimeout(function () {\n\t\t\t\t\tel.focus();\n\t\t\t\t\tif (s.maxLength > 0) {\n\t\t\t\t\t\texistingValue = html.text(el);\n\t\t\t\t\t\texistingLength = existingValue.length;\n\t\t\t\t\t\toverallLength = existingLength + textarea.value.length;\n\t\t\t\t\t\tif (overallLength > existingLength) {\n\t\t\t\t\t\t\ttextarea.value = textarea.value.substring(0, s.maxLength - existingLength);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfn(textarea.value);\n\t\t\t\t\thtml.deleteNode(textarea);\n\t\t\t\t}, 2);*/\n\t\t\t},\n\t\t\tsetupContents: function () {\n\t\t\t\tvar el = this.element,\n\t\t\t\t\tchildren = el.children,\n\t\t\t\t\tchildNodes = el.childNodes,\n\t\t\t\t\tinitialParagraph;\n\n\t\t\t\tif (\n\t\t\t\t\t!this.settings.tags.paragraph\n\t\t\t\t\t|| children.length > 0\n\t\t\t\t\t|| this.settings.mode === Medium.inlineMode\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t//has content, but no children\n\t\t\t\tif (childNodes.length > 0) {\n\t\t\t\t\tinitialParagraph = d.createElement(this.settings.tags.paragraph);\n\t\t\t\t\tif (el.innerHTML.match('^[&]nbsp[;]')) {\n\t\t\t\t\t\tel.innerHTML = el.innerHTML.substring(6, el.innerHTML.length - 1);\n\t\t\t\t\t}\n\t\t\t\t\tinitialParagraph.innerHTML = el.innerHTML;\n\t\t\t\t\tel.innerHTML = '';\n\t\t\t\t\tel.appendChild(initialParagraph);\n\t\t\t\t\tthis.cursor.set(initialParagraph.innerHTML.length, initialParagraph);\n\t\t\t\t} else {\n\t\t\t\t\tinitialParagraph = d.createElement(this.settings.tags.paragraph);\n\t\t\t\t\tinitialParagraph.innerHTML = '&nbsp;';\n\t\t\t\t\tel.appendChild(initialParagraph);\n\t\t\t\t}\n\t\t\t},\n\t\t\ttraverseAll: function (element, options, depth) {\n\t\t\t\tvar children = element.childNodes,\n\t\t\t\t\tlength = children.length,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tnode,\n\t\t\t\t\tdepth = depth || 1;\n\n\t\t\t\toptions = options || {};\n\n\t\t\t\tif (length > 0) {\n\t\t\t\t\tfor (; i < length; i++) {\n\t\t\t\t\t\tnode = children[i];\n\t\t\t\t\t\tswitch (node.nodeType) {\n\t\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\t\tthis.traverseAll(node, options, depth + 1);\n\t\t\t\t\t\t\t\tif (options.element !== undefined) options.element(node, i, depth, element);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\tif (options.fragment !== undefined) options.fragment(node, i, depth, element);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//length may change\n\t\t\t\t\t\tlength = children.length;\n\t\t\t\t\t\t//if length did change, and we are at the last item, this causes infinite recursion, so if we are at the last item, then stop to prevent this\n\t\t\t\t\t\tif (node === element.lastChild) {\n\t\t\t\t\t\t\ti = length;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t};\n\n\t\t/*\n\t\t * Handle Selection Logic\n\t\t */\n\t\tMedium.Selection = function () {\n\t\t};\n\t\tMedium.Selection.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\tsaveSelection: function () {\n\t\t\t\tif (w.getSelection) {\n\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\tif (sel.rangeCount > 0) {\n\t\t\t\t\t\treturn sel.getRangeAt(0);\n\t\t\t\t\t}\n\t\t\t\t} else if (d.selection && d.selection.createRange) { // IE\n\t\t\t\t\treturn d.selection.createRange();\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\n\t\t\trestoreSelection: function (range) {\n\t\t\t\tif (range) {\n\t\t\t\t\tif (w.getSelection) {\n\t\t\t\t\t\tvar sel = w.getSelection();\n\t\t\t\t\t\tsel.removeAllRanges();\n\t\t\t\t\t\tsel.addRange(range);\n\t\t\t\t\t} else if (d.selection && range.select) { // IE\n\t\t\t\t\t\trange.select();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t/*\n\t\t * Handle Cursor Logic\n\t\t */\n\t\tMedium.Cursor = function () {\n\t\t};\n\t\tMedium.Cursor.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\tset: function (pos, el) {\n\t\t\t\tvar range,\n\t\t\t\t\thtml = this.html;\n\n\t\t\t\tif (d.createRange) {\n\t\t\t\t\tvar selection = w.getSelection(),\n\t\t\t\t\t\tlastChild = html.lastChild(),\n\t\t\t\t\t\tlength = html.text(lastChild).length - 1,\n\t\t\t\t\t\ttoModify = el ? el : lastChild,\n\t\t\t\t\t\ttheLength = ((typeof pos !== 'undefined') && (pos !== null) ? pos : length);\n\n\t\t\t\t\trange = d.createRange();\n\t\t\t\t\trange.setStart(toModify, theLength);\n\t\t\t\t\trange.collapse(true);\n\t\t\t\t\tselection.removeAllRanges();\n\t\t\t\t\tselection.addRange(range);\n\t\t\t\t} else {\n\t\t\t\t\trange = d.body.createTextRange();\n\t\t\t\t\trange.moveToElementText(el);\n\t\t\t\t\trange.collapse(false);\n\t\t\t\t\trange.select();\n\t\t\t\t}\n\t\t\t},\n\t\t\tparent: function () {\n\t\t\t\tvar target = null, range;\n\n\t\t\t\tif (w.getSelection) {\n\t\t\t\t\trange = w.getSelection().getRangeAt(0);\n\t\t\t\t\ttarget = range.commonAncestorContainer;\n\n\t\t\t\t\ttarget = (target.nodeType === 1\n\t\t\t\t\t\t? target\n\t\t\t\t\t\t: target.parentNode\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\telse if (d.selection) {\n\t\t\t\t\ttarget = d.selection.createRange().parentElement();\n\t\t\t\t}\n\n\t\t\t\tif (target.tagName == 'SPAN') {\n\t\t\t\t\ttarget = target.parentNode;\n\t\t\t\t}\n\n\t\t\t\treturn target;\n\t\t\t},\n\t\t\tcaretToBeginning: function (el) {\n\t\t\t\tthis.set(0, el);\n\t\t\t},\n\t\t\tcaretToEnd: function (el) {\n\t\t\t\tthis.set(this.html.text(el).length, el);\n\t\t\t}\n\t\t};\n\n\t\t/*\n\t\t * HTML Abstractions\n\t\t */\n\t\tMedium.HtmlAssistant = function () {\n\t\t};\n\t\tMedium.HtmlAssistant.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\tencodeHtml: function (html) {\n\t\t\t\treturn d.createElement('a').appendChild(\n\t\t\t\t\td.createTextNode(html)).parentNode.innerHTML;\n\t\t\t},\n\t\t\ttext: function (node, val) {\n\t\t\t\tnode = node || this.settings.element;\n\t\t\t\tif (val) {\n\t\t\t\t\tif ((node.textContent) && (typeof (node.textContent) != \"undefined\")) {\n\t\t\t\t\t\tnode.textContent = val;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.innerText = val;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telse if (node.innerText) {\n\t\t\t\t\treturn trim(node.innerText);\n\t\t\t\t}\n\n\t\t\t\telse if (node.textContent) {\n\t\t\t\t\treturn trim(node.textContent);\n\t\t\t\t}\n\t\t\t\t//document fragment\n\t\t\t\telse if (node.data) {\n\t\t\t\t\treturn trim(node.data);\n\t\t\t\t}\n\n\t\t\t\t//for good measure\n\t\t\t\treturn '';\n\t\t\t},\n\t\t\tchangeTag: function (oldNode, newTag) {\n\t\t\t\tvar newNode = d.createElement(newTag),\n\t\t\t\t\tnode,\n\t\t\t\t\tnextNode;\n\n\t\t\t\tnode = oldNode.firstChild;\n\t\t\t\twhile (node) {\n\t\t\t\t\tnextNode = node.nextSibling;\n\t\t\t\t\tnewNode.appendChild(node);\n\t\t\t\t\tnode = nextNode;\n\t\t\t\t}\n\n\t\t\t\toldNode.parentNode.insertBefore(newNode, oldNode);\n\t\t\t\toldNode.parentNode.removeChild(oldNode);\n\n\t\t\t\treturn newNode;\n\t\t\t},\n\t\t\tdeleteNode: function (el) {\n\t\t\t\tel.parentNode.removeChild(el);\n\t\t\t},\n\t\t\tplaceholders: function () {\n\t\t\t\t//in IE8, just gracefully degrade to no placeholders\n\t\t\t\tif (!w.getComputedStyle) return;\n\n\t\t\t\tvar that = this,\n\t\t\t\t\ts = this.settings,\n\t\t\t\t\tplaceholder = this.medium.placeholder || (this.medium.placeholder = d.createElement('div')),\n\t\t\t\t\tel = s.element,\n\t\t\t\t\tstyle = placeholder.style,\n\t\t\t\t\telStyle = w.getComputedStyle(el, null),\n\t\t\t\t\tqStyle = function (prop) {\n\t\t\t\t\t\treturn elStyle.getPropertyValue(prop)\n\t\t\t\t\t},\n\t\t\t\t\tutils = this.utils,\n\t\t\t\t\ttext = utils.html.text(el),\n\t\t\t\t\tcursor = this.cursor,\n\t\t\t\t\tchildCount = el.children.length;\n\n\t\t\t\tel.placeholder = placeholder;\n\n\t\t\t\t// Empty Editor\n\t\t\t\tif (text.length < 1 && childCount < 2) {\n                    //the behavior when the editable content becomes empty.\n                    //simplified from the previous version\n\t\t\t\t\tel.innerHTML = '<p><br></p>';\n                 \n\t\t\t\t\t/*if (el.placeHolderActive) return;\n\n\t\t\t\t\tif (!el.innerHTML.match('<' + s.tags.paragraph)) {\n\t\t\t\t\t\tel.innerHTML = '';\n\t\t\t\t\t}\n\n\t\t\t\t\t// We need to add placeholders\n\t\t\t\t\tif (s.placeholder.length > 0) {\n\t\t\t\t\t\tif (!placeholder.setup) {\n\t\t\t\t\t\t\tplaceholder.setup = true;\n\n\t\t\t\t\t\t\t//background & background color\n\t\t\t\t\t\t\tstyle.background = qStyle('background');\n\t\t\t\t\t\t\tstyle.backgroundColor = qStyle('background-color');\n\n\t\t\t\t\t\t\t//text size & text color\n\t\t\t\t\t\t\tstyle.fontSize = qStyle('font-size');\n\t\t\t\t\t\t\tstyle.color = elStyle.color;\n\n\t\t\t\t\t\t\t//begin box-model\n\t\t\t\t\t\t\t//margin\n\t\t\t\t\t\t\tstyle.marginTop = qStyle('margin-top');\n\t\t\t\t\t\t\tstyle.marginBottom = qStyle('margin-bottom');\n\t\t\t\t\t\t\tstyle.marginLeft = qStyle('margin-left');\n\t\t\t\t\t\t\tstyle.marginRight = qStyle('margin-right');\n\n\t\t\t\t\t\t\t//padding\n\t\t\t\t\t\t\tstyle.paddingTop = qStyle('padding-top');\n\t\t\t\t\t\t\tstyle.paddingBottom = qStyle('padding-bottom');\n\t\t\t\t\t\t\tstyle.paddingLeft = qStyle('padding-left');\n\t\t\t\t\t\t\tstyle.paddingRight = qStyle('padding-right');\n\n\t\t\t\t\t\t\t//border\n\t\t\t\t\t\t\tstyle.borderTopWidth = qStyle('border-top-width');\n\t\t\t\t\t\t\tstyle.borderTopColor = qStyle('border-top-color');\n\t\t\t\t\t\t\tstyle.borderTopStyle = qStyle('border-top-style');\n\t\t\t\t\t\t\tstyle.borderBottomWidth = qStyle('border-bottom-width');\n\t\t\t\t\t\t\tstyle.borderBottomColor = qStyle('border-bottom-color');\n\t\t\t\t\t\t\tstyle.borderBottomStyle = qStyle('border-bottom-style');\n\t\t\t\t\t\t\tstyle.borderLeftWidth = qStyle('border-left-width');\n\t\t\t\t\t\t\tstyle.borderLeftColor = qStyle('border-left-color');\n\t\t\t\t\t\t\tstyle.borderLeftStyle = qStyle('border-left-style');\n\t\t\t\t\t\t\tstyle.borderRightWidth = qStyle('border-right-width');\n\t\t\t\t\t\t\tstyle.borderRightColor = qStyle('border-right-color');\n\t\t\t\t\t\t\tstyle.borderRightStyle = qStyle('border-right-style');\n\t\t\t\t\t\t\t//end box model\n\n\t\t\t\t\t\t\t//element setup\n\t\t\t\t\t\t\tplaceholder.className = s.cssClasses.placeholder + ' ' + s.cssClasses.placeholder + '-' + s.mode;\n\t\t\t\t\t\t\tplaceholder.innerHTML = '<div>' + s.placeholder + '</div>';\n\t\t\t\t\t\t\tel.parentNode.insertBefore(placeholder, el);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tel.className += ' ' + s.cssClasses.clear;\n\n\t\t\t\t\t\tstyle.display = '';\n\t\t\t\t\t\t// Add base P tag and do auto focus, give it a min height if el has one\n\t\t\t\t\t\tstyle.minHeight = el.clientHeight + 'px';\n\t\t\t\t\t\tstyle.minWidth = el.clientWidth + 'px';\n\n\t\t\t\t\t\tif (s.mode !== Medium.inlineMode) {\n\t\t\t\t\t\t\tutils.setupContents();\n\n\t\t\t\t\t\t\tif (childCount === 0 && el.firstChild) {\n\t\t\t\t\t\t\t\tcursor.set(0, el.firstChild);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tel.placeHolderActive = true;*/\n\t\t\t\t} else if (el.placeHolderActive) {\n\t\t\t\t\tel.placeHolderActive = false;\n\t\t\t\t\tstyle.display = 'none';\n\t\t\t\t\tel.className = trim(el.className.replace(s.cssClasses.clear, ''));\n\t\t\t\t\tutils.setupContents();\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Cleans element\n\t\t\t * @param {HtmlElement} [el] default is settings.element\n\t\t\t */\n\t\t\tclean: function (el) {\n\n\t\t\t\t/*\n\t\t\t\t * Deletes invalid nodes\n\t\t\t\t * Removes Attributes\n\t\t\t\t */\n\t\t\t\tvar s = this.settings,\n\t\t\t\t\tplaceholderClass = s.cssClasses.placeholder,\n\t\t\t\t\tattributesToRemove = (s.attributes || {}).remove || [],\n\t\t\t\t\ttags = s.tags || {},\n\t\t\t\t\tonlyOuter = tags.outerLevel || null,\n\t\t\t\t\tonlyInner = tags.innerLevel || null,\n\t\t\t\t\touterSwitch = {},\n\t\t\t\t\tinnerSwitch = {},\n\t\t\t\t\tparagraphTag = (tags.paragraph || '').toUpperCase(),\n\t\t\t\t\thtml = this.html,\n\t\t\t\t\tattr,\n\t\t\t\t\ttext,\n\t\t\t\t\tj;\n\n\t\t\t\tel = el || s.element;\n\n\t\t\t\tif (onlyOuter !== null) {\n\t\t\t\t\tfor (j = 0; j < onlyOuter.length; j++) {\n\t\t\t\t\t\touterSwitch[onlyOuter[j].toUpperCase()] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (onlyInner !== null) {\n\t\t\t\t\tfor (j = 0; j < onlyInner.length; j++) {\n\t\t\t\t\t\tinnerSwitch[onlyInner[j].toUpperCase()] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.utils.traverseAll(el, {\n\t\t\t\t\telement: function (child, i, depth, parent) {\n\t\t\t\t\t\tvar nodeName = child.nodeName,\n\t\t\t\t\t\t\tshouldDelete = true;\n\n\t\t\t\t\t\t// Remove attributes\n\t\t\t\t\t\tfor (j = 0; j < attributesToRemove.length; j++) {\n\t\t\t\t\t\t\tattr = attributesToRemove[j];\n\t\t\t\t\t\t\tif (child.hasAttribute(attr)) {\n\t\t\t\t\t\t\t\tif (child.getAttribute(attr) !== placeholderClass) {\n\t\t\t\t\t\t\t\t\tchild.removeAttribute(attr);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (onlyOuter === null && onlyInner === null) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (depth === 1 && outerSwitch[nodeName] !== undefined) {\n\t\t\t\t\t\t\tshouldDelete = false;\n\t\t\t\t\t\t} else if (depth > 1 && innerSwitch[nodeName] !== undefined) {\n\t\t\t\t\t\t\tshouldDelete = false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Convert tags or delete\n\t\t\t\t\t\tif (shouldDelete) {\n\t\t\t\t\t\t\tif (w.getComputedStyle(child, null).getPropertyValue('display') === 'block') {\n\t\t\t\t\t\t\t\tif (paragraphTag.length > 0 && paragraphTag !== nodeName) {\n\t\t\t\t\t\t\t\t\thtml.changeTag(child, paragraphTag);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (depth > 1) {\n\t\t\t\t\t\t\t\t\twhile (parent.childNodes.length > i) {\n\t\t\t\t\t\t\t\t\t\tparent.parentNode.insertBefore(parent.lastChild, parent.nextSibling);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tswitch (nodeName) {\n\t\t\t\t\t\t\t\t\tcase 'BR':\n\t\t\t\t\t\t\t\t\t\tif (child === child.parentNode.lastChild) {\n\t\t\t\t\t\t\t\t\t\t\tif (child === child.parentNode.firstChild) {\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\ttext = document.createTextNode(\"\");\n\t\t\t\t\t\t\t\t\t\t\ttext.innerHTML = '&nbsp';\n\t\t\t\t\t\t\t\t\t\t\tparent.insertBefore(text, child);\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\twhile (child.firstChild !== null) {\n\t\t\t\t\t\t\t\t\t\t\tparent.insertBefore(child.firstChild, child);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\thtml.deleteNode(child);\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tlastChild: function () {\n\t\t\t\treturn this.element.lastChild;\n\t\t\t},\n\t\t\taddTag: function (tag, shouldFocus, isEditable, afterElement) {\n\t\t\t\tif (!this.settings.beforeAddTag(tag, shouldFocus, isEditable, afterElement)) {\n\t\t\t\t\tvar newEl = d.createElement(tag),\n\t\t\t\t\t\ttoFocus;\n\n\t\t\t\t\tif (typeof isEditable !== \"undefined\" && isEditable === false) {\n\t\t\t\t\t\tnewEl.contentEditable = false;\n\t\t\t\t\t}\n\t\t\t\t\tif (newEl.innerHTML.length == 0) {\n\t\t\t\t\t\tnewEl.innerHTML = ' ';\n\t\t\t\t\t}\n\t\t\t\t\tif (afterElement && afterElement.nextSibling) {\n\t\t\t\t\t\tafterElement.parentNode.insertBefore(newEl, afterElement.nextSibling);\n\t\t\t\t\t\ttoFocus = afterElement.nextSibling;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.settings.element.appendChild(newEl);\n\t\t\t\t\t\ttoFocus = this.html.lastChild();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (shouldFocus) {\n\t\t\t\t\t\tthis.cache.focusedElement = toFocus;\n\t\t\t\t\t\tthis.cursor.set(0, toFocus);\n\t\t\t\t\t}\n\t\t\t\t\treturn newEl;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\tbaseAtCaret: function () {\n\t\t\t\tif (!this.medium.isActive()) return null;\n\n\t\t\t\tvar sel = w.getSelection ? w.getSelection() : document.selection;\n\n\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\tvar selRange = sel.getRangeAt(0),\n\t\t\t\t\t\tcontainer = selRange.endContainer;\n\n\t\t\t\t\tswitch (container.nodeType) {\n\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\tif (container.data && container.data.length != selRange.endOffset) return false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn container;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\tgetTopLevel: function (container) {\n\t\t\t\twhile (container && container.parentNode !== this.element) {\n\t\t\t\t\tcontainer = container.parentNode;\n\t\t\t\t}\n\t\t\t\treturn container;\n\t\t\t},\n\t\t\tatCaret: function () {\n\t\t\t\tvar container = this.baseAtCaret() || {},\n\t\t\t\t\tel = this.element;\n\n\t\t\t\tif (container === false) return null;\n\n\t\t\t\tcontainer = this.getTopLevel(container);\n\t\t\t\t//while (container && container.parentNode !== el) {\n\t\t\t\t//\tcontainer = container.parentNode;\n\t\t\t\t//}\n\n\t\t\t\tif (container && container.nodeType == 1) {\n\t\t\t\t\treturn container;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttextElementsAtCaret: function () {\n\t\t\t\tif (!this.medium.isActive()) return null;\n\n\t\t\t\tvar sel = w.getSelection ? w.getSelection() : document.selection;\n\n\t\t\t\tif (sel.rangeCount) {\n\t\t\t\t\tvar selRange = sel.getRangeAt(0),\n\t\t\t\t\t\t//container = selRange.endContainer;\n\t\t\t\t\t\tcontainerStart = this.getTopLevel(selRange.startContainer),\n\t\t\t\t\t\tcontainerEnd = this.getTopLevel(selRange.endContainer);\n\n\t\t\t\t\tvar arr = [];\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tif (containerStart.nodeType ==1) { \n\t\t\t\t\t\t    arr.push(containerStart);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (containerStart === containerEnd || !containerStart.nextElementSibling) break;\n                        containerStart = containerStart.nextElementSibling;\t\t\t\t\t\n\t\t\t\t\t};\n\t\t\t\t\t\n\t\t\t\t\t//while (containerStart && containerStart.parentNode !== this.element) {\n\t\t\t\t\t//\tcontainerStart = containerStart.parentNode;\n\t\t\t\t\t//}\n\t\t\t\t\t\n\n\t\t\t\t\treturn arr;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t};\n\n\t\tMedium.Action = function () {\n\t\t};\n\t\tMedium.Action.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t},\n\t\t\tlisten: function () {\n\t\t\t\tvar el = this.element,\n\t\t\t\t\tintercept = this.intercept;\n\n\t\t\t\tthis.utils\n\t\t\t\t\t.addEvent(el, 'keyup', intercept.up)\n\t\t\t\t\t.addEvent(el, 'keydown', intercept.down)\n\t\t\t\t\t.addEvent(el, 'focus', intercept.focus)\n\t\t\t\t\t.addEvent(el, 'blur', intercept.blur)\n\t\t\t\t\t.addEvent(el, 'paste', this.settings.pasteEventHandler);\n\t\t\t},\n\t\t\tpreserveElementFocus: function () {\n\t\t\t\t// Fetch node that has focus\n\t\t\t\tvar anchorNode = w.getSelection ? w.getSelection().anchorNode : d.activeElement;\n\t\t\t\tif (anchorNode) {\n\t\t\t\t\tvar cache = this.medium.cache,\n\t\t\t\t\t\ts = this.settings,\n\t\t\t\t\t\tcur = anchorNode.parentNode,\n\t\t\t\t\t\tchildren = s.element.children,\n\t\t\t\t\t\tdiff = cur !== cache.focusedElement,\n\t\t\t\t\t\telementIndex = 0,\n\t\t\t\t\t\ti;\n\n\t\t\t\t\t// anchorNode is our target if element is empty\n\t\t\t\t\tif (cur === s.element) {\n\t\t\t\t\t\tcur = anchorNode;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Find our child index\n\t\t\t\t\tfor (i = 0; i < children.length; i++) {\n\t\t\t\t\t\tif (cur === children[i]) {\n\t\t\t\t\t\t\telementIndex = i;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Focused element is different\n\t\t\t\t\tif (diff) {\n\t\t\t\t\t\tcache.focusedElement = cur;\n\t\t\t\t\t\tcache.focusedElementIndex = elementIndex;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tMedium.Cache = function () {\n\t\t\tthis.initialized = false;\n\t\t\tthis.cmd = false;\n\t\t\tthis.focusedElement = null\n\t\t};\n\t\tMedium.Cache.prototype = {\n\t\t\tsetBridge: function (bridge) {\n\t\t\t\tfor (var i in bridge) {\n\t\t\t\t\tthis[i] = bridge[i];\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t//Modes;\n\t\tMedium.inlineMode = 'inline';\n\t\tMedium.partialMode = 'partial';\n\t\tMedium.richMode = 'rich';\n\t\tMedium.Messages = {\n\t\t\tpastHere: 'Paste Here'\n\t\t};\n\n\t\treturn Medium;\n\t}());\n\n\tif (typeof define === 'function' && define['amd']) {\n\t\tdefine(function () { return Medium; });\n\t} else if (typeof module !== 'undefined' && module.exports) {\n\t\tmodule.exports = Medium;\n\t} else if (typeof this !== 'undefined') {\n\t\tthis.Medium = Medium;\n\t}\n\n}).call(this, window, document);\n"
  },
  {
    "path": "public/assets/js/source/util--geo-complete.js",
    "content": "/**\n * jQuery Geocoding and Places Autocomplete Plugin - V 1.6.4\n *\n * @author Martin Kleppe <kleppe@ubilabs.net>, 2014\n * @author Ubilabs http://ubilabs.net, 2014\n * @license MIT License <http://www.opensource.org/licenses/mit-license.php>\n */\n(function($,window,document,undefined){var defaults={bounds:true,country:null,map:false,details:false,detailsAttribute:\"name\",autoselect:true,location:false,mapOptions:{zoom:14,scrollwheel:false,mapTypeId:\"roadmap\"},markerOptions:{draggable:false},maxZoom:16,types:[\"geocode\"],blur:false};var componentTypes=(\"street_address route intersection political \"+\"country administrative_area_level_1 administrative_area_level_2 \"+\"administrative_area_level_3 colloquial_area locality sublocality \"+\"neighborhood premise subpremise postal_code natural_feature airport \"+\"park point_of_interest post_box street_number floor room \"+\"lat lng viewport location \"+\"formatted_address location_type bounds\").split(\" \");var placesDetails=(\"id place_id url website vicinity reference name rating \"+\"international_phone_number icon formatted_phone_number\").split(\" \");function GeoComplete(input,options){this.options=$.extend(true,{},defaults,options);this.input=input;this.$input=$(input);this._defaults=defaults;this._name=\"geocomplete\";this.init()}$.extend(GeoComplete.prototype,{init:function(){this.initMap();this.initMarker();this.initGeocoder();this.initDetails();this.initLocation()},initMap:function(){if(!this.options.map){return}if(typeof this.options.map.setCenter==\"function\"){this.map=this.options.map;return}this.map=new google.maps.Map($(this.options.map)[0],this.options.mapOptions);google.maps.event.addListener(this.map,\"click\",$.proxy(this.mapClicked,this));google.maps.event.addListener(this.map,\"zoom_changed\",$.proxy(this.mapZoomed,this))},initMarker:function(){if(!this.map){return}var options=$.extend(this.options.markerOptions,{map:this.map});if(options.disabled){return}this.marker=new google.maps.Marker(options);google.maps.event.addListener(this.marker,\"dragend\",$.proxy(this.markerDragged,this))},initGeocoder:function(){var options={types:this.options.types,bounds:this.options.bounds===true?null:this.options.bounds,componentRestrictions:this.options.componentRestrictions};if(this.options.country){options.componentRestrictions={country:this.options.country}}this.autocomplete=new google.maps.places.Autocomplete(this.input,options);this.geocoder=new google.maps.Geocoder;if(this.map&&this.options.bounds===true){this.autocomplete.bindTo(\"bounds\",this.map)}google.maps.event.addListener(this.autocomplete,\"place_changed\",$.proxy(this.placeChanged,this));this.$input.keypress(function(event){if(event.keyCode===13){return false}});this.$input.bind(\"geocode\",$.proxy(function(){this.find()},this));if(this.options.blur===true){this.$input.blur($.proxy(function(){this.find()},this))}},initDetails:function(){if(!this.options.details){return}var $details=$(this.options.details),attribute=this.options.detailsAttribute,details={};function setDetail(value){details[value]=$details.find(\"[\"+attribute+\"=\"+value+\"]\")}$.each(componentTypes,function(index,key){setDetail(key);setDetail(key+\"_short\")});$.each(placesDetails,function(index,key){setDetail(key)});this.$details=$details;this.details=details},initLocation:function(){var location=this.options.location,latLng;if(!location){return}if(typeof location==\"string\"){this.find(location);return}if(location instanceof Array){latLng=new google.maps.LatLng(location[0],location[1])}if(location instanceof google.maps.LatLng){latLng=location}if(latLng){if(this.map){this.map.setCenter(latLng)}if(this.marker){this.marker.setPosition(latLng)}}},find:function(address){this.geocode({address:address||this.$input.val()})},geocode:function(request){if(this.options.bounds&&!request.bounds){if(this.options.bounds===true){request.bounds=this.map&&this.map.getBounds()}else{request.bounds=this.options.bounds}}if(this.options.country){request.region=this.options.country}this.geocoder.geocode(request,$.proxy(this.handleGeocode,this))},selectFirstResult:function(){var selected=\"\";if($(\".pac-item-selected\")[0]){selected=\"-selected\"}var $span1=$(\".pac-container .pac-item\"+selected+\":first span:nth-child(2)\").text();var $span2=$(\".pac-container .pac-item\"+selected+\":first span:nth-child(3)\").text();var firstResult=$span1;if($span2){firstResult+=\" - \"+$span2}this.$input.val(firstResult);return firstResult},handleGeocode:function(results,status){if(status===google.maps.GeocoderStatus.OK){var result=results[0];this.$input.val(result.formatted_address);this.update(result);if(results.length>1){this.trigger(\"geocode:multiple\",results)}}else{this.trigger(\"geocode:error\",status)}},trigger:function(event,argument){this.$input.trigger(event,[argument])},center:function(geometry){if(geometry.viewport){this.map.fitBounds(geometry.viewport);if(this.map.getZoom()>this.options.maxZoom){this.map.setZoom(this.options.maxZoom)}}else{this.map.setZoom(this.options.maxZoom);this.map.setCenter(geometry.location)}if(this.marker){this.marker.setPosition(geometry.location);this.marker.setAnimation(this.options.markerOptions.animation)}},update:function(result){if(this.map){this.center(result.geometry)}if(this.$details){this.fillDetails(result)}this.trigger(\"geocode:result\",result)},fillDetails:function(result){var data={},geometry=result.geometry,viewport=geometry.viewport,bounds=geometry.bounds;$.each(result.address_components,function(index,object){var name=object.types[0];$.each(object.types,function(index,name){data[name]=object.long_name;data[name+\"_short\"]=object.short_name})});$.each(placesDetails,function(index,key){data[key]=result[key]});$.extend(data,{formatted_address:result.formatted_address,location_type:geometry.location_type||\"PLACES\",viewport:viewport,bounds:bounds,location:geometry.location,lat:geometry.location.lat(),lng:geometry.location.lng()});$.each(this.details,$.proxy(function(key,$detail){var value=data[key];this.setDetail($detail,value)},this));this.data=data},setDetail:function($element,value){if(value===undefined){value=\"\"}else if(typeof value.toUrlValue==\"function\"){value=value.toUrlValue()}if($element.is(\":input\")){$element.val(value)}else{$element.text(value)}},markerDragged:function(event){this.trigger(\"geocode:dragged\",event.latLng)},mapClicked:function(event){this.trigger(\"geocode:click\",event.latLng)},mapZoomed:function(event){this.trigger(\"geocode:zoom\",this.map.getZoom())},resetMarker:function(){this.marker.setPosition(this.data.location);this.setDetail(this.details.lat,this.data.location.lat());this.setDetail(this.details.lng,this.data.location.lng())},placeChanged:function(){var place=this.autocomplete.getPlace();if(!place||!place.geometry){if(this.options.autoselect){var autoSelection=this.selectFirstResult();this.find(autoSelection)}}else{this.update(place)}}});$.fn.geocomplete=function(options){var attribute=\"plugin_geocomplete\";if(typeof options==\"string\"){var instance=$(this).data(attribute)||$(this).geocomplete().data(attribute),prop=instance[options];if(typeof prop==\"function\"){prop.apply(instance,Array.prototype.slice.call(arguments,1));return $(this)}else{if(arguments.length==2){prop=arguments[1]}return prop}}else{return this.each(function(){var instance=$.data(this,attribute);if(!instance){instance=new GeoComplete(this,options);$.data(this,attribute,instance)}})}}})(jQuery,window,document);"
  },
  {
    "path": "public/assets/js/source/util--imagesloaded.js",
    "content": "// packaged - 3.1.8\n(function () {\n\n\t/**\n\t * Class for managing events.\n\t * Can be extended to provide event functionality in other classes.\n\t *\n\t * @class EventEmitter Manages event registering and emitting.\n\t */\n\tfunction EventEmitter() {}\n\n\t// Shortcuts to improve speed and size\n\tvar proto = EventEmitter.prototype;\n\tvar exports = this;\n\tvar originalGlobalValue = exports.EventEmitter;\n\n\t/**\n\t * Finds the index of the listener for the event in it's storage array.\n\t *\n\t * @param {Function[]} listeners Array of listeners to search through.\n\t * @param {Function} listener Method to look for.\n\t * @return {Number} Index of the specified listener, -1 if not found\n\t * @api private\n\t */\n\tfunction indexOfListener(listeners, listener) {\n\t\tvar i = listeners.length;\n\t\twhile (i--) {\n\t\t\tif (listeners[i].listener === listener) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t}\n\n\t/**\n\t * Alias a method while keeping the context correct, to allow for overwriting of target method.\n\t *\n\t * @param {String} name The name of the target method.\n\t * @return {Function} The aliased method\n\t * @api private\n\t */\n\tfunction alias(name) {\n\t\treturn function aliasClosure() {\n\t\t\treturn this[name].apply(this, arguments);\n\t\t};\n\t}\n\n\t/**\n\t * Returns the listener array for the specified event.\n\t * Will initialise the event object and listener arrays if required.\n\t * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.\n\t * Each property in the object response is an array of listener functions.\n\t *\n\t * @param {String|RegExp} evt Name of the event to return the listeners from.\n\t * @return {Function[]|Object} All listener functions for the event.\n\t */\n\tproto.getListeners = function getListeners(evt) {\n\t\tvar events = this._getEvents();\n\t\tvar response;\n\t\tvar key;\n\n\t\t// Return a concatenated array of all matching events if\n\t\t// the selector is a regular expression.\n\t\tif (typeof evt === 'object') {\n\t\t\tresponse = {};\n\t\t\tfor (key in events) {\n\t\t\t\tif (events.hasOwnProperty(key) && evt.test(key)) {\n\t\t\t\t\tresponse[key] = events[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tresponse = events[evt] || (events[evt] = []);\n\t\t}\n\n\t\treturn response;\n\t};\n\n\t/**\n\t * Takes a list of listener objects and flattens it into a list of listener functions.\n\t *\n\t * @param {Object[]} listeners Raw listener objects.\n\t * @return {Function[]} Just the listener functions.\n\t */\n\tproto.flattenListeners = function flattenListeners(listeners) {\n\t\tvar flatListeners = [];\n\t\tvar i;\n\n\t\tfor (i = 0; i < listeners.length; i += 1) {\n\t\t\tflatListeners.push(listeners[i].listener);\n\t\t}\n\n\t\treturn flatListeners;\n\t};\n\n\t/**\n\t * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.\n\t *\n\t * @param {String|RegExp} evt Name of the event to return the listeners from.\n\t * @return {Object} All listener functions for an event in an object.\n\t */\n\tproto.getListenersAsObject = function getListenersAsObject(evt) {\n\t\tvar listeners = this.getListeners(evt);\n\t\tvar response;\n\n\t\tif (listeners instanceof Array) {\n\t\t\tresponse = {};\n\t\t\tresponse[evt] = listeners;\n\t\t}\n\n\t\treturn response || listeners;\n\t};\n\n\t/**\n\t * Adds a listener function to the specified event.\n\t * The listener will not be added if it is a duplicate.\n\t * If the listener returns true then it will be removed after it is called.\n\t * If you pass a regular expression as the event name then the listener will be added to all events that match it.\n\t *\n\t * @param {String|RegExp} evt Name of the event to attach the listener to.\n\t * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.addListener = function addListener(evt, listener) {\n\t\tvar listeners = this.getListenersAsObject(evt);\n\t\tvar listenerIsWrapped = typeof listener === 'object';\n\t\tvar key;\n\n\t\tfor (key in listeners) {\n\t\t\tif (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {\n\t\t\t\tlisteners[key].push(listenerIsWrapped ? listener : {\n\t\t\t\t\tlistener: listener,\n\t\t\t\t\tonce: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Alias of addListener\n\t */\n\tproto.on = alias('addListener');\n\n\t/**\n\t * Semi-alias of addListener. It will add a listener that will be\n\t * automatically removed after it's first execution.\n\t *\n\t * @param {String|RegExp} evt Name of the event to attach the listener to.\n\t * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.addOnceListener = function addOnceListener(evt, listener) {\n\t\treturn this.addListener(evt, {\n\t\t\tlistener: listener,\n\t\t\tonce: true\n\t\t});\n\t};\n\n\t/**\n\t * Alias of addOnceListener.\n\t */\n\tproto.once = alias('addOnceListener');\n\n\t/**\n\t * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.\n\t * You need to tell it what event names should be matched by a regex.\n\t *\n\t * @param {String} evt Name of the event to create.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.defineEvent = function defineEvent(evt) {\n\t\tthis.getListeners(evt);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Uses defineEvent to define multiple events.\n\t *\n\t * @param {String[]} evts An array of event names to define.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.defineEvents = function defineEvents(evts) {\n\t\tfor (var i = 0; i < evts.length; i += 1) {\n\t\t\tthis.defineEvent(evts[i]);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Removes a listener function from the specified event.\n\t * When passed a regular expression as the event name, it will remove the listener from all events that match it.\n\t *\n\t * @param {String|RegExp} evt Name of the event to remove the listener from.\n\t * @param {Function} listener Method to remove from the event.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.removeListener = function removeListener(evt, listener) {\n\t\tvar listeners = this.getListenersAsObject(evt);\n\t\tvar index;\n\t\tvar key;\n\n\t\tfor (key in listeners) {\n\t\t\tif (listeners.hasOwnProperty(key)) {\n\t\t\t\tindex = indexOfListener(listeners[key], listener);\n\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\tlisteners[key].splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Alias of removeListener\n\t */\n\tproto.off = alias('removeListener');\n\n\t/**\n\t * Adds listeners in bulk using the manipulateListeners method.\n\t * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.\n\t * You can also pass it a regular expression to add the array of listeners to all events that match it.\n\t * Yeah, this function does quite a bit. That's probably a bad thing.\n\t *\n\t * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.\n\t * @param {Function[]} [listeners] An optional array of listener functions to add.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.addListeners = function addListeners(evt, listeners) {\n\t\t// Pass through to manipulateListeners\n\t\treturn this.manipulateListeners(false, evt, listeners);\n\t};\n\n\t/**\n\t * Removes listeners in bulk using the manipulateListeners method.\n\t * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n\t * You can also pass it an event name and an array of listeners to be removed.\n\t * You can also pass it a regular expression to remove the listeners from all events that match it.\n\t *\n\t * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.\n\t * @param {Function[]} [listeners] An optional array of listener functions to remove.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.removeListeners = function removeListeners(evt, listeners) {\n\t\t// Pass through to manipulateListeners\n\t\treturn this.manipulateListeners(true, evt, listeners);\n\t};\n\n\t/**\n\t * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.\n\t * The first argument will determine if the listeners are removed (true) or added (false).\n\t * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n\t * You can also pass it an event name and an array of listeners to be added/removed.\n\t * You can also pass it a regular expression to manipulate the listeners of all events that match it.\n\t *\n\t * @param {Boolean} remove True if you want to remove listeners, false if you want to add.\n\t * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.\n\t * @param {Function[]} [listeners] An optional array of listener functions to add/remove.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {\n\t\tvar i;\n\t\tvar value;\n\t\tvar single = remove ? this.removeListener : this.addListener;\n\t\tvar multiple = remove ? this.removeListeners : this.addListeners;\n\n\t\t// If evt is an object then pass each of it's properties to this method\n\t\tif (typeof evt === 'object' && !(evt instanceof RegExp)) {\n\t\t\tfor (i in evt) {\n\t\t\t\tif (evt.hasOwnProperty(i) && (value = evt[i])) {\n\t\t\t\t\t// Pass the single listener straight through to the singular method\n\t\t\t\t\tif (typeof value === 'function') {\n\t\t\t\t\t\tsingle.call(this, i, value);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t// Otherwise pass back to the multiple function\n\t\t\t\t\t\tmultiple.call(this, i, value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// So evt must be a string\n\t\t\t// And listeners must be an array of listeners\n\t\t\t// Loop over it and pass each one to the multiple method\n\t\t\ti = listeners.length;\n\t\t\twhile (i--) {\n\t\t\t\tsingle.call(this, evt, listeners[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Removes all listeners from a specified event.\n\t * If you do not specify an event then all listeners will be removed.\n\t * That means every event will be emptied.\n\t * You can also pass a regex to remove all events that match it.\n\t *\n\t * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.removeEvent = function removeEvent(evt) {\n\t\tvar type = typeof evt;\n\t\tvar events = this._getEvents();\n\t\tvar key;\n\n\t\t// Remove different things depending on the state of evt\n\t\tif (type === 'string') {\n\t\t\t// Remove all listeners for the specified event\n\t\t\tdelete events[evt];\n\t\t}\n\t\telse if (type === 'object') {\n\t\t\t// Remove all events matching the regex.\n\t\t\tfor (key in events) {\n\t\t\t\tif (events.hasOwnProperty(key) && evt.test(key)) {\n\t\t\t\t\tdelete events[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// Remove all listeners in all events\n\t\t\tdelete this._events;\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Alias of removeEvent.\n\t *\n\t * Added to mirror the node API.\n\t */\n\tproto.removeAllListeners = alias('removeEvent');\n\n\t/**\n\t * Emits an event of your choice.\n\t * When emitted, every listener attached to that event will be executed.\n\t * If you pass the optional argument array then those arguments will be passed to every listener upon execution.\n\t * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.\n\t * So they will not arrive within the array on the other side, they will be separate.\n\t * You can also pass a regular expression to emit to all events that match it.\n\t *\n\t * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n\t * @param {Array} [args] Optional array of arguments to be passed to each listener.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.emitEvent = function emitEvent(evt, args) {\n\t\tvar listeners = this.getListenersAsObject(evt);\n\t\tvar listener;\n\t\tvar i;\n\t\tvar key;\n\t\tvar response;\n\n\t\tfor (key in listeners) {\n\t\t\tif (listeners.hasOwnProperty(key)) {\n\t\t\t\ti = listeners[key].length;\n\n\t\t\t\twhile (i--) {\n\t\t\t\t\t// If the listener returns true then it shall be removed from the event\n\t\t\t\t\t// The function is executed either with a basic call or an apply if there is an args array\n\t\t\t\t\tlistener = listeners[key][i];\n\n\t\t\t\t\tif (listener.once === true) {\n\t\t\t\t\t\tthis.removeListener(evt, listener.listener);\n\t\t\t\t\t}\n\n\t\t\t\t\tresponse = listener.listener.apply(this, args || []);\n\n\t\t\t\t\tif (response === this._getOnceReturnValue()) {\n\t\t\t\t\t\tthis.removeListener(evt, listener.listener);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Alias of emitEvent\n\t */\n\tproto.trigger = alias('emitEvent');\n\n\t/**\n\t * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.\n\t * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.\n\t *\n\t * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n\t * @param {...*} Optional additional arguments to be passed to each listener.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.emit = function emit(evt) {\n\t\tvar args = Array.prototype.slice.call(arguments, 1);\n\t\treturn this.emitEvent(evt, args);\n\t};\n\n\t/**\n\t * Sets the current value to check against when executing listeners. If a\n\t * listeners return value matches the one set here then it will be removed\n\t * after execution. This value defaults to true.\n\t *\n\t * @param {*} value The new value to check for when executing listeners.\n\t * @return {Object} Current instance of EventEmitter for chaining.\n\t */\n\tproto.setOnceReturnValue = function setOnceReturnValue(value) {\n\t\tthis._onceReturnValue = value;\n\t\treturn this;\n\t};\n\n\t/**\n\t * Fetches the current value to check against when executing listeners. If\n\t * the listeners return value matches this one then it should be removed\n\t * automatically. It will return true by default.\n\t *\n\t * @return {*|Boolean} The current value to check for or the default, true.\n\t * @api private\n\t */\n\tproto._getOnceReturnValue = function _getOnceReturnValue() {\n\t\tif (this.hasOwnProperty('_onceReturnValue')) {\n\t\t\treturn this._onceReturnValue;\n\t\t}\n\t\telse {\n\t\t\treturn true;\n\t\t}\n\t};\n\n\t/**\n\t * Fetches the events object and creates one if required.\n\t *\n\t * @return {Object} The events storage object.\n\t * @api private\n\t */\n\tproto._getEvents = function _getEvents() {\n\t\treturn this._events || (this._events = {});\n\t};\n\n\t/**\n\t * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.\n\t *\n\t * @return {Function} Non conflicting EventEmitter class.\n\t */\n\tEventEmitter.noConflict = function noConflict() {\n\t\texports.EventEmitter = originalGlobalValue;\n\t\treturn EventEmitter;\n\t};\n\n\t// Expose the class either via AMD, CommonJS or the global object\n\tif (typeof define === 'function' && define.amd) {\n\t\tdefine('eventEmitter/EventEmitter',[],function () {\n\t\t\treturn EventEmitter;\n\t\t});\n\t}\n\telse if (typeof module === 'object' && module.exports){\n\t\tmodule.exports = EventEmitter;\n\t}\n\telse {\n\t\tthis.EventEmitter = EventEmitter;\n\t}\n}.call(this));\n\n/*!\n * eventie v1.0.4\n * event binding helper\n *   eventie.bind( elem, 'click', myFn )\n *   eventie.unbind( elem, 'click', myFn )\n */\n\n/*jshint browser: true, undef: true, unused: true */\n/*global define: false */\n\n( function( window ) {\n\n\n\nvar docElem = document.documentElement;\n\nvar bind = function() {};\n\nfunction getIEEvent( obj ) {\n  var event = window.event;\n  // add event.target\n  event.target = event.target || event.srcElement || obj;\n  return event;\n}\n\nif ( docElem.addEventListener ) {\n  bind = function( obj, type, fn ) {\n    obj.addEventListener( type, fn, false );\n  };\n} else if ( docElem.attachEvent ) {\n  bind = function( obj, type, fn ) {\n    obj[ type + fn ] = fn.handleEvent ?\n      function() {\n        var event = getIEEvent( obj );\n        fn.handleEvent.call( fn, event );\n      } :\n      function() {\n        var event = getIEEvent( obj );\n        fn.call( obj, event );\n      };\n    obj.attachEvent( \"on\" + type, obj[ type + fn ] );\n  };\n}\n\nvar unbind = function() {};\n\nif ( docElem.removeEventListener ) {\n  unbind = function( obj, type, fn ) {\n    obj.removeEventListener( type, fn, false );\n  };\n} else if ( docElem.detachEvent ) {\n  unbind = function( obj, type, fn ) {\n    obj.detachEvent( \"on\" + type, obj[ type + fn ] );\n    try {\n      delete obj[ type + fn ];\n    } catch ( err ) {\n      // can't delete window object properties\n      obj[ type + fn ] = undefined;\n    }\n  };\n}\n\nvar eventie = {\n  bind: bind,\n  unbind: unbind\n};\n\n// transport\nif ( typeof define === 'function' && define.amd ) {\n  // AMD\n  define( 'eventie/eventie',eventie );\n} else {\n  // browser global\n  window.eventie = eventie;\n}\n\n})( this );\n\n/*!\n * imagesLoaded v3.1.8\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n\n( function( window, factory ) { \n  // universal module definition\n\n  /*global define: false, module: false, require: false */\n\n  if ( typeof define === 'function' && define.amd ) {\n    // AMD\n    define( [\n      'eventEmitter/EventEmitter',\n      'eventie/eventie'\n    ], function( EventEmitter, eventie ) {\n      return factory( window, EventEmitter, eventie );\n    });\n  } else if ( typeof exports === 'object' ) {\n    // CommonJS\n    module.exports = factory(\n      window,\n      require('wolfy87-eventemitter'),\n      require('eventie')\n    );\n  } else {\n    // browser global\n    window.imagesLoaded = factory(\n      window,\n      window.EventEmitter,\n      window.eventie\n    );\n  }\n\n})( window,\n\n// --------------------------  factory -------------------------- //\n\nfunction factory( window, EventEmitter, eventie ) {\n\n\n\nvar $ = window.jQuery;\nvar console = window.console;\nvar hasConsole = typeof console !== 'undefined';\n\n// -------------------------- helpers -------------------------- //\n\n// extend objects\nfunction extend( a, b ) {\n  for ( var prop in b ) {\n    a[ prop ] = b[ prop ];\n  }\n  return a;\n}\n\nvar objToString = Object.prototype.toString;\nfunction isArray( obj ) {\n  return objToString.call( obj ) === '[object Array]';\n}\n\n// turn element or nodeList into an array\nfunction makeArray( obj ) {\n  var ary = [];\n  if ( isArray( obj ) ) {\n    // use object if already an array\n    ary = obj;\n  } else if ( typeof obj.length === 'number' ) {\n    // convert nodeList to array\n    for ( var i=0, len = obj.length; i < len; i++ ) {\n      ary.push( obj[i] );\n    }\n  } else {\n    // array of single index\n    ary.push( obj );\n  }\n  return ary;\n}\n\n  // -------------------------- imagesLoaded -------------------------- //\n\n  /**\n   * @param {Array, Element, NodeList, String} elem\n   * @param {Object or Function} options - if function, use as callback\n   * @param {Function} onAlways - callback function\n   */\n  function ImagesLoaded( elem, options, onAlways ) {\n    // coerce ImagesLoaded() without new, to be new ImagesLoaded()\n    if ( !( this instanceof ImagesLoaded ) ) {\n      return new ImagesLoaded( elem, options );\n    }\n    // use elem as selector string\n    if ( typeof elem === 'string' ) {\n      elem = document.querySelectorAll( elem );\n    }\n\n    this.elements = makeArray( elem );\n    this.options = extend( {}, this.options );\n\n    if ( typeof options === 'function' ) {\n      onAlways = options;\n    } else {\n      extend( this.options, options );\n    }\n\n    if ( onAlways ) {\n      this.on( 'always', onAlways );\n    }\n\n    this.getImages();\n\n    if ( $ ) {\n      // add jQuery Deferred object\n      this.jqDeferred = new $.Deferred();\n    }\n\n    // HACK check async to allow time to bind listeners\n    var _this = this;\n    setTimeout( function() {\n      _this.check();\n    });\n  }\n\n  ImagesLoaded.prototype = new EventEmitter();\n\n  ImagesLoaded.prototype.options = {};\n\n  ImagesLoaded.prototype.getImages = function() {\n    this.images = [];\n\n    // filter & find items if we have an item selector\n    for ( var i=0, len = this.elements.length; i < len; i++ ) {\n      var elem = this.elements[i];\n      // filter siblings\n      if ( elem.nodeName === 'IMG' ) {\n        this.addImage( elem );\n      }\n      // find children\n      // no non-element nodes, #143\n      var nodeType = elem.nodeType;\n      if ( !nodeType || !( nodeType === 1 || nodeType === 9 || nodeType === 11 ) ) {\n        continue;\n      }\n      var childElems = elem.querySelectorAll('img');\n      // concat childElems to filterFound array\n      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {\n        var img = childElems[j];\n        this.addImage( img );\n      }\n    }\n  };\n\n  /**\n   * @param {Image} img\n   */\n  ImagesLoaded.prototype.addImage = function( img ) {\n    var loadingImage = new LoadingImage( img );\n    this.images.push( loadingImage );\n  };\n\n  ImagesLoaded.prototype.check = function() {\n    var _this = this;\n    var checkedCount = 0;\n    var length = this.images.length;\n    this.hasAnyBroken = false;\n    // complete if no images\n    if ( !length ) {\n      this.complete();\n      return;\n    }\n\n    function onConfirm( image, message ) {\n      if ( _this.options.debug && hasConsole ) {\n        console.log( 'confirm', image, message );\n      }\n\n      _this.progress( image );\n      checkedCount++;\n      if ( checkedCount === length ) {\n        _this.complete();\n      }\n      return true; // bind once\n    }\n\n    for ( var i=0; i < length; i++ ) {\n      var loadingImage = this.images[i];\n      loadingImage.on( 'confirm', onConfirm );\n      loadingImage.check();\n    }\n  };\n\n  ImagesLoaded.prototype.progress = function( image ) {\n    this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;\n    // HACK - Chrome triggers event before object properties have changed. #83\n    var _this = this;\n    setTimeout( function() {\n      _this.emit( 'progress', _this, image );\n      if ( _this.jqDeferred && _this.jqDeferred.notify ) {\n        _this.jqDeferred.notify( _this, image );\n      }\n    });\n  };\n\n  ImagesLoaded.prototype.complete = function() {\n    var eventName = this.hasAnyBroken ? 'fail' : 'done';\n    this.isComplete = true;\n    var _this = this;\n    // HACK - another setTimeout so that confirm happens after progress\n    setTimeout( function() {\n      _this.emit( eventName, _this );\n      _this.emit( 'always', _this );\n      if ( _this.jqDeferred ) {\n        var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve';\n        _this.jqDeferred[ jqMethod ]( _this );\n      }\n    });\n  };\n\n  // -------------------------- jquery -------------------------- //\n\n  if ( $ ) {\n    $.fn.imagesLoaded = function( options, callback ) {\n      var instance = new ImagesLoaded( this, options, callback );\n      return instance.jqDeferred.promise( $(this) );\n    };\n  }\n\n\n  // --------------------------  -------------------------- //\n\n  function LoadingImage( img ) {\n    this.img = img;\n  }\n\n  LoadingImage.prototype = new EventEmitter();\n\n  LoadingImage.prototype.check = function() {\n    // first check cached any previous images that have same src\n    var resource = cache[ this.img.src ] || new Resource( this.img.src );\n    if ( resource.isConfirmed ) {\n      this.confirm( resource.isLoaded, 'cached was confirmed' );\n      return;\n    }\n\n    // If complete is true and browser supports natural sizes,\n    // try to check for image status manually.\n    if ( this.img.complete && this.img.naturalWidth !== undefined ) {\n      // report based on naturalWidth\n      this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );\n      return;\n    }\n\n    // If none of the checks above matched, simulate loading on detached element.\n    var _this = this;\n    resource.on( 'confirm', function( resrc, message ) {\n      _this.confirm( resrc.isLoaded, message );\n      return true;\n    });\n\n    resource.check();\n  };\n\n  LoadingImage.prototype.confirm = function( isLoaded, message ) {\n    this.isLoaded = isLoaded;\n    this.emit( 'confirm', this, message );\n  };\n\n  // -------------------------- Resource -------------------------- //\n\n  // Resource checks each src, only once\n  // separate class from LoadingImage to prevent memory leaks. See #115\n\n  var cache = {};\n\n  function Resource( src ) {\n    this.src = src;\n    // add to cache\n    cache[ src ] = this;\n  }\n\n  Resource.prototype = new EventEmitter();\n\n  Resource.prototype.check = function() {\n    // only trigger checking once\n    if ( this.isChecked ) {\n      return;\n    }\n    // simulate loading on detached element\n    var proxyImage = new Image();\n    eventie.bind( proxyImage, 'load', this );\n    eventie.bind( proxyImage, 'error', this );\n    proxyImage.src = this.src;\n    // set flag\n    this.isChecked = true;\n  };\n\n  // ----- events ----- //\n\n  // trigger specified handler for event type\n  Resource.prototype.handleEvent = function( event ) {\n    var method = 'on' + event.type;\n    if ( this[ method ] ) {\n      this[ method ]( event );\n    }\n  };\n\n  Resource.prototype.onload = function( event ) {\n    this.confirm( true, 'onload' );\n    this.unbindProxyEvents( event );\n  };\n\n  Resource.prototype.onerror = function( event ) {\n    this.confirm( false, 'onerror' );\n    this.unbindProxyEvents( event );\n  };\n\n  // ----- confirm ----- //\n\n  Resource.prototype.confirm = function( isLoaded, message ) {\n    this.isConfirmed = true;\n    this.isLoaded = isLoaded;\n    this.emit( 'confirm', this, message );\n  };\n\n  Resource.prototype.unbindProxyEvents = function( event ) {\n    eventie.unbind( event.target, 'load', this );\n    eventie.unbind( event.target, 'error', this );\n  };\n\n  // -----  ----- //\n\n  return ImagesLoaded;\n\n});"
  },
  {
    "path": "public/assets/js/source/util--rangy-classapplier.js",
    "content": "/**\n * Class Applier module for Rangy.\n * Adds, removes and toggles classes on Ranges and Selections\n *\n * Part of Rangy, a cross-browser JavaScript range and selection library\n * http://code.google.com/p/rangy/\n *\n * Depends on Rangy core.\n *\n * Copyright 2014, Tim Down\n * Licensed under the MIT license.\n * Version: 1.3.0-alpha.20140827\n * Build date: 27 August 2014\n */\n(function(factory, root) {\n    if (typeof define == \"function\" && define.amd) {\n        // AMD. Register as an anonymous module with a dependency on Rangy.\n        define([\"./rangy-core\"], factory);\n    } else if (typeof module != \"undefined\" && typeof exports == \"object\") {\n        // Node/CommonJS style\n        module.exports = factory( require(\"rangy\") );\n    } else {\n        // No AMD or CommonJS support so we use the rangy property of root (probably the global variable)\n        factory(root.rangy);\n    }\n})(function(rangy) {\n    rangy.createModule(\"ClassApplier\", [\"WrappedSelection\"], function(api, module) {\n        var dom = api.dom;\n        var DomPosition = dom.DomPosition;\n        var contains = dom.arrayContains;\n        var isHtmlNamespace = dom.isHtmlNamespace;\n\n\n        var defaultTagName = \"span\";\n\n        function each(obj, func) {\n            for (var i in obj) {\n                if (obj.hasOwnProperty(i)) {\n                    if (func(i, obj[i]) === false) {\n                        return false;\n                    }\n                }\n            }\n            return true;\n        }\n        \n        function trim(str) {\n            return str.replace(/^\\s\\s*/, \"\").replace(/\\s\\s*$/, \"\");\n        }\n\n        function hasClass(el, className) {\n            return el.className && new RegExp(\"(?:^|\\\\s)\" + className + \"(?:\\\\s|$)\").test(el.className);\n        }\n\n        function addClass(el, className) {\n            if (el.className) {\n                if (!hasClass(el, className)) {\n                    el.className += \" \" + className;\n                }\n            } else {\n                el.className = className;\n            }\n        }\n\n        var removeClass = (function() {\n            function replacer(matched, whiteSpaceBefore, whiteSpaceAfter) {\n                return (whiteSpaceBefore && whiteSpaceAfter) ? \" \" : \"\";\n            }\n\n            return function(el, className) {\n                if (el.className) {\n                    el.className = el.className.replace(new RegExp(\"(^|\\\\s)\" + className + \"(\\\\s|$)\"), replacer);\n                }\n            };\n        })();\n\n        function sortClassName(className) {\n            return className && className.split(/\\s+/).sort().join(\" \");\n        }\n\n        function getSortedClassName(el) {\n            return sortClassName(el.className);\n        }\n\n        function haveSameClasses(el1, el2) {\n            return getSortedClassName(el1) == getSortedClassName(el2);\n        }\n\n        function movePosition(position, oldParent, oldIndex, newParent, newIndex) {\n            var posNode = position.node, posOffset = position.offset;\n            var newNode = posNode, newOffset = posOffset;\n\n            if (posNode == newParent && posOffset > newIndex) {\n                ++newOffset;\n            }\n\n            if (posNode == oldParent && (posOffset == oldIndex  || posOffset == oldIndex + 1)) {\n                newNode = newParent;\n                newOffset += newIndex - oldIndex;\n            }\n\n            if (posNode == oldParent && posOffset > oldIndex + 1) {\n                --newOffset;\n            }\n\n            position.node = newNode;\n            position.offset = newOffset;\n        }\n        \n        function movePositionWhenRemovingNode(position, parentNode, index) {\n            if (position.node == parentNode && position.offset > index) {\n                --position.offset;\n            }\n        }\n\n        function movePreservingPositions(node, newParent, newIndex, positionsToPreserve) {\n            // For convenience, allow newIndex to be -1 to mean \"insert at the end\".\n            if (newIndex == -1) {\n                newIndex = newParent.childNodes.length;\n            }\n\n            var oldParent = node.parentNode;\n            var oldIndex = dom.getNodeIndex(node);\n\n            for (var i = 0, position; position = positionsToPreserve[i++]; ) {\n                movePosition(position, oldParent, oldIndex, newParent, newIndex);\n            }\n\n            // Now actually move the node.\n            if (newParent.childNodes.length == newIndex) {\n                newParent.appendChild(node);\n            } else {\n                newParent.insertBefore(node, newParent.childNodes[newIndex]);\n            }\n        }\n        \n        function removePreservingPositions(node, positionsToPreserve) {\n\n            var oldParent = node.parentNode;\n            var oldIndex = dom.getNodeIndex(node);\n\n            for (var i = 0, position; position = positionsToPreserve[i++]; ) {\n                movePositionWhenRemovingNode(position, oldParent, oldIndex);\n            }\n\n            node.parentNode.removeChild(node);\n        }\n\n        function moveChildrenPreservingPositions(node, newParent, newIndex, removeNode, positionsToPreserve) {\n            var child, children = [];\n            while ( (child = node.firstChild) ) {\n                movePreservingPositions(child, newParent, newIndex++, positionsToPreserve);\n                children.push(child);\n            }\n            if (removeNode) {\n                removePreservingPositions(node, positionsToPreserve);\n            }\n            return children;\n        }\n\n        function replaceWithOwnChildrenPreservingPositions(element, positionsToPreserve) {\n            return moveChildrenPreservingPositions(element, element.parentNode, dom.getNodeIndex(element), true, positionsToPreserve);\n        }\n\n        function rangeSelectsAnyText(range, textNode) {\n            var textNodeRange = range.cloneRange();\n            textNodeRange.selectNodeContents(textNode);\n\n            var intersectionRange = textNodeRange.intersection(range);\n            var text = intersectionRange ? intersectionRange.toString() : \"\";\n\n            return text != \"\";\n        }\n\n        function getEffectiveTextNodes(range) {\n            var nodes = range.getNodes([3]);\n            \n            // Optimization as per issue 145\n            \n            // Remove non-intersecting text nodes from the start of the range\n            var start = 0, node;\n            while ( (node = nodes[start]) && !rangeSelectsAnyText(range, node) ) {\n                ++start;\n            }\n\n            // Remove non-intersecting text nodes from the start of the range\n            var end = nodes.length - 1;\n            while ( (node = nodes[end]) && !rangeSelectsAnyText(range, node) ) {\n                --end;\n            }\n            \n            return nodes.slice(start, end + 1);\n        }\n\n        function elementsHaveSameNonClassAttributes(el1, el2) {\n            if (el1.attributes.length != el2.attributes.length) return false;\n            for (var i = 0, len = el1.attributes.length, attr1, attr2, name; i < len; ++i) {\n                attr1 = el1.attributes[i];\n                name = attr1.name;\n                if (name != \"class\") {\n                    attr2 = el2.attributes.getNamedItem(name);\n                    if ( (attr1 === null) != (attr2 === null) ) return false;\n                    if (attr1.specified != attr2.specified) return false;\n                    if (attr1.specified && attr1.nodeValue !== attr2.nodeValue) return false;\n                }\n            }\n            return true;\n        }\n\n        function elementHasNonClassAttributes(el, exceptions) {\n            for (var i = 0, len = el.attributes.length, attrName; i < len; ++i) {\n                attrName = el.attributes[i].name;\n                if ( !(exceptions && contains(exceptions, attrName)) && el.attributes[i].specified && attrName != \"class\") {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        function elementHasProperties(el, props) {\n            return each(props, function(p, propValue) {\n                if (typeof propValue == \"object\") {\n                    if (!elementHasProperties(el[p], propValue)) {\n                        return false;\n                    }\n                } else if (el[p] !== propValue) {\n                    return false;\n                }\n            });\n        }\n\n        var getComputedStyleProperty = dom.getComputedStyleProperty;\n        var isEditableElement = (function() {\n            var testEl = document.createElement(\"div\");\n            return typeof testEl.isContentEditable == \"boolean\" ?\n                function (node) {\n                    return node && node.nodeType == 1 && node.isContentEditable;\n                } :\n                function (node) {\n                    if (!node || node.nodeType != 1 || node.contentEditable == \"false\") {\n                        return false;\n                    }\n                    return node.contentEditable == \"true\" || isEditableElement(node.parentNode);\n                };\n        })();\n\n        function isEditingHost(node) {\n            var parent;\n            return node && node.nodeType == 1 &&\n                (( (parent = node.parentNode) && parent.nodeType == 9 && parent.designMode == \"on\") ||\n                (isEditableElement(node) && !isEditableElement(node.parentNode)));\n        }\n\n        function isEditable(node) {\n            return (isEditableElement(node) || (node.nodeType != 1 && isEditableElement(node.parentNode))) && !isEditingHost(node);\n        }\n\n        var inlineDisplayRegex = /^inline(-block|-table)?$/i;\n\n        function isNonInlineElement(node) {\n            return node && node.nodeType == 1 && !inlineDisplayRegex.test(getComputedStyleProperty(node, \"display\"));\n        }\n\n        // White space characters as defined by HTML 4 (http://www.w3.org/TR/html401/struct/text.html)\n        var htmlNonWhiteSpaceRegex = /[^\\r\\n\\t\\f \\u200B]/;\n\n        function isUnrenderedWhiteSpaceNode(node) {\n            if (node.data.length == 0) {\n                return true;\n            }\n            if (htmlNonWhiteSpaceRegex.test(node.data)) {\n                return false;\n            }\n            var cssWhiteSpace = getComputedStyleProperty(node.parentNode, \"whiteSpace\");\n            switch (cssWhiteSpace) {\n                case \"pre\":\n                case \"pre-wrap\":\n                case \"-moz-pre-wrap\":\n                    return false;\n                case \"pre-line\":\n                    if (/[\\r\\n]/.test(node.data)) {\n                        return false;\n                    }\n            }\n\n            // We now have a whitespace-only text node that may be rendered depending on its context. If it is adjacent to a\n            // non-inline element, it will not be rendered. This seems to be a good enough definition.\n            return isNonInlineElement(node.previousSibling) || isNonInlineElement(node.nextSibling);\n        }\n\n        function getRangeBoundaries(ranges) {\n            var positions = [], i, range;\n            for (i = 0; range = ranges[i++]; ) {\n                positions.push(\n                    new DomPosition(range.startContainer, range.startOffset),\n                    new DomPosition(range.endContainer, range.endOffset)\n                );\n            }\n            return positions;\n        }\n\n        function updateRangesFromBoundaries(ranges, positions) {\n            for (var i = 0, range, start, end, len = ranges.length; i < len; ++i) {\n                range = ranges[i];\n                start = positions[i * 2];\n                end = positions[i * 2 + 1];\n                range.setStartAndEnd(start.node, start.offset, end.node, end.offset);\n            }\n        }\n\n        function isSplitPoint(node, offset) {\n            if (dom.isCharacterDataNode(node)) {\n                if (offset == 0) {\n                    return !!node.previousSibling;\n                } else if (offset == node.length) {\n                    return !!node.nextSibling;\n                } else {\n                    return true;\n                }\n            }\n\n            return offset > 0 && offset < node.childNodes.length;\n        }\n\n        function splitNodeAt(node, descendantNode, descendantOffset, positionsToPreserve) {\n            var newNode, parentNode;\n            var splitAtStart = (descendantOffset == 0);\n\n            if (dom.isAncestorOf(descendantNode, node)) {\n                return node;\n            }\n\n            if (dom.isCharacterDataNode(descendantNode)) {\n                var descendantIndex = dom.getNodeIndex(descendantNode);\n                if (descendantOffset == 0) {\n                    descendantOffset = descendantIndex;\n                } else if (descendantOffset == descendantNode.length) {\n                    descendantOffset = descendantIndex + 1;\n                } else {\n                    throw module.createError(\"splitNodeAt() should not be called with offset in the middle of a data node (\" +\n                        descendantOffset + \" in \" + descendantNode.data);\n                }\n                descendantNode = descendantNode.parentNode;\n            }\n\n            if (isSplitPoint(descendantNode, descendantOffset)) {\n                // descendantNode is now guaranteed not to be a text or other character node\n                newNode = descendantNode.cloneNode(false);\n                parentNode = descendantNode.parentNode;\n                if (newNode.id) {\n                    newNode.removeAttribute(\"id\");\n                }\n                var child, newChildIndex = 0;\n\n                while ( (child = descendantNode.childNodes[descendantOffset]) ) {\n                    movePreservingPositions(child, newNode, newChildIndex++, positionsToPreserve);\n                }\n                movePreservingPositions(newNode, parentNode, dom.getNodeIndex(descendantNode) + 1, positionsToPreserve);\n                return (descendantNode == node) ? newNode : splitNodeAt(node, parentNode, dom.getNodeIndex(newNode), positionsToPreserve);\n            } else if (node != descendantNode) {\n                newNode = descendantNode.parentNode;\n\n                // Work out a new split point in the parent node\n                var newNodeIndex = dom.getNodeIndex(descendantNode);\n\n                if (!splitAtStart) {\n                    newNodeIndex++;\n                }\n                return splitNodeAt(node, newNode, newNodeIndex, positionsToPreserve);\n            }\n            return node;\n        }\n\n        function areElementsMergeable(el1, el2) {\n            return el1.namespaceURI == el2.namespaceURI &&\n                el1.tagName.toLowerCase() == el2.tagName.toLowerCase() &&\n                haveSameClasses(el1, el2) &&\n                elementsHaveSameNonClassAttributes(el1, el2) &&\n                getComputedStyleProperty(el1, \"display\") == \"inline\" &&\n                getComputedStyleProperty(el2, \"display\") == \"inline\";\n        }\n\n        function createAdjacentMergeableTextNodeGetter(forward) {\n            var siblingPropName = forward ? \"nextSibling\" : \"previousSibling\";\n\n            return function(textNode, checkParentElement) {\n                var el = textNode.parentNode;\n                var adjacentNode = textNode[siblingPropName];\n                if (adjacentNode) {\n                    // Can merge if the node's previous/next sibling is a text node\n                    if (adjacentNode && adjacentNode.nodeType == 3) {\n                        return adjacentNode;\n                    }\n                } else if (checkParentElement) {\n                    // Compare text node parent element with its sibling\n                    adjacentNode = el[siblingPropName];\n                    if (adjacentNode && adjacentNode.nodeType == 1 && areElementsMergeable(el, adjacentNode)) {\n                        var adjacentNodeChild = adjacentNode[forward ? \"firstChild\" : \"lastChild\"];\n                        if (adjacentNodeChild && adjacentNodeChild.nodeType == 3) {\n                            return adjacentNodeChild;\n                        }\n                    }\n                }\n                return null;\n            };\n        }\n\n        var getPreviousMergeableTextNode = createAdjacentMergeableTextNodeGetter(false),\n            getNextMergeableTextNode = createAdjacentMergeableTextNodeGetter(true);\n\n    \n        function Merge(firstNode) {\n            this.isElementMerge = (firstNode.nodeType == 1);\n            this.textNodes = [];\n            var firstTextNode = this.isElementMerge ? firstNode.lastChild : firstNode;\n            if (firstTextNode) {\n                this.textNodes[0] = firstTextNode;\n            }\n        }\n\n        Merge.prototype = {\n            doMerge: function(positionsToPreserve) {\n                var textNodes = this.textNodes;\n                var firstTextNode = textNodes[0];\n                if (textNodes.length > 1) {\n                    var firstTextNodeIndex = dom.getNodeIndex(firstTextNode);\n                    var textParts = [], combinedTextLength = 0, textNode, parent;\n                    for (var i = 0, len = textNodes.length, j, position; i < len; ++i) {\n                        textNode = textNodes[i];\n                        parent = textNode.parentNode;\n                        if (i > 0) {\n                            parent.removeChild(textNode);\n                            if (!parent.hasChildNodes()) {\n                                parent.parentNode.removeChild(parent);\n                            }\n                            if (positionsToPreserve) {\n                                for (j = 0; position = positionsToPreserve[j++]; ) {\n                                    // Handle case where position is inside the text node being merged into a preceding node\n                                    if (position.node == textNode) {\n                                        position.node = firstTextNode;\n                                        position.offset += combinedTextLength;\n                                    }\n                                    // Handle case where both text nodes precede the position within the same parent node\n                                    if (position.node == parent && position.offset > firstTextNodeIndex) {\n                                        --position.offset;\n                                        if (position.offset == firstTextNodeIndex + 1 && i < len - 1) {\n                                            position.node = firstTextNode;\n                                            position.offset = combinedTextLength;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        textParts[i] = textNode.data;\n                        combinedTextLength += textNode.data.length;\n                    }\n                    firstTextNode.data = textParts.join(\"\");\n                }\n                return firstTextNode.data;\n            },\n\n            getLength: function() {\n                var i = this.textNodes.length, len = 0;\n                while (i--) {\n                    len += this.textNodes[i].length;\n                }\n                return len;\n            },\n\n            toString: function() {\n                var textParts = [];\n                for (var i = 0, len = this.textNodes.length; i < len; ++i) {\n                    textParts[i] = \"'\" + this.textNodes[i].data + \"'\";\n                }\n                return \"[Merge(\" + textParts.join(\",\") + \")]\";\n            }\n        };\n\n        var optionProperties = [\"elementTagName\", \"ignoreWhiteSpace\", \"applyToEditableOnly\", \"useExistingElements\",\n            \"removeEmptyElements\", \"onElementCreate\"];\n\n        // TODO: Populate this with every attribute name that corresponds to a property with a different name. Really??\n        var attrNamesForProperties = {};\n\n        function ClassApplier(className, options, tagNames) {\n            var normalize, i, len, propName, applier = this;\n            applier.cssClass = applier.className = className; // cssClass property is for backward compatibility\n\n            var elementPropertiesFromOptions = null, elementAttributes = {};\n\n            // Initialize from options object\n            if (typeof options == \"object\" && options !== null) {\n                tagNames = options.tagNames;\n                elementPropertiesFromOptions = options.elementProperties;\n                elementAttributes = options.elementAttributes;\n\n                for (i = 0; propName = optionProperties[i++]; ) {\n                    if (options.hasOwnProperty(propName)) {\n                        applier[propName] = options[propName];\n                    }\n                }\n                normalize = options.normalize;\n            } else {\n                normalize = options;\n            }\n\n            // Backward compatibility: the second parameter can also be a Boolean indicating to normalize after unapplying\n            applier.normalize = (typeof normalize == \"undefined\") ? true : normalize;\n\n            // Initialize element properties and attribute exceptions\n            applier.attrExceptions = [];\n            var el = document.createElement(applier.elementTagName);\n            applier.elementProperties = applier.copyPropertiesToElement(elementPropertiesFromOptions, el, true);\n            each(elementAttributes, function(attrName) {\n                applier.attrExceptions.push(attrName);\n            });\n            applier.elementAttributes = elementAttributes;\n\n            applier.elementSortedClassName = applier.elementProperties.hasOwnProperty(\"className\") ?\n                applier.elementProperties.className : className;\n\n            // Initialize tag names\n            applier.applyToAnyTagName = false;\n            var type = typeof tagNames;\n            if (type == \"string\") {\n                if (tagNames == \"*\") {\n                    applier.applyToAnyTagName = true;\n                } else {\n                    applier.tagNames = trim(tagNames.toLowerCase()).split(/\\s*,\\s*/);\n                }\n            } else if (type == \"object\" && typeof tagNames.length == \"number\") {\n                applier.tagNames = [];\n                for (i = 0, len = tagNames.length; i < len; ++i) {\n                    if (tagNames[i] == \"*\") {\n                        applier.applyToAnyTagName = true;\n                    } else {\n                        applier.tagNames.push(tagNames[i].toLowerCase());\n                    }\n                }\n            } else {\n                applier.tagNames = [applier.elementTagName];\n            }\n        }\n\n        ClassApplier.prototype = {\n            elementTagName: defaultTagName,\n            elementProperties: {},\n            elementAttributes: {},\n            ignoreWhiteSpace: true,\n            applyToEditableOnly: false,\n            useExistingElements: true,\n            removeEmptyElements: true,\n            onElementCreate: null,\n\n            copyPropertiesToElement: function(props, el, createCopy) {\n                var s, elStyle, elProps = {}, elPropsStyle, propValue, elPropValue, attrName;\n\n                for (var p in props) {\n                    if (props.hasOwnProperty(p)) {\n                        propValue = props[p];\n                        elPropValue = el[p];\n\n                        // Special case for class. The copied properties object has the applier's CSS class as well as its\n                        // own to simplify checks when removing styling elements\n                        if (p == \"className\") {\n                            addClass(el, propValue);\n                            addClass(el, this.className);\n                            el[p] = sortClassName(el[p]);\n                            if (createCopy) {\n                                elProps[p] = el[p];\n                            }\n                        }\n\n                        // Special case for style\n                        else if (p == \"style\") {\n                            elStyle = elPropValue;\n                            if (createCopy) {\n                                elProps[p] = elPropsStyle = {};\n                            }\n                            for (s in props[p]) {\n                                elStyle[s] = propValue[s];\n                                if (createCopy) {\n                                    elPropsStyle[s] = elStyle[s];\n                                }\n                            }\n                            this.attrExceptions.push(p);\n                        } else {\n                            el[p] = propValue;\n                            // Copy the property back from the dummy element so that later comparisons to check whether\n                            // elements may be removed are checking against the right value. For example, the href property\n                            // of an element returns a fully qualified URL even if it was previously assigned a relative\n                            // URL.\n                            if (createCopy) {\n                                elProps[p] = el[p];\n\n                                // Not all properties map to identically-named attributes\n                                attrName = attrNamesForProperties.hasOwnProperty(p) ? attrNamesForProperties[p] : p;\n                                this.attrExceptions.push(attrName);\n                            }\n                        }\n                    }\n                }\n\n                return createCopy ? elProps : \"\";\n            },\n            \n            copyAttributesToElement: function(attrs, el) {\n                for (var attrName in attrs) {\n                    if (attrs.hasOwnProperty(attrName)) {\n                        el.setAttribute(attrName, attrs[attrName]);\n                    }\n                }\n            },\n\n            hasClass: function(node) {\n                return node.nodeType == 1 &&\n                    contains(this.tagNames, node.tagName.toLowerCase()) &&\n                    hasClass(node, this.className);\n            },\n\n            getSelfOrAncestorWithClass: function(node) {\n                while (node) {\n                    if (this.hasClass(node)) {\n                        return node;\n                    }\n                    node = node.parentNode;\n                }\n                return null;\n            },\n\n            isModifiable: function(node) {\n                return !this.applyToEditableOnly || isEditable(node);\n            },\n\n            // White space adjacent to an unwrappable node can be ignored for wrapping\n            isIgnorableWhiteSpaceNode: function(node) {\n                return this.ignoreWhiteSpace && node && node.nodeType == 3 && isUnrenderedWhiteSpaceNode(node);\n            },\n\n            // Normalizes nodes after applying a CSS class to a Range.\n            postApply: function(textNodes, range, positionsToPreserve, isUndo) {\n                var firstNode = textNodes[0], lastNode = textNodes[textNodes.length - 1];\n\n                var merges = [], currentMerge;\n\n                var rangeStartNode = firstNode, rangeEndNode = lastNode;\n                var rangeStartOffset = 0, rangeEndOffset = lastNode.length;\n\n                var textNode, precedingTextNode;\n\n                // Check for every required merge and create a Merge object for each\n                for (var i = 0, len = textNodes.length; i < len; ++i) {\n                    textNode = textNodes[i];\n                    precedingTextNode = getPreviousMergeableTextNode(textNode, !isUndo);\n                    if (precedingTextNode) {\n                        if (!currentMerge) {\n                            currentMerge = new Merge(precedingTextNode);\n                            merges.push(currentMerge);\n                        }\n                        currentMerge.textNodes.push(textNode);\n                        if (textNode === firstNode) {\n                            rangeStartNode = currentMerge.textNodes[0];\n                            rangeStartOffset = rangeStartNode.length;\n                        }\n                        if (textNode === lastNode) {\n                            rangeEndNode = currentMerge.textNodes[0];\n                            rangeEndOffset = currentMerge.getLength();\n                        }\n                    } else {\n                        currentMerge = null;\n                    }\n                }\n\n                // Test whether the first node after the range needs merging\n                var nextTextNode = getNextMergeableTextNode(lastNode, !isUndo);\n\n                if (nextTextNode) {\n                    if (!currentMerge) {\n                        currentMerge = new Merge(lastNode);\n                        merges.push(currentMerge);\n                    }\n                    currentMerge.textNodes.push(nextTextNode);\n                }\n\n                // Apply the merges\n                if (merges.length) {\n                    for (i = 0, len = merges.length; i < len; ++i) {\n                        merges[i].doMerge(positionsToPreserve);\n                    }\n\n                    // Set the range boundaries\n                    range.setStartAndEnd(rangeStartNode, rangeStartOffset, rangeEndNode, rangeEndOffset);\n                }\n            },\n\n            createContainer: function(doc) {\n                var el = doc.createElement(this.elementTagName);\n                this.copyPropertiesToElement(this.elementProperties, el, false);\n                this.copyAttributesToElement(this.elementAttributes, el);\n                addClass(el, this.className);\n                if (this.onElementCreate) {\n                    this.onElementCreate(el, this);\n                }\n                return el;\n            },\n\n            applyToTextNode: function(textNode, positionsToPreserve) {\n                var parent = textNode.parentNode;\n                if (parent.childNodes.length == 1 &&\n                        this.useExistingElements &&\n                        isHtmlNamespace(parent) &&\n                        contains(this.tagNames, parent.tagName.toLowerCase()) &&\n                        elementHasProperties(parent, this.elementProperties)) {\n\n                    addClass(parent, this.className);\n                } else {\n                    var el = this.createContainer(dom.getDocument(textNode));\n                    textNode.parentNode.insertBefore(el, textNode);\n                    el.appendChild(textNode);\n                }\n            },\n\n            isRemovable: function(el) {\n                return isHtmlNamespace(el) &&\n                    el.tagName.toLowerCase() == this.elementTagName &&\n                    getSortedClassName(el) == this.elementSortedClassName &&\n                    elementHasProperties(el, this.elementProperties) &&\n                    !elementHasNonClassAttributes(el, this.attrExceptions) &&\n                    this.isModifiable(el);\n            },\n\n            isEmptyContainer: function(el) {\n                var childNodeCount = el.childNodes.length;\n                return el.nodeType == 1 &&\n                    this.isRemovable(el) &&\n                    (childNodeCount == 0 || (childNodeCount == 1 && this.isEmptyContainer(el.firstChild)));\n            },\n            \n            removeEmptyContainers: function(range) {\n                var applier = this;\n                var nodesToRemove = range.getNodes([1], function(el) {\n                    return applier.isEmptyContainer(el);\n                });\n                \n                var rangesToPreserve = [range];\n                var positionsToPreserve = getRangeBoundaries(rangesToPreserve);\n                \n                for (var i = 0, node; node = nodesToRemove[i++]; ) {\n                    removePreservingPositions(node, positionsToPreserve);\n                }\n\n                // Update the range from the preserved boundary positions\n                updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);\n            },\n\n            undoToTextNode: function(textNode, range, ancestorWithClass, positionsToPreserve) {\n                if (!range.containsNode(ancestorWithClass)) {\n                    // Split out the portion of the ancestor from which we can remove the CSS class\n                    //var parent = ancestorWithClass.parentNode, index = dom.getNodeIndex(ancestorWithClass);\n                    var ancestorRange = range.cloneRange();\n                    ancestorRange.selectNode(ancestorWithClass);\n                    if (ancestorRange.isPointInRange(range.endContainer, range.endOffset)) {\n                        splitNodeAt(ancestorWithClass, range.endContainer, range.endOffset, positionsToPreserve);\n                        range.setEndAfter(ancestorWithClass);\n                    }\n                    if (ancestorRange.isPointInRange(range.startContainer, range.startOffset)) {\n                        ancestorWithClass = splitNodeAt(ancestorWithClass, range.startContainer, range.startOffset, positionsToPreserve);\n                    }\n                }\n                if (this.isRemovable(ancestorWithClass)) {\n                    replaceWithOwnChildrenPreservingPositions(ancestorWithClass, positionsToPreserve);\n                } else {\n                    removeClass(ancestorWithClass, this.className);\n                }\n            },\n\n            applyToRange: function(range, rangesToPreserve) {\n                rangesToPreserve = rangesToPreserve || [];\n\n                // Create an array of range boundaries to preserve\n                var positionsToPreserve = getRangeBoundaries(rangesToPreserve || []);\n                \n                range.splitBoundariesPreservingPositions(positionsToPreserve);\n\n                // Tidy up the DOM by removing empty containers \n                if (this.removeEmptyElements) {\n                    this.removeEmptyContainers(range);\n                }\n\n                var textNodes = getEffectiveTextNodes(range);\n\n                if (textNodes.length) {\n                    for (var i = 0, textNode; textNode = textNodes[i++]; ) {\n                        if (!this.isIgnorableWhiteSpaceNode(textNode) && !this.getSelfOrAncestorWithClass(textNode) &&\n                                this.isModifiable(textNode)) {\n                            this.applyToTextNode(textNode, positionsToPreserve);\n                        }\n                    }\n                    textNode = textNodes[textNodes.length - 1];\n                    range.setStartAndEnd(textNodes[0], 0, textNode, textNode.length);\n                    if (this.normalize) {\n                        this.postApply(textNodes, range, positionsToPreserve, false);\n                    }\n\n                    // Update the ranges from the preserved boundary positions\n                    updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);\n                }\n            },\n\n            applyToRanges: function(ranges) {\n\n                var i = ranges.length;\n                while (i--) {\n                    this.applyToRange(ranges[i], ranges);\n                }\n\n\n                return ranges;\n            },\n\n            applyToSelection: function(win) {\n                var sel = api.getSelection(win);\n                sel.setRanges( this.applyToRanges(sel.getAllRanges()) );\n            },\n\n            undoToRange: function(range, rangesToPreserve) {\n                // Create an array of range boundaries to preserve\n                rangesToPreserve = rangesToPreserve || [];\n                var positionsToPreserve = getRangeBoundaries(rangesToPreserve);\n\n\n                range.splitBoundariesPreservingPositions(positionsToPreserve);\n\n                // Tidy up the DOM by removing empty containers \n                if (this.removeEmptyElements) {\n                    this.removeEmptyContainers(range, positionsToPreserve);\n                }\n\n                var textNodes = getEffectiveTextNodes(range);\n                var textNode, ancestorWithClass;\n                var lastTextNode = textNodes[textNodes.length - 1];\n\n                if (textNodes.length) {\n                    for (var i = 0, len = textNodes.length; i < len; ++i) {\n                        textNode = textNodes[i];\n                        ancestorWithClass = this.getSelfOrAncestorWithClass(textNode);\n                        if (ancestorWithClass && this.isModifiable(textNode)) {\n                            this.undoToTextNode(textNode, range, ancestorWithClass, positionsToPreserve);\n                        }\n\n                        // Ensure the range is still valid\n                        range.setStartAndEnd(textNodes[0], 0, lastTextNode, lastTextNode.length);\n                    }\n\n\n                    if (this.normalize) {\n                        this.postApply(textNodes, range, positionsToPreserve, true);\n                    }\n\n                    // Update the ranges from the preserved boundary positions\n                    updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);\n                }\n            },\n\n            undoToRanges: function(ranges) {\n                // Get ranges returned in document order\n                var i = ranges.length;\n\n                while (i--) {\n                    this.undoToRange(ranges[i], ranges);\n                }\n\n                return ranges;\n            },\n\n            undoToSelection: function(win) {\n                var sel = api.getSelection(win);\n                var ranges = api.getSelection(win).getAllRanges();\n                this.undoToRanges(ranges);\n                sel.setRanges(ranges);\n            },\n\n    /*\n            getTextSelectedByRange: function(textNode, range) {\n                var textRange = range.cloneRange();\n                textRange.selectNodeContents(textNode);\n\n                var intersectionRange = textRange.intersection(range);\n                var text = intersectionRange ? intersectionRange.toString() : \"\";\n                textRange.detach();\n\n                return text;\n            },\n    */\n\n            isAppliedToRange: function(range) {\n                if (range.collapsed || range.toString() == \"\") {\n                    return !!this.getSelfOrAncestorWithClass(range.commonAncestorContainer);\n                } else {\n                    var textNodes = range.getNodes( [3] );\n                    if (textNodes.length)\n                    for (var i = 0, textNode; textNode = textNodes[i++]; ) {\n                        if (!this.isIgnorableWhiteSpaceNode(textNode) && rangeSelectsAnyText(range, textNode) &&\n                                this.isModifiable(textNode) && !this.getSelfOrAncestorWithClass(textNode)) {\n                            return false;\n                        }\n                    }\n                    return true;\n                }\n            },\n\n            isAppliedToRanges: function(ranges) {\n                var i = ranges.length;\n                if (i == 0) {\n                    return false;\n                }\n                while (i--) {\n                    if (!this.isAppliedToRange(ranges[i])) {\n                        return false;\n                    }\n                }\n                return true;\n            },\n\n            isAppliedToSelection: function(win) {\n                var sel = api.getSelection(win);\n                return this.isAppliedToRanges(sel.getAllRanges());\n            },\n\n            toggleRange: function(range) {\n                if (this.isAppliedToRange(range)) {\n                    this.undoToRange(range);\n                } else {\n                    this.applyToRange(range);\n                }\n            },\n\n    /*\n            toggleRanges: function(ranges) {\n                if (this.isAppliedToRanges(ranges)) {\n                    this.undoToRanges(ranges);\n                } else {\n                    this.applyToRanges(ranges);\n                }\n            },\n    */\n\n            toggleSelection: function(win) {\n                if (this.isAppliedToSelection(win)) {\n                    this.undoToSelection(win);\n                } else {\n                    this.applyToSelection(win);\n                }\n            },\n            \n            getElementsWithClassIntersectingRange: function(range) {\n                var elements = [];\n                var applier = this;\n                range.getNodes([3], function(textNode) {\n                    var el = applier.getSelfOrAncestorWithClass(textNode);\n                    if (el && !contains(elements, el)) {\n                        elements.push(el);\n                    }\n                });\n                return elements;\n            },\n\n    /*\n            getElementsWithClassIntersectingSelection: function(win) {\n                var sel = api.getSelection(win);\n                var elements = [];\n                var applier = this;\n                sel.eachRange(function(range) {\n                    var rangeElements = applier.getElementsWithClassIntersectingRange(range);\n                    for (var i = 0, el; el = rangeElements[i++]; ) {\n                        if (!contains(elements, el)) {\n                            elements.push(el);\n                        }\n                    }\n                });\n                return elements;\n            },\n    */\n\n            detach: function() {}\n        };\n\n        function createClassApplier(className, options, tagNames) {\n            return new ClassApplier(className, options, tagNames);\n        }\n\n        ClassApplier.util = {\n            hasClass: hasClass,\n            addClass: addClass,\n            removeClass: removeClass,\n            hasSameClasses: haveSameClasses,\n            replaceWithOwnChildren: replaceWithOwnChildrenPreservingPositions,\n            elementsHaveSameNonClassAttributes: elementsHaveSameNonClassAttributes,\n            elementHasNonClassAttributes: elementHasNonClassAttributes,\n            splitNodeAt: splitNodeAt,\n            isEditableElement: isEditableElement,\n            isEditingHost: isEditingHost,\n            isEditable: isEditable\n        };\n\n        api.CssClassApplier = api.ClassApplier = ClassApplier;\n        api.createCssClassApplier = api.createClassApplier = createClassApplier;\n    });\n    \n}, this);"
  },
  {
    "path": "public/assets/js/source/util--rangy-core.js",
    "content": "/**\n * Rangy, a cross-browser JavaScript range and selection library\n * http://code.google.com/p/rangy/\n *\n * Copyright 2014, Tim Down\n * Licensed under the MIT license.\n * Version: 1.3.0-alpha.20140827\n * Build date: 27 August 2014\n */\n\n(function(factory, root) {\n    if (typeof define == \"function\" && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(factory);\n    } else if (typeof module != \"undefined\" && typeof exports == \"object\") {\n        // Node/CommonJS style\n        module.exports = factory();\n    } else {\n        // No AMD or CommonJS support so we place Rangy in (probably) the global variable\n        root.rangy = factory();\n    }\n})(function() {\n\n    var OBJECT = \"object\", FUNCTION = \"function\", UNDEFINED = \"undefined\";\n\n    // Minimal set of properties required for DOM Level 2 Range compliance. Comparison constants such as START_TO_START\n    // are omitted because ranges in KHTML do not have them but otherwise work perfectly well. See issue 113.\n    var domRangeProperties = [\"startContainer\", \"startOffset\", \"endContainer\", \"endOffset\", \"collapsed\",\n        \"commonAncestorContainer\"];\n\n    // Minimal set of methods required for DOM Level 2 Range compliance\n    var domRangeMethods = [\"setStart\", \"setStartBefore\", \"setStartAfter\", \"setEnd\", \"setEndBefore\",\n        \"setEndAfter\", \"collapse\", \"selectNode\", \"selectNodeContents\", \"compareBoundaryPoints\", \"deleteContents\",\n        \"extractContents\", \"cloneContents\", \"insertNode\", \"surroundContents\", \"cloneRange\", \"toString\", \"detach\"];\n\n    var textRangeProperties = [\"boundingHeight\", \"boundingLeft\", \"boundingTop\", \"boundingWidth\", \"htmlText\", \"text\"];\n\n    // Subset of TextRange's full set of methods that we're interested in\n    var textRangeMethods = [\"collapse\", \"compareEndPoints\", \"duplicate\", \"moveToElementText\", \"parentElement\", \"select\",\n        \"setEndPoint\", \"getBoundingClientRect\"];\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Trio of functions taken from Peter Michaux's article:\n    // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting\n    function isHostMethod(o, p) {\n        var t = typeof o[p];\n        return t == FUNCTION || (!!(t == OBJECT && o[p])) || t == \"unknown\";\n    }\n\n    function isHostObject(o, p) {\n        return !!(typeof o[p] == OBJECT && o[p]);\n    }\n\n    function isHostProperty(o, p) {\n        return typeof o[p] != UNDEFINED;\n    }\n\n    // Creates a convenience function to save verbose repeated calls to tests functions\n    function createMultiplePropertyTest(testFunc) {\n        return function(o, props) {\n            var i = props.length;\n            while (i--) {\n                if (!testFunc(o, props[i])) {\n                    return false;\n                }\n            }\n            return true;\n        };\n    }\n\n    // Next trio of functions are a convenience to save verbose repeated calls to previous two functions\n    var areHostMethods = createMultiplePropertyTest(isHostMethod);\n    var areHostObjects = createMultiplePropertyTest(isHostObject);\n    var areHostProperties = createMultiplePropertyTest(isHostProperty);\n\n    function isTextRange(range) {\n        return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties);\n    }\n\n    function getBody(doc) {\n        return isHostObject(doc, \"body\") ? doc.body : doc.getElementsByTagName(\"body\")[0];\n    }\n\n    var modules = {};\n\n    var isBrowser = (typeof window != UNDEFINED && typeof document != UNDEFINED);\n\n    var util = {\n        isHostMethod: isHostMethod,\n        isHostObject: isHostObject,\n        isHostProperty: isHostProperty,\n        areHostMethods: areHostMethods,\n        areHostObjects: areHostObjects,\n        areHostProperties: areHostProperties,\n        isTextRange: isTextRange,\n        getBody: getBody\n    };\n\n    var api = {\n        version: \"1.3.0-alpha.20140827\",\n        initialized: false,\n        isBrowser: isBrowser,\n        supported: true,\n        util: util,\n        features: {},\n        modules: modules,\n        config: {\n            alertOnFail: true,\n            alertOnWarn: false,\n            preferTextRange: false,\n            autoInitialize: (typeof rangyAutoInitialize == UNDEFINED) ? true : rangyAutoInitialize\n        }\n    };\n\n    function consoleLog(msg) {\n        if (typeof console != UNDEFINED && isHostMethod(console, \"log\")) {\n            console.log(msg);\n        }\n    }\n\n    function alertOrLog(msg, shouldAlert) {\n        if (isBrowser && shouldAlert) {\n            alert(msg);\n        } else  {\n            consoleLog(msg);\n        }\n    }\n\n    function fail(reason) {\n        api.initialized = true;\n        api.supported = false;\n        alertOrLog(\"Rangy is not supported in this environment. Reason: \" + reason, api.config.alertOnFail);\n    }\n\n    api.fail = fail;\n\n    function warn(msg) {\n        alertOrLog(\"Rangy warning: \" + msg, api.config.alertOnWarn);\n    }\n\n    api.warn = warn;\n\n    // Add utility extend() method\n    var extend;\n    if ({}.hasOwnProperty) {\n        util.extend = extend = function(obj, props, deep) {\n            var o, p;\n            for (var i in props) {\n                if (props.hasOwnProperty(i)) {\n                    o = obj[i];\n                    p = props[i];\n                    if (deep && o !== null && typeof o == \"object\" && p !== null && typeof p == \"object\") {\n                        extend(o, p, true);\n                    }\n                    obj[i] = p;\n                }\n            }\n            // Special case for toString, which does not show up in for...in loops in IE <= 8\n            if (props.hasOwnProperty(\"toString\")) {\n                obj.toString = props.toString;\n            }\n            return obj;\n        };\n\n        util.createOptions = function(optionsParam, defaults) {\n            var options = {};\n            extend(options, defaults);\n            if (optionsParam) {\n                extend(options, optionsParam, true);\n            }\n            return options;\n        };\n    } else {\n        fail(\"hasOwnProperty not supported\");\n    }\n    \n    // Test whether we're in a browser and bail out if not\n    if (!isBrowser) {\n        fail(\"Rangy can only run in a browser\");\n    }\n\n    // Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not\n    (function() {\n        var toArray;\n\n        if (isBrowser) {\n            var el = document.createElement(\"div\");\n            el.appendChild(document.createElement(\"span\"));\n            var slice = [].slice;\n            try {\n                if (slice.call(el.childNodes, 0)[0].nodeType == 1) {\n                    toArray = function(arrayLike) {\n                        return slice.call(arrayLike, 0);\n                    };\n                }\n            } catch (e) {}\n        }\n\n        if (!toArray) {\n            toArray = function(arrayLike) {\n                var arr = [];\n                for (var i = 0, len = arrayLike.length; i < len; ++i) {\n                    arr[i] = arrayLike[i];\n                }\n                return arr;\n            };\n        }\n\n        util.toArray = toArray;\n    })();\n\n    // Very simple event handler wrapper function that doesn't attempt to solve issues such as \"this\" handling or\n    // normalization of event properties\n    var addListener;\n    if (isBrowser) {\n        if (isHostMethod(document, \"addEventListener\")) {\n            addListener = function(obj, eventType, listener) {\n                obj.addEventListener(eventType, listener, false);\n            };\n        } else if (isHostMethod(document, \"attachEvent\")) {\n            addListener = function(obj, eventType, listener) {\n                obj.attachEvent(\"on\" + eventType, listener);\n            };\n        } else {\n            fail(\"Document does not have required addEventListener or attachEvent method\");\n        }\n\n        util.addListener = addListener;\n    }\n\n    var initListeners = [];\n\n    function getErrorDesc(ex) {\n        return ex.message || ex.description || String(ex);\n    }\n\n    // Initialization\n    function init() {\n        if (!isBrowser || api.initialized) {\n            return;\n        }\n        var testRange;\n        var implementsDomRange = false, implementsTextRange = false;\n\n        // First, perform basic feature tests\n\n        if (isHostMethod(document, \"createRange\")) {\n            testRange = document.createRange();\n            if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) {\n                implementsDomRange = true;\n            }\n        }\n\n        var body = getBody(document);\n        if (!body || body.nodeName.toLowerCase() != \"body\") {\n            fail(\"No body element found\");\n            return;\n        }\n\n        if (body && isHostMethod(body, \"createTextRange\")) {\n            testRange = body.createTextRange();\n            if (isTextRange(testRange)) {\n                implementsTextRange = true;\n            }\n        }\n\n        if (!implementsDomRange && !implementsTextRange) {\n            fail(\"Neither Range nor TextRange are available\");\n            return;\n        }\n\n        api.initialized = true;\n        api.features = {\n            implementsDomRange: implementsDomRange,\n            implementsTextRange: implementsTextRange\n        };\n\n        // Initialize modules\n        var module, errorMessage;\n        for (var moduleName in modules) {\n            if ( (module = modules[moduleName]) instanceof Module ) {\n                module.init(module, api);\n            }\n        }\n\n        // Call init listeners\n        for (var i = 0, len = initListeners.length; i < len; ++i) {\n            try {\n                initListeners[i](api);\n            } catch (ex) {\n                errorMessage = \"Rangy init listener threw an exception. Continuing. Detail: \" + getErrorDesc(ex);\n                consoleLog(errorMessage);\n            }\n        }\n    }\n\n    // Allow external scripts to initialize this library in case it's loaded after the document has loaded\n    api.init = init;\n\n    // Execute listener immediately if already initialized\n    api.addInitListener = function(listener) {\n        if (api.initialized) {\n            listener(api);\n        } else {\n            initListeners.push(listener);\n        }\n    };\n\n    var shimListeners = [];\n\n    api.addShimListener = function(listener) {\n        shimListeners.push(listener);\n    };\n\n    function shim(win) {\n        win = win || window;\n        init();\n\n        // Notify listeners\n        for (var i = 0, len = shimListeners.length; i < len; ++i) {\n            shimListeners[i](win);\n        }\n    }\n\n    if (isBrowser) {\n        api.shim = api.createMissingNativeApi = shim;\n    }\n\n    function Module(name, dependencies, initializer) {\n        this.name = name;\n        this.dependencies = dependencies;\n        this.initialized = false;\n        this.supported = false;\n        this.initializer = initializer;\n    }\n\n    Module.prototype = {\n        init: function() {\n            var requiredModuleNames = this.dependencies || [];\n            for (var i = 0, len = requiredModuleNames.length, requiredModule, moduleName; i < len; ++i) {\n                moduleName = requiredModuleNames[i];\n\n                requiredModule = modules[moduleName];\n                if (!requiredModule || !(requiredModule instanceof Module)) {\n                    throw new Error(\"required module '\" + moduleName + \"' not found\");\n                }\n\n                requiredModule.init();\n\n                if (!requiredModule.supported) {\n                    throw new Error(\"required module '\" + moduleName + \"' not supported\");\n                }\n            }\n            \n            // Now run initializer\n            this.initializer(this);\n        },\n        \n        fail: function(reason) {\n            this.initialized = true;\n            this.supported = false;\n            throw new Error(\"Module '\" + this.name + \"' failed to load: \" + reason);\n        },\n\n        warn: function(msg) {\n            api.warn(\"Module \" + this.name + \": \" + msg);\n        },\n\n        deprecationNotice: function(deprecated, replacement) {\n            api.warn(\"DEPRECATED: \" + deprecated + \" in module \" + this.name + \"is deprecated. Please use \" +\n                replacement + \" instead\");\n        },\n\n        createError: function(msg) {\n            return new Error(\"Error in Rangy \" + this.name + \" module: \" + msg);\n        }\n    };\n    \n    function createModule(name, dependencies, initFunc) {\n        var newModule = new Module(name, dependencies, function(module) {\n            if (!module.initialized) {\n                module.initialized = true;\n                try {\n                    initFunc(api, module);\n                    module.supported = true;\n                } catch (ex) {\n                    var errorMessage = \"Module '\" + name + \"' failed to load: \" + getErrorDesc(ex);\n                    consoleLog(errorMessage);\n                }\n            }\n        });\n        modules[name] = newModule;\n        return newModule;\n    }\n\n    api.createModule = function(name) {\n        // Allow 2 or 3 arguments (second argument is an optional array of dependencies)\n        var initFunc, dependencies;\n        if (arguments.length == 2) {\n            initFunc = arguments[1];\n            dependencies = [];\n        } else {\n            initFunc = arguments[2];\n            dependencies = arguments[1];\n        }\n\n        var module = createModule(name, dependencies, initFunc);\n\n        // Initialize the module immediately if the core is already initialized\n        if (api.initialized && api.supported) {\n            module.init();\n        }\n    };\n\n    api.createCoreModule = function(name, dependencies, initFunc) {\n        createModule(name, dependencies, initFunc);\n    };\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately\n\n    function RangePrototype() {}\n    api.RangePrototype = RangePrototype;\n    api.rangePrototype = new RangePrototype();\n\n    function SelectionPrototype() {}\n    api.selectionPrototype = new SelectionPrototype();\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // DOM utility methods used by Rangy\n    api.createCoreModule(\"DomUtil\", [], function(api, module) {\n        var UNDEF = \"undefined\";\n        var util = api.util;\n\n        // Perform feature tests\n        if (!util.areHostMethods(document, [\"createDocumentFragment\", \"createElement\", \"createTextNode\"])) {\n            module.fail(\"document missing a Node creation method\");\n        }\n\n        if (!util.isHostMethod(document, \"getElementsByTagName\")) {\n            module.fail(\"document missing getElementsByTagName method\");\n        }\n\n        var el = document.createElement(\"div\");\n        if (!util.areHostMethods(el, [\"insertBefore\", \"appendChild\", \"cloneNode\"] ||\n                !util.areHostObjects(el, [\"previousSibling\", \"nextSibling\", \"childNodes\", \"parentNode\"]))) {\n            module.fail(\"Incomplete Element implementation\");\n        }\n\n        // innerHTML is required for Range's createContextualFragment method\n        if (!util.isHostProperty(el, \"innerHTML\")) {\n            module.fail(\"Element is missing innerHTML property\");\n        }\n\n        var textNode = document.createTextNode(\"test\");\n        if (!util.areHostMethods(textNode, [\"splitText\", \"deleteData\", \"insertData\", \"appendData\", \"cloneNode\"] ||\n                !util.areHostObjects(el, [\"previousSibling\", \"nextSibling\", \"childNodes\", \"parentNode\"]) ||\n                !util.areHostProperties(textNode, [\"data\"]))) {\n            module.fail(\"Incomplete Text Node implementation\");\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been\n        // able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that\n        // contains just the document as a single element and the value searched for is the document.\n        var arrayContains = /*Array.prototype.indexOf ?\n            function(arr, val) {\n                return arr.indexOf(val) > -1;\n            }:*/\n\n            function(arr, val) {\n                var i = arr.length;\n                while (i--) {\n                    if (arr[i] === val) {\n                        return true;\n                    }\n                }\n                return false;\n            };\n\n        // Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI\n        function isHtmlNamespace(node) {\n            var ns;\n            return typeof node.namespaceURI == UNDEF || ((ns = node.namespaceURI) === null || ns == \"http://www.w3.org/1999/xhtml\");\n        }\n\n        function parentElement(node) {\n            var parent = node.parentNode;\n            return (parent.nodeType == 1) ? parent : null;\n        }\n\n        function getNodeIndex(node) {\n            var i = 0;\n            while( (node = node.previousSibling) ) {\n                ++i;\n            }\n            return i;\n        }\n\n        function getNodeLength(node) {\n            switch (node.nodeType) {\n                case 7:\n                case 10:\n                    return 0;\n                case 3:\n                case 8:\n                    return node.length;\n                default:\n                    return node.childNodes.length;\n            }\n        }\n\n        function getCommonAncestor(node1, node2) {\n            var ancestors = [], n;\n            for (n = node1; n; n = n.parentNode) {\n                ancestors.push(n);\n            }\n\n            for (n = node2; n; n = n.parentNode) {\n                if (arrayContains(ancestors, n)) {\n                    return n;\n                }\n            }\n\n            return null;\n        }\n\n        function isAncestorOf(ancestor, descendant, selfIsAncestor) {\n            var n = selfIsAncestor ? descendant : descendant.parentNode;\n            while (n) {\n                if (n === ancestor) {\n                    return true;\n                } else {\n                    n = n.parentNode;\n                }\n            }\n            return false;\n        }\n\n        function isOrIsAncestorOf(ancestor, descendant) {\n            return isAncestorOf(ancestor, descendant, true);\n        }\n\n        function getClosestAncestorIn(node, ancestor, selfIsAncestor) {\n            var p, n = selfIsAncestor ? node : node.parentNode;\n            while (n) {\n                p = n.parentNode;\n                if (p === ancestor) {\n                    return n;\n                }\n                n = p;\n            }\n            return null;\n        }\n\n        function isCharacterDataNode(node) {\n            var t = node.nodeType;\n            return t == 3 || t == 4 || t == 8 ; // Text, CDataSection or Comment\n        }\n\n        function isTextOrCommentNode(node) {\n            if (!node) {\n                return false;\n            }\n            var t = node.nodeType;\n            return t == 3 || t == 8 ; // Text or Comment\n        }\n\n        function insertAfter(node, precedingNode) {\n            var nextNode = precedingNode.nextSibling, parent = precedingNode.parentNode;\n            if (nextNode) {\n                parent.insertBefore(node, nextNode);\n            } else {\n                parent.appendChild(node);\n            }\n            return node;\n        }\n\n        // Note that we cannot use splitText() because it is bugridden in IE 9.\n        function splitDataNode(node, index, positionsToPreserve) {\n            var newNode = node.cloneNode(false);\n            newNode.deleteData(0, index);\n            node.deleteData(index, node.length - index);\n            insertAfter(newNode, node);\n\n            // Preserve positions\n            if (positionsToPreserve) {\n                for (var i = 0, position; position = positionsToPreserve[i++]; ) {\n                    // Handle case where position was inside the portion of node after the split point\n                    if (position.node == node && position.offset > index) {\n                        position.node = newNode;\n                        position.offset -= index;\n                    }\n                    // Handle the case where the position is a node offset within node's parent\n                    else if (position.node == node.parentNode && position.offset > getNodeIndex(node)) {\n                        ++position.offset;\n                    }\n                }\n            }\n            return newNode;\n        }\n\n        function getDocument(node) {\n            if (node.nodeType == 9) {\n                return node;\n            } else if (typeof node.ownerDocument != UNDEF) {\n                return node.ownerDocument;\n            } else if (typeof node.document != UNDEF) {\n                return node.document;\n            } else if (node.parentNode) {\n                return getDocument(node.parentNode);\n            } else {\n                throw module.createError(\"getDocument: no document found for node\");\n            }\n        }\n\n        function getWindow(node) {\n            var doc = getDocument(node);\n            if (typeof doc.defaultView != UNDEF) {\n                return doc.defaultView;\n            } else if (typeof doc.parentWindow != UNDEF) {\n                return doc.parentWindow;\n            } else {\n                throw module.createError(\"Cannot get a window object for node\");\n            }\n        }\n\n        function getIframeDocument(iframeEl) {\n            if (typeof iframeEl.contentDocument != UNDEF) {\n                return iframeEl.contentDocument;\n            } else if (typeof iframeEl.contentWindow != UNDEF) {\n                return iframeEl.contentWindow.document;\n            } else {\n                throw module.createError(\"getIframeDocument: No Document object found for iframe element\");\n            }\n        }\n\n        function getIframeWindow(iframeEl) {\n            if (typeof iframeEl.contentWindow != UNDEF) {\n                return iframeEl.contentWindow;\n            } else if (typeof iframeEl.contentDocument != UNDEF) {\n                return iframeEl.contentDocument.defaultView;\n            } else {\n                throw module.createError(\"getIframeWindow: No Window object found for iframe element\");\n            }\n        }\n\n        // This looks bad. Is it worth it?\n        function isWindow(obj) {\n            return obj && util.isHostMethod(obj, \"setTimeout\") && util.isHostObject(obj, \"document\");\n        }\n\n        function getContentDocument(obj, module, methodName) {\n            var doc;\n\n            if (!obj) {\n                doc = document;\n            }\n\n            // Test if a DOM node has been passed and obtain a document object for it if so\n            else if (util.isHostProperty(obj, \"nodeType\")) {\n                doc = (obj.nodeType == 1 && obj.tagName.toLowerCase() == \"iframe\") ?\n                    getIframeDocument(obj) : getDocument(obj);\n            }\n\n            // Test if the doc parameter appears to be a Window object\n            else if (isWindow(obj)) {\n                doc = obj.document;\n            }\n\n            if (!doc) {\n                throw module.createError(methodName + \"(): Parameter must be a Window object or DOM node\");\n            }\n\n            return doc;\n        }\n\n        function getRootContainer(node) {\n            var parent;\n            while ( (parent = node.parentNode) ) {\n                node = parent;\n            }\n            return node;\n        }\n\n        function comparePoints(nodeA, offsetA, nodeB, offsetB) {\n            // See http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing\n            var nodeC, root, childA, childB, n;\n            if (nodeA == nodeB) {\n                // Case 1: nodes are the same\n                return offsetA === offsetB ? 0 : (offsetA < offsetB) ? -1 : 1;\n            } else if ( (nodeC = getClosestAncestorIn(nodeB, nodeA, true)) ) {\n                // Case 2: node C (container B or an ancestor) is a child node of A\n                return offsetA <= getNodeIndex(nodeC) ? -1 : 1;\n            } else if ( (nodeC = getClosestAncestorIn(nodeA, nodeB, true)) ) {\n                // Case 3: node C (container A or an ancestor) is a child node of B\n                return getNodeIndex(nodeC) < offsetB  ? -1 : 1;\n            } else {\n                root = getCommonAncestor(nodeA, nodeB);\n                if (!root) {\n                    throw new Error(\"comparePoints error: nodes have no common ancestor\");\n                }\n\n                // Case 4: containers are siblings or descendants of siblings\n                childA = (nodeA === root) ? root : getClosestAncestorIn(nodeA, root, true);\n                childB = (nodeB === root) ? root : getClosestAncestorIn(nodeB, root, true);\n\n                if (childA === childB) {\n                    // This shouldn't be possible\n                    throw module.createError(\"comparePoints got to case 4 and childA and childB are the same!\");\n                } else {\n                    n = root.firstChild;\n                    while (n) {\n                        if (n === childA) {\n                            return -1;\n                        } else if (n === childB) {\n                            return 1;\n                        }\n                        n = n.nextSibling;\n                    }\n                }\n            }\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Test for IE's crash (IE 6/7) or exception (IE >= 8) when a reference to garbage-collected text node is queried\n        var crashyTextNodes = false;\n\n        function isBrokenNode(node) {\n            var n;\n            try {\n                n = node.parentNode;\n                return false;\n            } catch (e) {\n                return true;\n            }\n        }\n\n        (function() {\n            var el = document.createElement(\"b\");\n            el.innerHTML = \"1\";\n            var textNode = el.firstChild;\n            el.innerHTML = \"<br>\";\n            crashyTextNodes = isBrokenNode(textNode);\n\n            api.features.crashyTextNodes = crashyTextNodes;\n        })();\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        function inspectNode(node) {\n            if (!node) {\n                return \"[No node]\";\n            }\n            if (crashyTextNodes && isBrokenNode(node)) {\n                return \"[Broken node]\";\n            }\n            if (isCharacterDataNode(node)) {\n                return '\"' + node.data + '\"';\n            }\n            if (node.nodeType == 1) {\n                var idAttr = node.id ? ' id=\"' + node.id + '\"' : \"\";\n                return \"<\" + node.nodeName + idAttr + \">[index:\" + getNodeIndex(node) + \",length:\" + node.childNodes.length + \"][\" + (node.innerHTML || \"[innerHTML not supported]\").slice(0, 25) + \"]\";\n            }\n            return node.nodeName;\n        }\n\n        function fragmentFromNodeChildren(node) {\n            var fragment = getDocument(node).createDocumentFragment(), child;\n            while ( (child = node.firstChild) ) {\n                fragment.appendChild(child);\n            }\n            return fragment;\n        }\n\n        var getComputedStyleProperty;\n        if (typeof window.getComputedStyle != UNDEF) {\n            getComputedStyleProperty = function(el, propName) {\n                return getWindow(el).getComputedStyle(el, null)[propName];\n            };\n        } else if (typeof document.documentElement.currentStyle != UNDEF) {\n            getComputedStyleProperty = function(el, propName) {\n                return el.currentStyle[propName];\n            };\n        } else {\n            module.fail(\"No means of obtaining computed style properties found\");\n        }\n\n        function NodeIterator(root) {\n            this.root = root;\n            this._next = root;\n        }\n\n        NodeIterator.prototype = {\n            _current: null,\n\n            hasNext: function() {\n                return !!this._next;\n            },\n\n            next: function() {\n                var n = this._current = this._next;\n                var child, next;\n                if (this._current) {\n                    child = n.firstChild;\n                    if (child) {\n                        this._next = child;\n                    } else {\n                        next = null;\n                        while ((n !== this.root) && !(next = n.nextSibling)) {\n                            n = n.parentNode;\n                        }\n                        this._next = next;\n                    }\n                }\n                return this._current;\n            },\n\n            detach: function() {\n                this._current = this._next = this.root = null;\n            }\n        };\n\n        function createIterator(root) {\n            return new NodeIterator(root);\n        }\n\n        function DomPosition(node, offset) {\n            this.node = node;\n            this.offset = offset;\n        }\n\n        DomPosition.prototype = {\n            equals: function(pos) {\n                return !!pos && this.node === pos.node && this.offset == pos.offset;\n            },\n\n            inspect: function() {\n                return \"[DomPosition(\" + inspectNode(this.node) + \":\" + this.offset + \")]\";\n            },\n\n            toString: function() {\n                return this.inspect();\n            }\n        };\n\n        function DOMException(codeName) {\n            this.code = this[codeName];\n            this.codeName = codeName;\n            this.message = \"DOMException: \" + this.codeName;\n        }\n\n        DOMException.prototype = {\n            INDEX_SIZE_ERR: 1,\n            HIERARCHY_REQUEST_ERR: 3,\n            WRONG_DOCUMENT_ERR: 4,\n            NO_MODIFICATION_ALLOWED_ERR: 7,\n            NOT_FOUND_ERR: 8,\n            NOT_SUPPORTED_ERR: 9,\n            INVALID_STATE_ERR: 11,\n            INVALID_NODE_TYPE_ERR: 24\n        };\n\n        DOMException.prototype.toString = function() {\n            return this.message;\n        };\n\n        api.dom = {\n            arrayContains: arrayContains,\n            isHtmlNamespace: isHtmlNamespace,\n            parentElement: parentElement,\n            getNodeIndex: getNodeIndex,\n            getNodeLength: getNodeLength,\n            getCommonAncestor: getCommonAncestor,\n            isAncestorOf: isAncestorOf,\n            isOrIsAncestorOf: isOrIsAncestorOf,\n            getClosestAncestorIn: getClosestAncestorIn,\n            isCharacterDataNode: isCharacterDataNode,\n            isTextOrCommentNode: isTextOrCommentNode,\n            insertAfter: insertAfter,\n            splitDataNode: splitDataNode,\n            getDocument: getDocument,\n            getWindow: getWindow,\n            getIframeWindow: getIframeWindow,\n            getIframeDocument: getIframeDocument,\n            getBody: util.getBody,\n            isWindow: isWindow,\n            getContentDocument: getContentDocument,\n            getRootContainer: getRootContainer,\n            comparePoints: comparePoints,\n            isBrokenNode: isBrokenNode,\n            inspectNode: inspectNode,\n            getComputedStyleProperty: getComputedStyleProperty,\n            fragmentFromNodeChildren: fragmentFromNodeChildren,\n            createIterator: createIterator,\n            DomPosition: DomPosition\n        };\n\n        api.DOMException = DOMException;\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Pure JavaScript implementation of DOM Range\n    api.createCoreModule(\"DomRange\", [\"DomUtil\"], function(api, module) {\n        var dom = api.dom;\n        var util = api.util;\n        var DomPosition = dom.DomPosition;\n        var DOMException = api.DOMException;\n\n        var isCharacterDataNode = dom.isCharacterDataNode;\n        var getNodeIndex = dom.getNodeIndex;\n        var isOrIsAncestorOf = dom.isOrIsAncestorOf;\n        var getDocument = dom.getDocument;\n        var comparePoints = dom.comparePoints;\n        var splitDataNode = dom.splitDataNode;\n        var getClosestAncestorIn = dom.getClosestAncestorIn;\n        var getNodeLength = dom.getNodeLength;\n        var arrayContains = dom.arrayContains;\n        var getRootContainer = dom.getRootContainer;\n        var crashyTextNodes = api.features.crashyTextNodes;\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Utility functions\n\n        function isNonTextPartiallySelected(node, range) {\n            return (node.nodeType != 3) &&\n                   (isOrIsAncestorOf(node, range.startContainer) || isOrIsAncestorOf(node, range.endContainer));\n        }\n\n        function getRangeDocument(range) {\n            return range.document || getDocument(range.startContainer);\n        }\n\n        function getBoundaryBeforeNode(node) {\n            return new DomPosition(node.parentNode, getNodeIndex(node));\n        }\n\n        function getBoundaryAfterNode(node) {\n            return new DomPosition(node.parentNode, getNodeIndex(node) + 1);\n        }\n\n        function insertNodeAtPosition(node, n, o) {\n            var firstNodeInserted = node.nodeType == 11 ? node.firstChild : node;\n            if (isCharacterDataNode(n)) {\n                if (o == n.length) {\n                    dom.insertAfter(node, n);\n                } else {\n                    n.parentNode.insertBefore(node, o == 0 ? n : splitDataNode(n, o));\n                }\n            } else if (o >= n.childNodes.length) {\n                n.appendChild(node);\n            } else {\n                n.insertBefore(node, n.childNodes[o]);\n            }\n            return firstNodeInserted;\n        }\n\n        function rangesIntersect(rangeA, rangeB, touchingIsIntersecting) {\n            assertRangeValid(rangeA);\n            assertRangeValid(rangeB);\n\n            if (getRangeDocument(rangeB) != getRangeDocument(rangeA)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n\n            var startComparison = comparePoints(rangeA.startContainer, rangeA.startOffset, rangeB.endContainer, rangeB.endOffset),\n                endComparison = comparePoints(rangeA.endContainer, rangeA.endOffset, rangeB.startContainer, rangeB.startOffset);\n\n            return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;\n        }\n\n        function cloneSubtree(iterator) {\n            var partiallySelected;\n            for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {\n                partiallySelected = iterator.isPartiallySelectedSubtree();\n                node = node.cloneNode(!partiallySelected);\n                if (partiallySelected) {\n                    subIterator = iterator.getSubtreeIterator();\n                    node.appendChild(cloneSubtree(subIterator));\n                    subIterator.detach();\n                }\n\n                if (node.nodeType == 10) { // DocumentType\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n                frag.appendChild(node);\n            }\n            return frag;\n        }\n\n        function iterateSubtree(rangeIterator, func, iteratorState) {\n            var it, n;\n            iteratorState = iteratorState || { stop: false };\n            for (var node, subRangeIterator; node = rangeIterator.next(); ) {\n                if (rangeIterator.isPartiallySelectedSubtree()) {\n                    if (func(node) === false) {\n                        iteratorState.stop = true;\n                        return;\n                    } else {\n                        // The node is partially selected by the Range, so we can use a new RangeIterator on the portion of\n                        // the node selected by the Range.\n                        subRangeIterator = rangeIterator.getSubtreeIterator();\n                        iterateSubtree(subRangeIterator, func, iteratorState);\n                        subRangeIterator.detach();\n                        if (iteratorState.stop) {\n                            return;\n                        }\n                    }\n                } else {\n                    // The whole node is selected, so we can use efficient DOM iteration to iterate over the node and its\n                    // descendants\n                    it = dom.createIterator(node);\n                    while ( (n = it.next()) ) {\n                        if (func(n) === false) {\n                            iteratorState.stop = true;\n                            return;\n                        }\n                    }\n                }\n            }\n        }\n\n        function deleteSubtree(iterator) {\n            var subIterator;\n            while (iterator.next()) {\n                if (iterator.isPartiallySelectedSubtree()) {\n                    subIterator = iterator.getSubtreeIterator();\n                    deleteSubtree(subIterator);\n                    subIterator.detach();\n                } else {\n                    iterator.remove();\n                }\n            }\n        }\n\n        function extractSubtree(iterator) {\n            for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {\n\n                if (iterator.isPartiallySelectedSubtree()) {\n                    node = node.cloneNode(false);\n                    subIterator = iterator.getSubtreeIterator();\n                    node.appendChild(extractSubtree(subIterator));\n                    subIterator.detach();\n                } else {\n                    iterator.remove();\n                }\n                if (node.nodeType == 10) { // DocumentType\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n                frag.appendChild(node);\n            }\n            return frag;\n        }\n\n        function getNodesInRange(range, nodeTypes, filter) {\n            var filterNodeTypes = !!(nodeTypes && nodeTypes.length), regex;\n            var filterExists = !!filter;\n            if (filterNodeTypes) {\n                regex = new RegExp(\"^(\" + nodeTypes.join(\"|\") + \")$\");\n            }\n\n            var nodes = [];\n            iterateSubtree(new RangeIterator(range, false), function(node) {\n                if (filterNodeTypes && !regex.test(node.nodeType)) {\n                    return;\n                }\n                if (filterExists && !filter(node)) {\n                    return;\n                }\n                // Don't include a boundary container if it is a character data node and the range does not contain any\n                // of its character data. See issue 190.\n                var sc = range.startContainer;\n                if (node == sc && isCharacterDataNode(sc) && range.startOffset == sc.length) {\n                    return;\n                }\n\n                var ec = range.endContainer;\n                if (node == ec && isCharacterDataNode(ec) && range.endOffset == 0) {\n                    return;\n                }\n\n                nodes.push(node);\n            });\n            return nodes;\n        }\n\n        function inspect(range) {\n            var name = (typeof range.getName == \"undefined\") ? \"Range\" : range.getName();\n            return \"[\" + name + \"(\" + dom.inspectNode(range.startContainer) + \":\" + range.startOffset + \", \" +\n                    dom.inspectNode(range.endContainer) + \":\" + range.endOffset + \")]\";\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // RangeIterator code partially borrows from IERange by Tim Ryan (http://github.com/timcameronryan/IERange)\n\n        function RangeIterator(range, clonePartiallySelectedTextNodes) {\n            this.range = range;\n            this.clonePartiallySelectedTextNodes = clonePartiallySelectedTextNodes;\n\n\n            if (!range.collapsed) {\n                this.sc = range.startContainer;\n                this.so = range.startOffset;\n                this.ec = range.endContainer;\n                this.eo = range.endOffset;\n                var root = range.commonAncestorContainer;\n\n                if (this.sc === this.ec && isCharacterDataNode(this.sc)) {\n                    this.isSingleCharacterDataNode = true;\n                    this._first = this._last = this._next = this.sc;\n                } else {\n                    this._first = this._next = (this.sc === root && !isCharacterDataNode(this.sc)) ?\n                        this.sc.childNodes[this.so] : getClosestAncestorIn(this.sc, root, true);\n                    this._last = (this.ec === root && !isCharacterDataNode(this.ec)) ?\n                        this.ec.childNodes[this.eo - 1] : getClosestAncestorIn(this.ec, root, true);\n                }\n            }\n        }\n\n        RangeIterator.prototype = {\n            _current: null,\n            _next: null,\n            _first: null,\n            _last: null,\n            isSingleCharacterDataNode: false,\n\n            reset: function() {\n                this._current = null;\n                this._next = this._first;\n            },\n\n            hasNext: function() {\n                return !!this._next;\n            },\n\n            next: function() {\n                // Move to next node\n                var current = this._current = this._next;\n                if (current) {\n                    this._next = (current !== this._last) ? current.nextSibling : null;\n\n                    // Check for partially selected text nodes\n                    if (isCharacterDataNode(current) && this.clonePartiallySelectedTextNodes) {\n                        if (current === this.ec) {\n                            (current = current.cloneNode(true)).deleteData(this.eo, current.length - this.eo);\n                        }\n                        if (this._current === this.sc) {\n                            (current = current.cloneNode(true)).deleteData(0, this.so);\n                        }\n                    }\n                }\n\n                return current;\n            },\n\n            remove: function() {\n                var current = this._current, start, end;\n\n                if (isCharacterDataNode(current) && (current === this.sc || current === this.ec)) {\n                    start = (current === this.sc) ? this.so : 0;\n                    end = (current === this.ec) ? this.eo : current.length;\n                    if (start != end) {\n                        current.deleteData(start, end - start);\n                    }\n                } else {\n                    if (current.parentNode) {\n                        current.parentNode.removeChild(current);\n                    } else {\n                    }\n                }\n            },\n\n            // Checks if the current node is partially selected\n            isPartiallySelectedSubtree: function() {\n                var current = this._current;\n                return isNonTextPartiallySelected(current, this.range);\n            },\n\n            getSubtreeIterator: function() {\n                var subRange;\n                if (this.isSingleCharacterDataNode) {\n                    subRange = this.range.cloneRange();\n                    subRange.collapse(false);\n                } else {\n                    subRange = new Range(getRangeDocument(this.range));\n                    var current = this._current;\n                    var startContainer = current, startOffset = 0, endContainer = current, endOffset = getNodeLength(current);\n\n                    if (isOrIsAncestorOf(current, this.sc)) {\n                        startContainer = this.sc;\n                        startOffset = this.so;\n                    }\n                    if (isOrIsAncestorOf(current, this.ec)) {\n                        endContainer = this.ec;\n                        endOffset = this.eo;\n                    }\n\n                    updateBoundaries(subRange, startContainer, startOffset, endContainer, endOffset);\n                }\n                return new RangeIterator(subRange, this.clonePartiallySelectedTextNodes);\n            },\n\n            detach: function() {\n                this.range = this._current = this._next = this._first = this._last = this.sc = this.so = this.ec = this.eo = null;\n            }\n        };\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        var beforeAfterNodeTypes = [1, 3, 4, 5, 7, 8, 10];\n        var rootContainerNodeTypes = [2, 9, 11];\n        var readonlyNodeTypes = [5, 6, 10, 12];\n        var insertableNodeTypes = [1, 3, 4, 5, 7, 8, 10, 11];\n        var surroundNodeTypes = [1, 3, 4, 5, 7, 8];\n\n        function createAncestorFinder(nodeTypes) {\n            return function(node, selfIsAncestor) {\n                var t, n = selfIsAncestor ? node : node.parentNode;\n                while (n) {\n                    t = n.nodeType;\n                    if (arrayContains(nodeTypes, t)) {\n                        return n;\n                    }\n                    n = n.parentNode;\n                }\n                return null;\n            };\n        }\n\n        var getDocumentOrFragmentContainer = createAncestorFinder( [9, 11] );\n        var getReadonlyAncestor = createAncestorFinder(readonlyNodeTypes);\n        var getDocTypeNotationEntityAncestor = createAncestorFinder( [6, 10, 12] );\n\n        function assertNoDocTypeNotationEntityAncestor(node, allowSelf) {\n            if (getDocTypeNotationEntityAncestor(node, allowSelf)) {\n                throw new DOMException(\"INVALID_NODE_TYPE_ERR\");\n            }\n        }\n\n        function assertValidNodeType(node, invalidTypes) {\n            if (!arrayContains(invalidTypes, node.nodeType)) {\n                throw new DOMException(\"INVALID_NODE_TYPE_ERR\");\n            }\n        }\n\n        function assertValidOffset(node, offset) {\n            if (offset < 0 || offset > (isCharacterDataNode(node) ? node.length : node.childNodes.length)) {\n                throw new DOMException(\"INDEX_SIZE_ERR\");\n            }\n        }\n\n        function assertSameDocumentOrFragment(node1, node2) {\n            if (getDocumentOrFragmentContainer(node1, true) !== getDocumentOrFragmentContainer(node2, true)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n        }\n\n        function assertNodeNotReadOnly(node) {\n            if (getReadonlyAncestor(node, true)) {\n                throw new DOMException(\"NO_MODIFICATION_ALLOWED_ERR\");\n            }\n        }\n\n        function assertNode(node, codeName) {\n            if (!node) {\n                throw new DOMException(codeName);\n            }\n        }\n\n        function isOrphan(node) {\n            return (crashyTextNodes && dom.isBrokenNode(node)) ||\n                !arrayContains(rootContainerNodeTypes, node.nodeType) && !getDocumentOrFragmentContainer(node, true);\n        }\n\n        function isValidOffset(node, offset) {\n            return offset <= (isCharacterDataNode(node) ? node.length : node.childNodes.length);\n        }\n\n        function isRangeValid(range) {\n            return (!!range.startContainer && !!range.endContainer &&\n                    !isOrphan(range.startContainer) &&\n                    !isOrphan(range.endContainer) &&\n                    isValidOffset(range.startContainer, range.startOffset) &&\n                    isValidOffset(range.endContainer, range.endOffset));\n        }\n\n        function assertRangeValid(range) {\n            if (!isRangeValid(range)) {\n                throw new Error(\"Range error: Range is no longer valid after DOM mutation (\" + range.inspect() + \")\");\n            }\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Test the browser's innerHTML support to decide how to implement createContextualFragment\n        var styleEl = document.createElement(\"style\");\n        var htmlParsingConforms = false;\n        try {\n            styleEl.innerHTML = \"<b>x</b>\";\n            htmlParsingConforms = (styleEl.firstChild.nodeType == 3); // Opera incorrectly creates an element node\n        } catch (e) {\n            // IE 6 and 7 throw\n        }\n\n        api.features.htmlParsingConforms = htmlParsingConforms;\n\n        var createContextualFragment = htmlParsingConforms ?\n\n            // Implementation as per HTML parsing spec, trusting in the browser's implementation of innerHTML. See\n            // discussion and base code for this implementation at issue 67.\n            // Spec: http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface\n            // Thanks to Aleks Williams.\n            function(fragmentStr) {\n                // \"Let node the context object's start's node.\"\n                var node = this.startContainer;\n                var doc = getDocument(node);\n\n                // \"If the context object's start's node is null, raise an INVALID_STATE_ERR\n                // exception and abort these steps.\"\n                if (!node) {\n                    throw new DOMException(\"INVALID_STATE_ERR\");\n                }\n\n                // \"Let element be as follows, depending on node's interface:\"\n                // Document, Document Fragment: null\n                var el = null;\n\n                // \"Element: node\"\n                if (node.nodeType == 1) {\n                    el = node;\n\n                // \"Text, Comment: node's parentElement\"\n                } else if (isCharacterDataNode(node)) {\n                    el = dom.parentElement(node);\n                }\n\n                // \"If either element is null or element's ownerDocument is an HTML document\n                // and element's local name is \"html\" and element's namespace is the HTML\n                // namespace\"\n                if (el === null || (\n                    el.nodeName == \"HTML\" &&\n                    dom.isHtmlNamespace(getDocument(el).documentElement) &&\n                    dom.isHtmlNamespace(el)\n                )) {\n\n                // \"let element be a new Element with \"body\" as its local name and the HTML\n                // namespace as its namespace.\"\"\n                    el = doc.createElement(\"body\");\n                } else {\n                    el = el.cloneNode(false);\n                }\n\n                // \"If the node's document is an HTML document: Invoke the HTML fragment parsing algorithm.\"\n                // \"If the node's document is an XML document: Invoke the XML fragment parsing algorithm.\"\n                // \"In either case, the algorithm must be invoked with fragment as the input\n                // and element as the context element.\"\n                el.innerHTML = fragmentStr;\n\n                // \"If this raises an exception, then abort these steps. Otherwise, let new\n                // children be the nodes returned.\"\n\n                // \"Let fragment be a new DocumentFragment.\"\n                // \"Append all new children to fragment.\"\n                // \"Return fragment.\"\n                return dom.fragmentFromNodeChildren(el);\n            } :\n\n            // In this case, innerHTML cannot be trusted, so fall back to a simpler, non-conformant implementation that\n            // previous versions of Rangy used (with the exception of using a body element rather than a div)\n            function(fragmentStr) {\n                var doc = getRangeDocument(this);\n                var el = doc.createElement(\"body\");\n                el.innerHTML = fragmentStr;\n\n                return dom.fragmentFromNodeChildren(el);\n            };\n\n        function splitRangeBoundaries(range, positionsToPreserve) {\n            assertRangeValid(range);\n\n            var sc = range.startContainer, so = range.startOffset, ec = range.endContainer, eo = range.endOffset;\n            var startEndSame = (sc === ec);\n\n            if (isCharacterDataNode(ec) && eo > 0 && eo < ec.length) {\n                splitDataNode(ec, eo, positionsToPreserve);\n            }\n\n            if (isCharacterDataNode(sc) && so > 0 && so < sc.length) {\n                sc = splitDataNode(sc, so, positionsToPreserve);\n                if (startEndSame) {\n                    eo -= so;\n                    ec = sc;\n                } else if (ec == sc.parentNode && eo >= getNodeIndex(sc)) {\n                    eo++;\n                }\n                so = 0;\n            }\n            range.setStartAndEnd(sc, so, ec, eo);\n        }\n        \n        function rangeToHtml(range) {\n            assertRangeValid(range);\n            var container = range.commonAncestorContainer.parentNode.cloneNode(false);\n            container.appendChild( range.cloneContents() );\n            return container.innerHTML;\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        var rangeProperties = [\"startContainer\", \"startOffset\", \"endContainer\", \"endOffset\", \"collapsed\",\n            \"commonAncestorContainer\"];\n\n        var s2s = 0, s2e = 1, e2e = 2, e2s = 3;\n        var n_b = 0, n_a = 1, n_b_a = 2, n_i = 3;\n\n        util.extend(api.rangePrototype, {\n            compareBoundaryPoints: function(how, range) {\n                assertRangeValid(this);\n                assertSameDocumentOrFragment(this.startContainer, range.startContainer);\n\n                var nodeA, offsetA, nodeB, offsetB;\n                var prefixA = (how == e2s || how == s2s) ? \"start\" : \"end\";\n                var prefixB = (how == s2e || how == s2s) ? \"start\" : \"end\";\n                nodeA = this[prefixA + \"Container\"];\n                offsetA = this[prefixA + \"Offset\"];\n                nodeB = range[prefixB + \"Container\"];\n                offsetB = range[prefixB + \"Offset\"];\n                return comparePoints(nodeA, offsetA, nodeB, offsetB);\n            },\n\n            insertNode: function(node) {\n                assertRangeValid(this);\n                assertValidNodeType(node, insertableNodeTypes);\n                assertNodeNotReadOnly(this.startContainer);\n\n                if (isOrIsAncestorOf(node, this.startContainer)) {\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n\n                // No check for whether the container of the start of the Range is of a type that does not allow\n                // children of the type of node: the browser's DOM implementation should do this for us when we attempt\n                // to add the node\n\n                var firstNodeInserted = insertNodeAtPosition(node, this.startContainer, this.startOffset);\n                this.setStartBefore(firstNodeInserted);\n            },\n\n            cloneContents: function() {\n                assertRangeValid(this);\n\n                var clone, frag;\n                if (this.collapsed) {\n                    return getRangeDocument(this).createDocumentFragment();\n                } else {\n                    if (this.startContainer === this.endContainer && isCharacterDataNode(this.startContainer)) {\n                        clone = this.startContainer.cloneNode(true);\n                        clone.data = clone.data.slice(this.startOffset, this.endOffset);\n                        frag = getRangeDocument(this).createDocumentFragment();\n                        frag.appendChild(clone);\n                        return frag;\n                    } else {\n                        var iterator = new RangeIterator(this, true);\n                        clone = cloneSubtree(iterator);\n                        iterator.detach();\n                    }\n                    return clone;\n                }\n            },\n\n            canSurroundContents: function() {\n                assertRangeValid(this);\n                assertNodeNotReadOnly(this.startContainer);\n                assertNodeNotReadOnly(this.endContainer);\n\n                // Check if the contents can be surrounded. Specifically, this means whether the range partially selects\n                // no non-text nodes.\n                var iterator = new RangeIterator(this, true);\n                var boundariesInvalid = (iterator._first && (isNonTextPartiallySelected(iterator._first, this)) ||\n                        (iterator._last && isNonTextPartiallySelected(iterator._last, this)));\n                iterator.detach();\n                return !boundariesInvalid;\n            },\n\n            surroundContents: function(node) {\n                assertValidNodeType(node, surroundNodeTypes);\n\n                if (!this.canSurroundContents()) {\n                    throw new DOMException(\"INVALID_STATE_ERR\");\n                }\n\n                // Extract the contents\n                var content = this.extractContents();\n\n                // Clear the children of the node\n                if (node.hasChildNodes()) {\n                    while (node.lastChild) {\n                        node.removeChild(node.lastChild);\n                    }\n                }\n\n                // Insert the new node and add the extracted contents\n                insertNodeAtPosition(node, this.startContainer, this.startOffset);\n                node.appendChild(content);\n\n                this.selectNode(node);\n            },\n\n            cloneRange: function() {\n                assertRangeValid(this);\n                var range = new Range(getRangeDocument(this));\n                var i = rangeProperties.length, prop;\n                while (i--) {\n                    prop = rangeProperties[i];\n                    range[prop] = this[prop];\n                }\n                return range;\n            },\n\n            toString: function() {\n                assertRangeValid(this);\n                var sc = this.startContainer;\n                if (sc === this.endContainer && isCharacterDataNode(sc)) {\n                    return (sc.nodeType == 3 || sc.nodeType == 4) ? sc.data.slice(this.startOffset, this.endOffset) : \"\";\n                } else {\n                    var textParts = [], iterator = new RangeIterator(this, true);\n                    iterateSubtree(iterator, function(node) {\n                        // Accept only text or CDATA nodes, not comments\n                        if (node.nodeType == 3 || node.nodeType == 4) {\n                            textParts.push(node.data);\n                        }\n                    });\n                    iterator.detach();\n                    return textParts.join(\"\");\n                }\n            },\n\n            // The methods below are all non-standard. The following batch were introduced by Mozilla but have since\n            // been removed from Mozilla.\n\n            compareNode: function(node) {\n                assertRangeValid(this);\n\n                var parent = node.parentNode;\n                var nodeIndex = getNodeIndex(node);\n\n                if (!parent) {\n                    throw new DOMException(\"NOT_FOUND_ERR\");\n                }\n\n                var startComparison = this.comparePoint(parent, nodeIndex),\n                    endComparison = this.comparePoint(parent, nodeIndex + 1);\n\n                if (startComparison < 0) { // Node starts before\n                    return (endComparison > 0) ? n_b_a : n_b;\n                } else {\n                    return (endComparison > 0) ? n_a : n_i;\n                }\n            },\n\n            comparePoint: function(node, offset) {\n                assertRangeValid(this);\n                assertNode(node, \"HIERARCHY_REQUEST_ERR\");\n                assertSameDocumentOrFragment(node, this.startContainer);\n\n                if (comparePoints(node, offset, this.startContainer, this.startOffset) < 0) {\n                    return -1;\n                } else if (comparePoints(node, offset, this.endContainer, this.endOffset) > 0) {\n                    return 1;\n                }\n                return 0;\n            },\n\n            createContextualFragment: createContextualFragment,\n\n            toHtml: function() {\n                return rangeToHtml(this);\n            },\n\n            // touchingIsIntersecting determines whether this method considers a node that borders a range intersects\n            // with it (as in WebKit) or not (as in Gecko pre-1.9, and the default)\n            intersectsNode: function(node, touchingIsIntersecting) {\n                assertRangeValid(this);\n                assertNode(node, \"NOT_FOUND_ERR\");\n                if (getDocument(node) !== getRangeDocument(this)) {\n                    return false;\n                }\n\n                var parent = node.parentNode, offset = getNodeIndex(node);\n                assertNode(parent, \"NOT_FOUND_ERR\");\n\n                var startComparison = comparePoints(parent, offset, this.endContainer, this.endOffset),\n                    endComparison = comparePoints(parent, offset + 1, this.startContainer, this.startOffset);\n\n                return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;\n            },\n\n            isPointInRange: function(node, offset) {\n                assertRangeValid(this);\n                assertNode(node, \"HIERARCHY_REQUEST_ERR\");\n                assertSameDocumentOrFragment(node, this.startContainer);\n\n                return (comparePoints(node, offset, this.startContainer, this.startOffset) >= 0) &&\n                       (comparePoints(node, offset, this.endContainer, this.endOffset) <= 0);\n            },\n\n            // The methods below are non-standard and invented by me.\n\n            // Sharing a boundary start-to-end or end-to-start does not count as intersection.\n            intersectsRange: function(range) {\n                return rangesIntersect(this, range, false);\n            },\n\n            // Sharing a boundary start-to-end or end-to-start does count as intersection.\n            intersectsOrTouchesRange: function(range) {\n                return rangesIntersect(this, range, true);\n            },\n\n            intersection: function(range) {\n                if (this.intersectsRange(range)) {\n                    var startComparison = comparePoints(this.startContainer, this.startOffset, range.startContainer, range.startOffset),\n                        endComparison = comparePoints(this.endContainer, this.endOffset, range.endContainer, range.endOffset);\n\n                    var intersectionRange = this.cloneRange();\n                    if (startComparison == -1) {\n                        intersectionRange.setStart(range.startContainer, range.startOffset);\n                    }\n                    if (endComparison == 1) {\n                        intersectionRange.setEnd(range.endContainer, range.endOffset);\n                    }\n                    return intersectionRange;\n                }\n                return null;\n            },\n\n            union: function(range) {\n                if (this.intersectsOrTouchesRange(range)) {\n                    var unionRange = this.cloneRange();\n                    if (comparePoints(range.startContainer, range.startOffset, this.startContainer, this.startOffset) == -1) {\n                        unionRange.setStart(range.startContainer, range.startOffset);\n                    }\n                    if (comparePoints(range.endContainer, range.endOffset, this.endContainer, this.endOffset) == 1) {\n                        unionRange.setEnd(range.endContainer, range.endOffset);\n                    }\n                    return unionRange;\n                } else {\n                    throw new DOMException(\"Ranges do not intersect\");\n                }\n            },\n\n            containsNode: function(node, allowPartial) {\n                if (allowPartial) {\n                    return this.intersectsNode(node, false);\n                } else {\n                    return this.compareNode(node) == n_i;\n                }\n            },\n\n            containsNodeContents: function(node) {\n                return this.comparePoint(node, 0) >= 0 && this.comparePoint(node, getNodeLength(node)) <= 0;\n            },\n\n            containsRange: function(range) {\n                var intersection = this.intersection(range);\n                return intersection !== null && range.equals(intersection);\n            },\n\n            containsNodeText: function(node) {\n                var nodeRange = this.cloneRange();\n                nodeRange.selectNode(node);\n                var textNodes = nodeRange.getNodes([3]);\n                if (textNodes.length > 0) {\n                    nodeRange.setStart(textNodes[0], 0);\n                    var lastTextNode = textNodes.pop();\n                    nodeRange.setEnd(lastTextNode, lastTextNode.length);\n                    return this.containsRange(nodeRange);\n                } else {\n                    return this.containsNodeContents(node);\n                }\n            },\n\n            getNodes: function(nodeTypes, filter) {\n                assertRangeValid(this);\n                return getNodesInRange(this, nodeTypes, filter);\n            },\n\n            getDocument: function() {\n                return getRangeDocument(this);\n            },\n\n            collapseBefore: function(node) {\n                this.setEndBefore(node);\n                this.collapse(false);\n            },\n\n            collapseAfter: function(node) {\n                this.setStartAfter(node);\n                this.collapse(true);\n            },\n            \n            getBookmark: function(containerNode) {\n                var doc = getRangeDocument(this);\n                var preSelectionRange = api.createRange(doc);\n                containerNode = containerNode || dom.getBody(doc);\n                preSelectionRange.selectNodeContents(containerNode);\n                var range = this.intersection(preSelectionRange);\n                var start = 0, end = 0;\n                if (range) {\n                    preSelectionRange.setEnd(range.startContainer, range.startOffset);\n                    start = preSelectionRange.toString().length;\n                    end = start + range.toString().length;\n                }\n\n                return {\n                    start: start,\n                    end: end,\n                    containerNode: containerNode\n                };\n            },\n            \n            moveToBookmark: function(bookmark) {\n                var containerNode = bookmark.containerNode;\n                var charIndex = 0;\n                this.setStart(containerNode, 0);\n                this.collapse(true);\n                var nodeStack = [containerNode], node, foundStart = false, stop = false;\n                var nextCharIndex, i, childNodes;\n\n                while (!stop && (node = nodeStack.pop())) {\n                    if (node.nodeType == 3) {\n                        nextCharIndex = charIndex + node.length;\n                        if (!foundStart && bookmark.start >= charIndex && bookmark.start <= nextCharIndex) {\n                            this.setStart(node, bookmark.start - charIndex);\n                            foundStart = true;\n                        }\n                        if (foundStart && bookmark.end >= charIndex && bookmark.end <= nextCharIndex) {\n                            this.setEnd(node, bookmark.end - charIndex);\n                            stop = true;\n                        }\n                        charIndex = nextCharIndex;\n                    } else {\n                        childNodes = node.childNodes;\n                        i = childNodes.length;\n                        while (i--) {\n                            nodeStack.push(childNodes[i]);\n                        }\n                    }\n                }\n            },\n\n            getName: function() {\n                return \"DomRange\";\n            },\n\n            equals: function(range) {\n                return Range.rangesEqual(this, range);\n            },\n\n            isValid: function() {\n                return isRangeValid(this);\n            },\n            \n            inspect: function() {\n                return inspect(this);\n            },\n            \n            detach: function() {\n                // In DOM4, detach() is now a no-op.\n            }\n        });\n\n        function copyComparisonConstantsToObject(obj) {\n            obj.START_TO_START = s2s;\n            obj.START_TO_END = s2e;\n            obj.END_TO_END = e2e;\n            obj.END_TO_START = e2s;\n\n            obj.NODE_BEFORE = n_b;\n            obj.NODE_AFTER = n_a;\n            obj.NODE_BEFORE_AND_AFTER = n_b_a;\n            obj.NODE_INSIDE = n_i;\n        }\n\n        function copyComparisonConstants(constructor) {\n            copyComparisonConstantsToObject(constructor);\n            copyComparisonConstantsToObject(constructor.prototype);\n        }\n\n        function createRangeContentRemover(remover, boundaryUpdater) {\n            return function() {\n                assertRangeValid(this);\n\n                var sc = this.startContainer, so = this.startOffset, root = this.commonAncestorContainer;\n\n                var iterator = new RangeIterator(this, true);\n\n                // Work out where to position the range after content removal\n                var node, boundary;\n                if (sc !== root) {\n                    node = getClosestAncestorIn(sc, root, true);\n                    boundary = getBoundaryAfterNode(node);\n                    sc = boundary.node;\n                    so = boundary.offset;\n                }\n\n                // Check none of the range is read-only\n                iterateSubtree(iterator, assertNodeNotReadOnly);\n\n                iterator.reset();\n\n                // Remove the content\n                var returnValue = remover(iterator);\n                iterator.detach();\n\n                // Move to the new position\n                boundaryUpdater(this, sc, so, sc, so);\n\n                return returnValue;\n            };\n        }\n\n        function createPrototypeRange(constructor, boundaryUpdater) {\n            function createBeforeAfterNodeSetter(isBefore, isStart) {\n                return function(node) {\n                    assertValidNodeType(node, beforeAfterNodeTypes);\n                    assertValidNodeType(getRootContainer(node), rootContainerNodeTypes);\n\n                    var boundary = (isBefore ? getBoundaryBeforeNode : getBoundaryAfterNode)(node);\n                    (isStart ? setRangeStart : setRangeEnd)(this, boundary.node, boundary.offset);\n                };\n            }\n\n            function setRangeStart(range, node, offset) {\n                var ec = range.endContainer, eo = range.endOffset;\n                if (node !== range.startContainer || offset !== range.startOffset) {\n                    // Check the root containers of the range and the new boundary, and also check whether the new boundary\n                    // is after the current end. In either case, collapse the range to the new position\n                    if (getRootContainer(node) != getRootContainer(ec) || comparePoints(node, offset, ec, eo) == 1) {\n                        ec = node;\n                        eo = offset;\n                    }\n                    boundaryUpdater(range, node, offset, ec, eo);\n                }\n            }\n\n            function setRangeEnd(range, node, offset) {\n                var sc = range.startContainer, so = range.startOffset;\n                if (node !== range.endContainer || offset !== range.endOffset) {\n                    // Check the root containers of the range and the new boundary, and also check whether the new boundary\n                    // is after the current end. In either case, collapse the range to the new position\n                    if (getRootContainer(node) != getRootContainer(sc) || comparePoints(node, offset, sc, so) == -1) {\n                        sc = node;\n                        so = offset;\n                    }\n                    boundaryUpdater(range, sc, so, node, offset);\n                }\n            }\n\n            // Set up inheritance\n            var F = function() {};\n            F.prototype = api.rangePrototype;\n            constructor.prototype = new F();\n\n            util.extend(constructor.prototype, {\n                setStart: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n\n                    setRangeStart(this, node, offset);\n                },\n\n                setEnd: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n\n                    setRangeEnd(this, node, offset);\n                },\n\n                /**\n                 * Convenience method to set a range's start and end boundaries. Overloaded as follows:\n                 * - Two parameters (node, offset) creates a collapsed range at that position\n                 * - Three parameters (node, startOffset, endOffset) creates a range contained with node starting at\n                 *   startOffset and ending at endOffset\n                 * - Four parameters (startNode, startOffset, endNode, endOffset) creates a range starting at startOffset in\n                 *   startNode and ending at endOffset in endNode\n                 */\n                setStartAndEnd: function() {\n                    var args = arguments;\n                    var sc = args[0], so = args[1], ec = sc, eo = so;\n\n                    switch (args.length) {\n                        case 3:\n                            eo = args[2];\n                            break;\n                        case 4:\n                            ec = args[2];\n                            eo = args[3];\n                            break;\n                    }\n\n                    boundaryUpdater(this, sc, so, ec, eo);\n                },\n                \n                setBoundary: function(node, offset, isStart) {\n                    this[\"set\" + (isStart ? \"Start\" : \"End\")](node, offset);\n                },\n\n                setStartBefore: createBeforeAfterNodeSetter(true, true),\n                setStartAfter: createBeforeAfterNodeSetter(false, true),\n                setEndBefore: createBeforeAfterNodeSetter(true, false),\n                setEndAfter: createBeforeAfterNodeSetter(false, false),\n\n                collapse: function(isStart) {\n                    assertRangeValid(this);\n                    if (isStart) {\n                        boundaryUpdater(this, this.startContainer, this.startOffset, this.startContainer, this.startOffset);\n                    } else {\n                        boundaryUpdater(this, this.endContainer, this.endOffset, this.endContainer, this.endOffset);\n                    }\n                },\n\n                selectNodeContents: function(node) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n\n                    boundaryUpdater(this, node, 0, node, getNodeLength(node));\n                },\n\n                selectNode: function(node) {\n                    assertNoDocTypeNotationEntityAncestor(node, false);\n                    assertValidNodeType(node, beforeAfterNodeTypes);\n\n                    var start = getBoundaryBeforeNode(node), end = getBoundaryAfterNode(node);\n                    boundaryUpdater(this, start.node, start.offset, end.node, end.offset);\n                },\n\n                extractContents: createRangeContentRemover(extractSubtree, boundaryUpdater),\n\n                deleteContents: createRangeContentRemover(deleteSubtree, boundaryUpdater),\n\n                canSurroundContents: function() {\n                    assertRangeValid(this);\n                    assertNodeNotReadOnly(this.startContainer);\n                    assertNodeNotReadOnly(this.endContainer);\n\n                    // Check if the contents can be surrounded. Specifically, this means whether the range partially selects\n                    // no non-text nodes.\n                    var iterator = new RangeIterator(this, true);\n                    var boundariesInvalid = (iterator._first && isNonTextPartiallySelected(iterator._first, this) ||\n                            (iterator._last && isNonTextPartiallySelected(iterator._last, this)));\n                    iterator.detach();\n                    return !boundariesInvalid;\n                },\n\n                splitBoundaries: function() {\n                    splitRangeBoundaries(this);\n                },\n\n                splitBoundariesPreservingPositions: function(positionsToPreserve) {\n                    splitRangeBoundaries(this, positionsToPreserve);\n                },\n\n                normalizeBoundaries: function() {\n                    assertRangeValid(this);\n\n                    var sc = this.startContainer, so = this.startOffset, ec = this.endContainer, eo = this.endOffset;\n\n                    var mergeForward = function(node) {\n                        var sibling = node.nextSibling;\n                        if (sibling && sibling.nodeType == node.nodeType) {\n                            ec = node;\n                            eo = node.length;\n                            node.appendData(sibling.data);\n                            sibling.parentNode.removeChild(sibling);\n                        }\n                    };\n\n                    var mergeBackward = function(node) {\n                        var sibling = node.previousSibling;\n                        if (sibling && sibling.nodeType == node.nodeType) {\n                            sc = node;\n                            var nodeLength = node.length;\n                            so = sibling.length;\n                            node.insertData(0, sibling.data);\n                            sibling.parentNode.removeChild(sibling);\n                            if (sc == ec) {\n                                eo += so;\n                                ec = sc;\n                            } else if (ec == node.parentNode) {\n                                var nodeIndex = getNodeIndex(node);\n                                if (eo == nodeIndex) {\n                                    ec = node;\n                                    eo = nodeLength;\n                                } else if (eo > nodeIndex) {\n                                    eo--;\n                                }\n                            }\n                        }\n                    };\n\n                    var normalizeStart = true;\n\n                    if (isCharacterDataNode(ec)) {\n                        if (ec.length == eo) {\n                            mergeForward(ec);\n                        }\n                    } else {\n                        if (eo > 0) {\n                            var endNode = ec.childNodes[eo - 1];\n                            if (endNode && isCharacterDataNode(endNode)) {\n                                mergeForward(endNode);\n                            }\n                        }\n                        normalizeStart = !this.collapsed;\n                    }\n\n                    if (normalizeStart) {\n                        if (isCharacterDataNode(sc)) {\n                            if (so == 0) {\n                                mergeBackward(sc);\n                            }\n                        } else {\n                            if (so < sc.childNodes.length) {\n                                var startNode = sc.childNodes[so];\n                                if (startNode && isCharacterDataNode(startNode)) {\n                                    mergeBackward(startNode);\n                                }\n                            }\n                        }\n                    } else {\n                        sc = ec;\n                        so = eo;\n                    }\n\n                    boundaryUpdater(this, sc, so, ec, eo);\n                },\n\n                collapseToPoint: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n                    this.setStartAndEnd(node, offset);\n                }\n            });\n\n            copyComparisonConstants(constructor);\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Updates commonAncestorContainer and collapsed after boundary change\n        function updateCollapsedAndCommonAncestor(range) {\n            range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);\n            range.commonAncestorContainer = range.collapsed ?\n                range.startContainer : dom.getCommonAncestor(range.startContainer, range.endContainer);\n        }\n\n        function updateBoundaries(range, startContainer, startOffset, endContainer, endOffset) {\n            range.startContainer = startContainer;\n            range.startOffset = startOffset;\n            range.endContainer = endContainer;\n            range.endOffset = endOffset;\n            range.document = dom.getDocument(startContainer);\n\n            updateCollapsedAndCommonAncestor(range);\n        }\n\n        function Range(doc) {\n            this.startContainer = doc;\n            this.startOffset = 0;\n            this.endContainer = doc;\n            this.endOffset = 0;\n            this.document = doc;\n            updateCollapsedAndCommonAncestor(this);\n        }\n\n        createPrototypeRange(Range, updateBoundaries);\n\n        util.extend(Range, {\n            rangeProperties: rangeProperties,\n            RangeIterator: RangeIterator,\n            copyComparisonConstants: copyComparisonConstants,\n            createPrototypeRange: createPrototypeRange,\n            inspect: inspect,\n            toHtml: rangeToHtml,\n            getRangeDocument: getRangeDocument,\n            rangesEqual: function(r1, r2) {\n                return r1.startContainer === r2.startContainer &&\n                    r1.startOffset === r2.startOffset &&\n                    r1.endContainer === r2.endContainer &&\n                    r1.endOffset === r2.endOffset;\n            }\n        });\n\n        api.DomRange = Range;\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Wrappers for the browser's native DOM Range and/or TextRange implementation \n    api.createCoreModule(\"WrappedRange\", [\"DomRange\"], function(api, module) {\n        var WrappedRange, WrappedTextRange;\n        var dom = api.dom;\n        var util = api.util;\n        var DomPosition = dom.DomPosition;\n        var DomRange = api.DomRange;\n        var getBody = dom.getBody;\n        var getContentDocument = dom.getContentDocument;\n        var isCharacterDataNode = dom.isCharacterDataNode;\n\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        if (api.features.implementsDomRange) {\n            // This is a wrapper around the browser's native DOM Range. It has two aims:\n            // - Provide workarounds for specific browser bugs\n            // - provide convenient extensions, which are inherited from Rangy's DomRange\n\n            (function() {\n                var rangeProto;\n                var rangeProperties = DomRange.rangeProperties;\n\n                function updateRangeProperties(range) {\n                    var i = rangeProperties.length, prop;\n                    while (i--) {\n                        prop = rangeProperties[i];\n                        range[prop] = range.nativeRange[prop];\n                    }\n                    // Fix for broken collapsed property in IE 9.\n                    range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);\n                }\n\n                function updateNativeRange(range, startContainer, startOffset, endContainer, endOffset) {\n                    var startMoved = (range.startContainer !== startContainer || range.startOffset != startOffset);\n                    var endMoved = (range.endContainer !== endContainer || range.endOffset != endOffset);\n                    var nativeRangeDifferent = !range.equals(range.nativeRange);\n\n                    // Always set both boundaries for the benefit of IE9 (see issue 35)\n                    if (startMoved || endMoved || nativeRangeDifferent) {\n                        range.setEnd(endContainer, endOffset);\n                        range.setStart(startContainer, startOffset);\n                    }\n                }\n\n                var createBeforeAfterNodeSetter;\n\n                WrappedRange = function(range) {\n                    if (!range) {\n                        throw module.createError(\"WrappedRange: Range must be specified\");\n                    }\n                    this.nativeRange = range;\n                    updateRangeProperties(this);\n                };\n\n                DomRange.createPrototypeRange(WrappedRange, updateNativeRange);\n\n                rangeProto = WrappedRange.prototype;\n\n                rangeProto.selectNode = function(node) {\n                    this.nativeRange.selectNode(node);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.cloneContents = function() {\n                    return this.nativeRange.cloneContents();\n                };\n\n                // Due to a long-standing Firefox bug that I have not been able to find a reliable way to detect,\n                // insertNode() is never delegated to the native range.\n\n                rangeProto.surroundContents = function(node) {\n                    this.nativeRange.surroundContents(node);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.collapse = function(isStart) {\n                    this.nativeRange.collapse(isStart);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.cloneRange = function() {\n                    return new WrappedRange(this.nativeRange.cloneRange());\n                };\n\n                rangeProto.refresh = function() {\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.toString = function() {\n                    return this.nativeRange.toString();\n                };\n\n                // Create test range and node for feature detection\n\n                var testTextNode = document.createTextNode(\"test\");\n                getBody(document).appendChild(testTextNode);\n                var range = document.createRange();\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for Firefox 2 bug that prevents moving the start of a Range to a point after its current end and\n                // correct for it\n\n                range.setStart(testTextNode, 0);\n                range.setEnd(testTextNode, 0);\n\n                try {\n                    range.setStart(testTextNode, 1);\n\n                    rangeProto.setStart = function(node, offset) {\n                        this.nativeRange.setStart(node, offset);\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.setEnd = function(node, offset) {\n                        this.nativeRange.setEnd(node, offset);\n                        updateRangeProperties(this);\n                    };\n\n                    createBeforeAfterNodeSetter = function(name) {\n                        return function(node) {\n                            this.nativeRange[name](node);\n                            updateRangeProperties(this);\n                        };\n                    };\n\n                } catch(ex) {\n\n                    rangeProto.setStart = function(node, offset) {\n                        try {\n                            this.nativeRange.setStart(node, offset);\n                        } catch (ex) {\n                            this.nativeRange.setEnd(node, offset);\n                            this.nativeRange.setStart(node, offset);\n                        }\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.setEnd = function(node, offset) {\n                        try {\n                            this.nativeRange.setEnd(node, offset);\n                        } catch (ex) {\n                            this.nativeRange.setStart(node, offset);\n                            this.nativeRange.setEnd(node, offset);\n                        }\n                        updateRangeProperties(this);\n                    };\n\n                    createBeforeAfterNodeSetter = function(name, oppositeName) {\n                        return function(node) {\n                            try {\n                                this.nativeRange[name](node);\n                            } catch (ex) {\n                                this.nativeRange[oppositeName](node);\n                                this.nativeRange[name](node);\n                            }\n                            updateRangeProperties(this);\n                        };\n                    };\n                }\n\n                rangeProto.setStartBefore = createBeforeAfterNodeSetter(\"setStartBefore\", \"setEndBefore\");\n                rangeProto.setStartAfter = createBeforeAfterNodeSetter(\"setStartAfter\", \"setEndAfter\");\n                rangeProto.setEndBefore = createBeforeAfterNodeSetter(\"setEndBefore\", \"setStartBefore\");\n                rangeProto.setEndAfter = createBeforeAfterNodeSetter(\"setEndAfter\", \"setStartAfter\");\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Always use DOM4-compliant selectNodeContents implementation: it's simpler and less code than testing\n                // whether the native implementation can be trusted\n                rangeProto.selectNodeContents = function(node) {\n                    this.setStartAndEnd(node, 0, dom.getNodeLength(node));\n                };\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for and correct WebKit bug that has the behaviour of compareBoundaryPoints round the wrong way for\n                // constants START_TO_END and END_TO_START: https://bugs.webkit.org/show_bug.cgi?id=20738\n\n                range.selectNodeContents(testTextNode);\n                range.setEnd(testTextNode, 3);\n\n                var range2 = document.createRange();\n                range2.selectNodeContents(testTextNode);\n                range2.setEnd(testTextNode, 4);\n                range2.setStart(testTextNode, 2);\n\n                if (range.compareBoundaryPoints(range.START_TO_END, range2) == -1 &&\n                        range.compareBoundaryPoints(range.END_TO_START, range2) == 1) {\n                    // This is the wrong way round, so correct for it\n\n                    rangeProto.compareBoundaryPoints = function(type, range) {\n                        range = range.nativeRange || range;\n                        if (type == range.START_TO_END) {\n                            type = range.END_TO_START;\n                        } else if (type == range.END_TO_START) {\n                            type = range.START_TO_END;\n                        }\n                        return this.nativeRange.compareBoundaryPoints(type, range);\n                    };\n                } else {\n                    rangeProto.compareBoundaryPoints = function(type, range) {\n                        return this.nativeRange.compareBoundaryPoints(type, range.nativeRange || range);\n                    };\n                }\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for IE deleteContents() and extractContents() bug and correct it. See issue 107.\n\n                var el = document.createElement(\"div\");\n                el.innerHTML = \"123\";\n                var textNode = el.firstChild;\n                var body = getBody(document);\n                body.appendChild(el);\n\n                range.setStart(textNode, 1);\n                range.setEnd(textNode, 2);\n                range.deleteContents();\n\n                if (textNode.data == \"13\") {\n                    // Behaviour is correct per DOM4 Range so wrap the browser's implementation of deleteContents() and\n                    // extractContents()\n                    rangeProto.deleteContents = function() {\n                        this.nativeRange.deleteContents();\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.extractContents = function() {\n                        var frag = this.nativeRange.extractContents();\n                        updateRangeProperties(this);\n                        return frag;\n                    };\n                } else {\n                }\n\n                body.removeChild(el);\n                body = null;\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for existence of createContextualFragment and delegate to it if it exists\n                if (util.isHostMethod(range, \"createContextualFragment\")) {\n                    rangeProto.createContextualFragment = function(fragmentStr) {\n                        return this.nativeRange.createContextualFragment(fragmentStr);\n                    };\n                }\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Clean up\n                getBody(document).removeChild(testTextNode);\n\n                rangeProto.getName = function() {\n                    return \"WrappedRange\";\n                };\n\n                api.WrappedRange = WrappedRange;\n\n                api.createNativeRange = function(doc) {\n                    doc = getContentDocument(doc, module, \"createNativeRange\");\n                    return doc.createRange();\n                };\n            })();\n        }\n        \n        if (api.features.implementsTextRange) {\n            /*\n            This is a workaround for a bug where IE returns the wrong container element from the TextRange's parentElement()\n            method. For example, in the following (where pipes denote the selection boundaries):\n\n            <ul id=\"ul\"><li id=\"a\">| a </li><li id=\"b\"> b |</li></ul>\n\n            var range = document.selection.createRange();\n            alert(range.parentElement().id); // Should alert \"ul\" but alerts \"b\"\n\n            This method returns the common ancestor node of the following:\n            - the parentElement() of the textRange\n            - the parentElement() of the textRange after calling collapse(true)\n            - the parentElement() of the textRange after calling collapse(false)\n            */\n            var getTextRangeContainerElement = function(textRange) {\n                var parentEl = textRange.parentElement();\n                var range = textRange.duplicate();\n                range.collapse(true);\n                var startEl = range.parentElement();\n                range = textRange.duplicate();\n                range.collapse(false);\n                var endEl = range.parentElement();\n                var startEndContainer = (startEl == endEl) ? startEl : dom.getCommonAncestor(startEl, endEl);\n\n                return startEndContainer == parentEl ? startEndContainer : dom.getCommonAncestor(parentEl, startEndContainer);\n            };\n\n            var textRangeIsCollapsed = function(textRange) {\n                return textRange.compareEndPoints(\"StartToEnd\", textRange) == 0;\n            };\n\n            // Gets the boundary of a TextRange expressed as a node and an offset within that node. This function started\n            // out as an improved version of code found in Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/)\n            // but has grown, fixing problems with line breaks in preformatted text, adding workaround for IE TextRange\n            // bugs, handling for inputs and images, plus optimizations.\n            var getTextRangeBoundaryPosition = function(textRange, wholeRangeContainerElement, isStart, isCollapsed, startInfo) {\n                var workingRange = textRange.duplicate();\n                workingRange.collapse(isStart);\n                var containerElement = workingRange.parentElement();\n\n                // Sometimes collapsing a TextRange that's at the start of a text node can move it into the previous node, so\n                // check for that\n                if (!dom.isOrIsAncestorOf(wholeRangeContainerElement, containerElement)) {\n                    containerElement = wholeRangeContainerElement;\n                }\n\n\n                // Deal with nodes that cannot \"contain rich HTML markup\". In practice, this means form inputs, images and\n                // similar. See http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx\n                if (!containerElement.canHaveHTML) {\n                    var pos = new DomPosition(containerElement.parentNode, dom.getNodeIndex(containerElement));\n                    return {\n                        boundaryPosition: pos,\n                        nodeInfo: {\n                            nodeIndex: pos.offset,\n                            containerElement: pos.node\n                        }\n                    };\n                }\n\n                var workingNode = dom.getDocument(containerElement).createElement(\"span\");\n\n                // Workaround for HTML5 Shiv's insane violation of document.createElement(). See Rangy issue 104 and HTML5\n                // Shiv issue 64: https://github.com/aFarkas/html5shiv/issues/64\n                if (workingNode.parentNode) {\n                    workingNode.parentNode.removeChild(workingNode);\n                }\n\n                var comparison, workingComparisonType = isStart ? \"StartToStart\" : \"StartToEnd\";\n                var previousNode, nextNode, boundaryPosition, boundaryNode;\n                var start = (startInfo && startInfo.containerElement == containerElement) ? startInfo.nodeIndex : 0;\n                var childNodeCount = containerElement.childNodes.length;\n                var end = childNodeCount;\n\n                // Check end first. Code within the loop assumes that the endth child node of the container is definitely\n                // after the range boundary.\n                var nodeIndex = end;\n\n                while (true) {\n                    if (nodeIndex == childNodeCount) {\n                        containerElement.appendChild(workingNode);\n                    } else {\n                        containerElement.insertBefore(workingNode, containerElement.childNodes[nodeIndex]);\n                    }\n                    workingRange.moveToElementText(workingNode);\n                    comparison = workingRange.compareEndPoints(workingComparisonType, textRange);\n                    if (comparison == 0 || start == end) {\n                        break;\n                    } else if (comparison == -1) {\n                        if (end == start + 1) {\n                            // We know the endth child node is after the range boundary, so we must be done.\n                            break;\n                        } else {\n                            start = nodeIndex;\n                        }\n                    } else {\n                        end = (end == start + 1) ? start : nodeIndex;\n                    }\n                    nodeIndex = Math.floor((start + end) / 2);\n                    containerElement.removeChild(workingNode);\n                }\n\n\n                // We've now reached or gone past the boundary of the text range we're interested in\n                // so have identified the node we want\n                boundaryNode = workingNode.nextSibling;\n\n                if (comparison == -1 && boundaryNode && isCharacterDataNode(boundaryNode)) {\n                    // This is a character data node (text, comment, cdata). The working range is collapsed at the start of\n                    // the node containing the text range's boundary, so we move the end of the working range to the\n                    // boundary point and measure the length of its text to get the boundary's offset within the node.\n                    workingRange.setEndPoint(isStart ? \"EndToStart\" : \"EndToEnd\", textRange);\n\n                    var offset;\n\n                    if (/[\\r\\n]/.test(boundaryNode.data)) {\n                        /*\n                        For the particular case of a boundary within a text node containing rendered line breaks (within a\n                        <pre> element, for example), we need a slightly complicated approach to get the boundary's offset in\n                        IE. The facts:\n                        \n                        - Each line break is represented as \\r in the text node's data/nodeValue properties\n                        - Each line break is represented as \\r\\n in the TextRange's 'text' property\n                        - The 'text' property of the TextRange does not contain trailing line breaks\n                        \n                        To get round the problem presented by the final fact above, we can use the fact that TextRange's\n                        moveStart() and moveEnd() methods return the actual number of characters moved, which is not\n                        necessarily the same as the number of characters it was instructed to move. The simplest approach is\n                        to use this to store the characters moved when moving both the start and end of the range to the\n                        start of the document body and subtracting the start offset from the end offset (the\n                        \"move-negative-gazillion\" method). However, this is extremely slow when the document is large and\n                        the range is near the end of it. Clearly doing the mirror image (i.e. moving the range boundaries to\n                        the end of the document) has the same problem.\n                        \n                        Another approach that works is to use moveStart() to move the start boundary of the range up to the\n                        end boundary one character at a time and incrementing a counter with the value returned by the\n                        moveStart() call. However, the check for whether the start boundary has reached the end boundary is\n                        expensive, so this method is slow (although unlike \"move-negative-gazillion\" is largely unaffected\n                        by the location of the range within the document).\n                        \n                        The approach used below is a hybrid of the two methods above. It uses the fact that a string\n                        containing the TextRange's 'text' property with each \\r\\n converted to a single \\r character cannot\n                        be longer than the text of the TextRange, so the start of the range is moved that length initially\n                        and then a character at a time to make up for any trailing line breaks not contained in the 'text'\n                        property. This has good performance in most situations compared to the previous two methods.\n                        */\n                        var tempRange = workingRange.duplicate();\n                        var rangeLength = tempRange.text.replace(/\\r\\n/g, \"\\r\").length;\n\n                        offset = tempRange.moveStart(\"character\", rangeLength);\n                        while ( (comparison = tempRange.compareEndPoints(\"StartToEnd\", tempRange)) == -1) {\n                            offset++;\n                            tempRange.moveStart(\"character\", 1);\n                        }\n                    } else {\n                        offset = workingRange.text.length;\n                    }\n                    boundaryPosition = new DomPosition(boundaryNode, offset);\n                } else {\n\n                    // If the boundary immediately follows a character data node and this is the end boundary, we should favour\n                    // a position within that, and likewise for a start boundary preceding a character data node\n                    previousNode = (isCollapsed || !isStart) && workingNode.previousSibling;\n                    nextNode = (isCollapsed || isStart) && workingNode.nextSibling;\n                    if (nextNode && isCharacterDataNode(nextNode)) {\n                        boundaryPosition = new DomPosition(nextNode, 0);\n                    } else if (previousNode && isCharacterDataNode(previousNode)) {\n                        boundaryPosition = new DomPosition(previousNode, previousNode.data.length);\n                    } else {\n                        boundaryPosition = new DomPosition(containerElement, dom.getNodeIndex(workingNode));\n                    }\n                }\n\n                // Clean up\n                workingNode.parentNode.removeChild(workingNode);\n\n                return {\n                    boundaryPosition: boundaryPosition,\n                    nodeInfo: {\n                        nodeIndex: nodeIndex,\n                        containerElement: containerElement\n                    }\n                };\n            };\n\n            // Returns a TextRange representing the boundary of a TextRange expressed as a node and an offset within that\n            // node. This function started out as an optimized version of code found in Tim Cameron Ryan's IERange\n            // (http://code.google.com/p/ierange/)\n            var createBoundaryTextRange = function(boundaryPosition, isStart) {\n                var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;\n                var doc = dom.getDocument(boundaryPosition.node);\n                var workingNode, childNodes, workingRange = getBody(doc).createTextRange();\n                var nodeIsDataNode = isCharacterDataNode(boundaryPosition.node);\n\n                if (nodeIsDataNode) {\n                    boundaryNode = boundaryPosition.node;\n                    boundaryParent = boundaryNode.parentNode;\n                } else {\n                    childNodes = boundaryPosition.node.childNodes;\n                    boundaryNode = (boundaryOffset < childNodes.length) ? childNodes[boundaryOffset] : null;\n                    boundaryParent = boundaryPosition.node;\n                }\n\n                // Position the range immediately before the node containing the boundary\n                workingNode = doc.createElement(\"span\");\n\n                // Making the working element non-empty element persuades IE to consider the TextRange boundary to be within\n                // the element rather than immediately before or after it\n                workingNode.innerHTML = \"&#feff;\";\n\n                // insertBefore is supposed to work like appendChild if the second parameter is null. However, a bug report\n                // for IERange suggests that it can crash the browser: http://code.google.com/p/ierange/issues/detail?id=12\n                if (boundaryNode) {\n                    boundaryParent.insertBefore(workingNode, boundaryNode);\n                } else {\n                    boundaryParent.appendChild(workingNode);\n                }\n\n                workingRange.moveToElementText(workingNode);\n                workingRange.collapse(!isStart);\n\n                // Clean up\n                boundaryParent.removeChild(workingNode);\n\n                // Move the working range to the text offset, if required\n                if (nodeIsDataNode) {\n                    workingRange[isStart ? \"moveStart\" : \"moveEnd\"](\"character\", boundaryOffset);\n                }\n\n                return workingRange;\n            };\n\n            /*------------------------------------------------------------------------------------------------------------*/\n\n            // This is a wrapper around a TextRange, providing full DOM Range functionality using rangy's DomRange as a\n            // prototype\n\n            WrappedTextRange = function(textRange) {\n                this.textRange = textRange;\n                this.refresh();\n            };\n\n            WrappedTextRange.prototype = new DomRange(document);\n\n            WrappedTextRange.prototype.refresh = function() {\n                var start, end, startBoundary;\n\n                // TextRange's parentElement() method cannot be trusted. getTextRangeContainerElement() works around that.\n                var rangeContainerElement = getTextRangeContainerElement(this.textRange);\n\n                if (textRangeIsCollapsed(this.textRange)) {\n                    end = start = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true,\n                        true).boundaryPosition;\n                } else {\n                    startBoundary = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true, false);\n                    start = startBoundary.boundaryPosition;\n\n                    // An optimization used here is that if the start and end boundaries have the same parent element, the\n                    // search scope for the end boundary can be limited to exclude the portion of the element that precedes\n                    // the start boundary\n                    end = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, false, false,\n                        startBoundary.nodeInfo).boundaryPosition;\n                }\n\n                this.setStart(start.node, start.offset);\n                this.setEnd(end.node, end.offset);\n            };\n\n            WrappedTextRange.prototype.getName = function() {\n                return \"WrappedTextRange\";\n            };\n\n            DomRange.copyComparisonConstants(WrappedTextRange);\n\n            var rangeToTextRange = function(range) {\n                if (range.collapsed) {\n                    return createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);\n                } else {\n                    var startRange = createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);\n                    var endRange = createBoundaryTextRange(new DomPosition(range.endContainer, range.endOffset), false);\n                    var textRange = getBody( DomRange.getRangeDocument(range) ).createTextRange();\n                    textRange.setEndPoint(\"StartToStart\", startRange);\n                    textRange.setEndPoint(\"EndToEnd\", endRange);\n                    return textRange;\n                }\n            };\n\n            WrappedTextRange.rangeToTextRange = rangeToTextRange;\n\n            WrappedTextRange.prototype.toTextRange = function() {\n                return rangeToTextRange(this);\n            };\n\n            api.WrappedTextRange = WrappedTextRange;\n\n            // IE 9 and above have both implementations and Rangy makes both available. The next few lines sets which\n            // implementation to use by default.\n            if (!api.features.implementsDomRange || api.config.preferTextRange) {\n                // Add WrappedTextRange as the Range property of the global object to allow expression like Range.END_TO_END to work\n                var globalObj = (function(f) { return f(\"return this;\")(); })(Function);\n                if (typeof globalObj.Range == \"undefined\") {\n                    globalObj.Range = WrappedTextRange;\n                }\n\n                api.createNativeRange = function(doc) {\n                    doc = getContentDocument(doc, module, \"createNativeRange\");\n                    return getBody(doc).createTextRange();\n                };\n\n                api.WrappedRange = WrappedTextRange;\n            }\n        }\n\n        api.createRange = function(doc) {\n            doc = getContentDocument(doc, module, \"createRange\");\n            return new api.WrappedRange(api.createNativeRange(doc));\n        };\n\n        api.createRangyRange = function(doc) {\n            doc = getContentDocument(doc, module, \"createRangyRange\");\n            return new DomRange(doc);\n        };\n\n        api.createIframeRange = function(iframeEl) {\n            module.deprecationNotice(\"createIframeRange()\", \"createRange(iframeEl)\");\n            return api.createRange(iframeEl);\n        };\n\n        api.createIframeRangyRange = function(iframeEl) {\n            module.deprecationNotice(\"createIframeRangyRange()\", \"createRangyRange(iframeEl)\");\n            return api.createRangyRange(iframeEl);\n        };\n\n        api.addShimListener(function(win) {\n            var doc = win.document;\n            if (typeof doc.createRange == \"undefined\") {\n                doc.createRange = function() {\n                    return api.createRange(doc);\n                };\n            }\n            doc = win = null;\n        });\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // This module creates a selection object wrapper that conforms as closely as possible to the Selection specification\n    // in the HTML Editing spec (http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections)\n    api.createCoreModule(\"WrappedSelection\", [\"DomRange\", \"WrappedRange\"], function(api, module) {\n        api.config.checkSelectionRanges = true;\n\n        var BOOLEAN = \"boolean\";\n        var NUMBER = \"number\";\n        var dom = api.dom;\n        var util = api.util;\n        var isHostMethod = util.isHostMethod;\n        var DomRange = api.DomRange;\n        var WrappedRange = api.WrappedRange;\n        var DOMException = api.DOMException;\n        var DomPosition = dom.DomPosition;\n        var getNativeSelection;\n        var selectionIsCollapsed;\n        var features = api.features;\n        var CONTROL = \"Control\";\n        var getDocument = dom.getDocument;\n        var getBody = dom.getBody;\n        var rangesEqual = DomRange.rangesEqual;\n\n\n        // Utility function to support direction parameters in the API that may be a string (\"backward\" or \"forward\") or a\n        // Boolean (true for backwards).\n        function isDirectionBackward(dir) {\n            return (typeof dir == \"string\") ? /^backward(s)?$/i.test(dir) : !!dir;\n        }\n\n        function getWindow(win, methodName) {\n            if (!win) {\n                return window;\n            } else if (dom.isWindow(win)) {\n                return win;\n            } else if (win instanceof WrappedSelection) {\n                return win.win;\n            } else {\n                var doc = dom.getContentDocument(win, module, methodName);\n                return dom.getWindow(doc);\n            }\n        }\n\n        function getWinSelection(winParam) {\n            return getWindow(winParam, \"getWinSelection\").getSelection();\n        }\n\n        function getDocSelection(winParam) {\n            return getWindow(winParam, \"getDocSelection\").document.selection;\n        }\n        \n        function winSelectionIsBackward(sel) {\n            var backward = false;\n            if (sel.anchorNode) {\n                backward = (dom.comparePoints(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset) == 1);\n            }\n            return backward;\n        }\n\n        // Test for the Range/TextRange and Selection features required\n        // Test for ability to retrieve selection\n        var implementsWinGetSelection = isHostMethod(window, \"getSelection\"),\n            implementsDocSelection = util.isHostObject(document, \"selection\");\n\n        features.implementsWinGetSelection = implementsWinGetSelection;\n        features.implementsDocSelection = implementsDocSelection;\n\n        var useDocumentSelection = implementsDocSelection && (!implementsWinGetSelection || api.config.preferTextRange);\n\n        if (useDocumentSelection) {\n            getNativeSelection = getDocSelection;\n            api.isSelectionValid = function(winParam) {\n                var doc = getWindow(winParam, \"isSelectionValid\").document, nativeSel = doc.selection;\n\n                // Check whether the selection TextRange is actually contained within the correct document\n                return (nativeSel.type != \"None\" || getDocument(nativeSel.createRange().parentElement()) == doc);\n            };\n        } else if (implementsWinGetSelection) {\n            getNativeSelection = getWinSelection;\n            api.isSelectionValid = function() {\n                return true;\n            };\n        } else {\n            module.fail(\"Neither document.selection or window.getSelection() detected.\");\n        }\n\n        api.getNativeSelection = getNativeSelection;\n\n        var testSelection = getNativeSelection();\n        var testRange = api.createNativeRange(document);\n        var body = getBody(document);\n\n        // Obtaining a range from a selection\n        var selectionHasAnchorAndFocus = util.areHostProperties(testSelection,\n            [\"anchorNode\", \"focusNode\", \"anchorOffset\", \"focusOffset\"]);\n\n        features.selectionHasAnchorAndFocus = selectionHasAnchorAndFocus;\n\n        // Test for existence of native selection extend() method\n        var selectionHasExtend = isHostMethod(testSelection, \"extend\");\n        features.selectionHasExtend = selectionHasExtend;\n        \n        // Test if rangeCount exists\n        var selectionHasRangeCount = (typeof testSelection.rangeCount == NUMBER);\n        features.selectionHasRangeCount = selectionHasRangeCount;\n\n        var selectionSupportsMultipleRanges = false;\n        var collapsedNonEditableSelectionsSupported = true;\n\n        var addRangeBackwardToNative = selectionHasExtend ?\n            function(nativeSelection, range) {\n                var doc = DomRange.getRangeDocument(range);\n                var endRange = api.createRange(doc);\n                endRange.collapseToPoint(range.endContainer, range.endOffset);\n                nativeSelection.addRange(getNativeRange(endRange));\n                nativeSelection.extend(range.startContainer, range.startOffset);\n            } : null;\n\n        if (util.areHostMethods(testSelection, [\"addRange\", \"getRangeAt\", \"removeAllRanges\"]) &&\n                typeof testSelection.rangeCount == NUMBER && features.implementsDomRange) {\n\n            (function() {\n                // Previously an iframe was used but this caused problems in some circumstances in IE, so tests are\n                // performed on the current document's selection. See issue 109.\n\n                // Note also that if a selection previously existed, it is wiped by these tests. This should usually be fine\n                // because initialization usually happens when the document loads, but could be a problem for a script that\n                // loads and initializes Rangy later. If anyone complains, code could be added to save and restore the\n                // selection.\n                var sel = window.getSelection();\n                if (sel) {\n                    // Store the current selection\n                    var originalSelectionRangeCount = sel.rangeCount;\n                    var selectionHasMultipleRanges = (originalSelectionRangeCount > 1);\n                    var originalSelectionRanges = [];\n                    var originalSelectionBackward = winSelectionIsBackward(sel); \n                    for (var i = 0; i < originalSelectionRangeCount; ++i) {\n                        originalSelectionRanges[i] = sel.getRangeAt(i);\n                    }\n                    \n                    // Create some test elements\n                    var body = getBody(document);\n                    var testEl = body.appendChild( document.createElement(\"div\") );\n                    testEl.contentEditable = \"false\";\n                    var textNode = testEl.appendChild( document.createTextNode(\"\\u00a0\\u00a0\\u00a0\") );\n\n                    // Test whether the native selection will allow a collapsed selection within a non-editable element\n                    var r1 = document.createRange();\n\n                    r1.setStart(textNode, 1);\n                    r1.collapse(true);\n                    sel.addRange(r1);\n                    collapsedNonEditableSelectionsSupported = (sel.rangeCount == 1);\n                    sel.removeAllRanges();\n\n                    // Test whether the native selection is capable of supporting multiple ranges.\n                    if (!selectionHasMultipleRanges) {\n                        // Doing the original feature test here in Chrome 36 (and presumably later versions) prints a\n                        // console error of \"Discontiguous selection is not supported.\" that cannot be suppressed. There's\n                        // nothing we can do about this while retaining the feature test so we have to resort to a browser\n                        // sniff. I'm not happy about it. See\n                        // https://code.google.com/p/chromium/issues/detail?id=399791\n                        var chromeMatch = window.navigator.appVersion.match(/Chrome\\/(.*?) /);\n                        if (chromeMatch && parseInt(chromeMatch[1]) >= 36) {\n                            selectionSupportsMultipleRanges = false;\n                        } else {\n                            var r2 = r1.cloneRange();\n                            r1.setStart(textNode, 0);\n                            r2.setEnd(textNode, 3);\n                            r2.setStart(textNode, 2);\n                            sel.addRange(r1);\n                            sel.addRange(r2);\n                            selectionSupportsMultipleRanges = (sel.rangeCount == 2);\n                        }\n                    }\n\n                    // Clean up\n                    body.removeChild(testEl);\n                    sel.removeAllRanges();\n\n                    for (i = 0; i < originalSelectionRangeCount; ++i) {\n                        if (i == 0 && originalSelectionBackward) {\n                            if (addRangeBackwardToNative) {\n                                addRangeBackwardToNative(sel, originalSelectionRanges[i]);\n                            } else {\n                                api.warn(\"Rangy initialization: original selection was backwards but selection has been restored forwards because the browser does not support Selection.extend\");\n                                sel.addRange(originalSelectionRanges[i]);\n                            }\n                        } else {\n                            sel.addRange(originalSelectionRanges[i]);\n                        }\n                    }\n                }\n            })();\n        }\n\n        features.selectionSupportsMultipleRanges = selectionSupportsMultipleRanges;\n        features.collapsedNonEditableSelectionsSupported = collapsedNonEditableSelectionsSupported;\n\n        // ControlRanges\n        var implementsControlRange = false, testControlRange;\n\n        if (body && isHostMethod(body, \"createControlRange\")) {\n            testControlRange = body.createControlRange();\n            if (util.areHostProperties(testControlRange, [\"item\", \"add\"])) {\n                implementsControlRange = true;\n            }\n        }\n        features.implementsControlRange = implementsControlRange;\n\n        // Selection collapsedness\n        if (selectionHasAnchorAndFocus) {\n            selectionIsCollapsed = function(sel) {\n                return sel.anchorNode === sel.focusNode && sel.anchorOffset === sel.focusOffset;\n            };\n        } else {\n            selectionIsCollapsed = function(sel) {\n                return sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1).collapsed : false;\n            };\n        }\n\n        function updateAnchorAndFocusFromRange(sel, range, backward) {\n            var anchorPrefix = backward ? \"end\" : \"start\", focusPrefix = backward ? \"start\" : \"end\";\n            sel.anchorNode = range[anchorPrefix + \"Container\"];\n            sel.anchorOffset = range[anchorPrefix + \"Offset\"];\n            sel.focusNode = range[focusPrefix + \"Container\"];\n            sel.focusOffset = range[focusPrefix + \"Offset\"];\n        }\n\n        function updateAnchorAndFocusFromNativeSelection(sel) {\n            var nativeSel = sel.nativeSelection;\n            sel.anchorNode = nativeSel.anchorNode;\n            sel.anchorOffset = nativeSel.anchorOffset;\n            sel.focusNode = nativeSel.focusNode;\n            sel.focusOffset = nativeSel.focusOffset;\n        }\n\n        function updateEmptySelection(sel) {\n            sel.anchorNode = sel.focusNode = null;\n            sel.anchorOffset = sel.focusOffset = 0;\n            sel.rangeCount = 0;\n            sel.isCollapsed = true;\n            sel._ranges.length = 0;\n        }\n\n        function getNativeRange(range) {\n            var nativeRange;\n            if (range instanceof DomRange) {\n                nativeRange = api.createNativeRange(range.getDocument());\n                nativeRange.setEnd(range.endContainer, range.endOffset);\n                nativeRange.setStart(range.startContainer, range.startOffset);\n            } else if (range instanceof WrappedRange) {\n                nativeRange = range.nativeRange;\n            } else if (features.implementsDomRange && (range instanceof dom.getWindow(range.startContainer).Range)) {\n                nativeRange = range;\n            }\n            return nativeRange;\n        }\n\n        function rangeContainsSingleElement(rangeNodes) {\n            if (!rangeNodes.length || rangeNodes[0].nodeType != 1) {\n                return false;\n            }\n            for (var i = 1, len = rangeNodes.length; i < len; ++i) {\n                if (!dom.isAncestorOf(rangeNodes[0], rangeNodes[i])) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        function getSingleElementFromRange(range) {\n            var nodes = range.getNodes();\n            if (!rangeContainsSingleElement(nodes)) {\n                throw module.createError(\"getSingleElementFromRange: range \" + range.inspect() + \" did not consist of a single element\");\n            }\n            return nodes[0];\n        }\n\n        // Simple, quick test which only needs to distinguish between a TextRange and a ControlRange\n        function isTextRange(range) {\n            return !!range && typeof range.text != \"undefined\";\n        }\n\n        function updateFromTextRange(sel, range) {\n            // Create a Range from the selected TextRange\n            var wrappedRange = new WrappedRange(range);\n            sel._ranges = [wrappedRange];\n\n            updateAnchorAndFocusFromRange(sel, wrappedRange, false);\n            sel.rangeCount = 1;\n            sel.isCollapsed = wrappedRange.collapsed;\n        }\n\n        function updateControlSelection(sel) {\n            // Update the wrapped selection based on what's now in the native selection\n            sel._ranges.length = 0;\n            if (sel.docSelection.type == \"None\") {\n                updateEmptySelection(sel);\n            } else {\n                var controlRange = sel.docSelection.createRange();\n                if (isTextRange(controlRange)) {\n                    // This case (where the selection type is \"Control\" and calling createRange() on the selection returns\n                    // a TextRange) can happen in IE 9. It happens, for example, when all elements in the selected\n                    // ControlRange have been removed from the ControlRange and removed from the document.\n                    updateFromTextRange(sel, controlRange);\n                } else {\n                    sel.rangeCount = controlRange.length;\n                    var range, doc = getDocument(controlRange.item(0));\n                    for (var i = 0; i < sel.rangeCount; ++i) {\n                        range = api.createRange(doc);\n                        range.selectNode(controlRange.item(i));\n                        sel._ranges.push(range);\n                    }\n                    sel.isCollapsed = sel.rangeCount == 1 && sel._ranges[0].collapsed;\n                    updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], false);\n                }\n            }\n        }\n\n        function addRangeToControlSelection(sel, range) {\n            var controlRange = sel.docSelection.createRange();\n            var rangeElement = getSingleElementFromRange(range);\n\n            // Create a new ControlRange containing all the elements in the selected ControlRange plus the element\n            // contained by the supplied range\n            var doc = getDocument(controlRange.item(0));\n            var newControlRange = getBody(doc).createControlRange();\n            for (var i = 0, len = controlRange.length; i < len; ++i) {\n                newControlRange.add(controlRange.item(i));\n            }\n            try {\n                newControlRange.add(rangeElement);\n            } catch (ex) {\n                throw module.createError(\"addRange(): Element within the specified Range could not be added to control selection (does it have layout?)\");\n            }\n            newControlRange.select();\n\n            // Update the wrapped selection based on what's now in the native selection\n            updateControlSelection(sel);\n        }\n\n        var getSelectionRangeAt;\n\n        if (isHostMethod(testSelection, \"getRangeAt\")) {\n            // try/catch is present because getRangeAt() must have thrown an error in some browser and some situation.\n            // Unfortunately, I didn't write a comment about the specifics and am now scared to take it out. Let that be a\n            // lesson to us all, especially me.\n            getSelectionRangeAt = function(sel, index) {\n                try {\n                    return sel.getRangeAt(index);\n                } catch (ex) {\n                    return null;\n                }\n            };\n        } else if (selectionHasAnchorAndFocus) {\n            getSelectionRangeAt = function(sel) {\n                var doc = getDocument(sel.anchorNode);\n                var range = api.createRange(doc);\n                range.setStartAndEnd(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);\n\n                // Handle the case when the selection was selected backwards (from the end to the start in the\n                // document)\n                if (range.collapsed !== this.isCollapsed) {\n                    range.setStartAndEnd(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset);\n                }\n\n                return range;\n            };\n        }\n\n        function WrappedSelection(selection, docSelection, win) {\n            this.nativeSelection = selection;\n            this.docSelection = docSelection;\n            this._ranges = [];\n            this.win = win;\n            this.refresh();\n        }\n\n        WrappedSelection.prototype = api.selectionPrototype;\n\n        function deleteProperties(sel) {\n            sel.win = sel.anchorNode = sel.focusNode = sel._ranges = null;\n            sel.rangeCount = sel.anchorOffset = sel.focusOffset = 0;\n            sel.detached = true;\n        }\n\n        var cachedRangySelections = [];\n\n        function actOnCachedSelection(win, action) {\n            var i = cachedRangySelections.length, cached, sel;\n            while (i--) {\n                cached = cachedRangySelections[i];\n                sel = cached.selection;\n                if (action == \"deleteAll\") {\n                    deleteProperties(sel);\n                } else if (cached.win == win) {\n                    if (action == \"delete\") {\n                        cachedRangySelections.splice(i, 1);\n                        return true;\n                    } else {\n                        return sel;\n                    }\n                }\n            }\n            if (action == \"deleteAll\") {\n                cachedRangySelections.length = 0;\n            }\n            return null;\n        }\n\n        var getSelection = function(win) {\n            // Check if the parameter is a Rangy Selection object\n            if (win && win instanceof WrappedSelection) {\n                win.refresh();\n                return win;\n            }\n\n            win = getWindow(win, \"getNativeSelection\");\n\n            var sel = actOnCachedSelection(win);\n            var nativeSel = getNativeSelection(win), docSel = implementsDocSelection ? getDocSelection(win) : null;\n            if (sel) {\n                sel.nativeSelection = nativeSel;\n                sel.docSelection = docSel;\n                sel.refresh();\n            } else {\n                sel = new WrappedSelection(nativeSel, docSel, win);\n                cachedRangySelections.push( { win: win, selection: sel } );\n            }\n            return sel;\n        };\n\n        api.getSelection = getSelection;\n\n        api.getIframeSelection = function(iframeEl) {\n            module.deprecationNotice(\"getIframeSelection()\", \"getSelection(iframeEl)\");\n            return api.getSelection(dom.getIframeWindow(iframeEl));\n        };\n\n        var selProto = WrappedSelection.prototype;\n\n        function createControlSelection(sel, ranges) {\n            // Ensure that the selection becomes of type \"Control\"\n            var doc = getDocument(ranges[0].startContainer);\n            var controlRange = getBody(doc).createControlRange();\n            for (var i = 0, el, len = ranges.length; i < len; ++i) {\n                el = getSingleElementFromRange(ranges[i]);\n                try {\n                    controlRange.add(el);\n                } catch (ex) {\n                    throw module.createError(\"setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)\");\n                }\n            }\n            controlRange.select();\n\n            // Update the wrapped selection based on what's now in the native selection\n            updateControlSelection(sel);\n        }\n\n        // Selecting a range\n        if (!useDocumentSelection && selectionHasAnchorAndFocus && util.areHostMethods(testSelection, [\"removeAllRanges\", \"addRange\"])) {\n            selProto.removeAllRanges = function() {\n                this.nativeSelection.removeAllRanges();\n                updateEmptySelection(this);\n            };\n\n            var addRangeBackward = function(sel, range) {\n                addRangeBackwardToNative(sel.nativeSelection, range);\n                sel.refresh();\n            };\n\n            if (selectionHasRangeCount) {\n                selProto.addRange = function(range, direction) {\n                    if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {\n                        addRangeToControlSelection(this, range);\n                    } else {\n                        if (isDirectionBackward(direction) && selectionHasExtend) {\n                            addRangeBackward(this, range);\n                        } else {\n                            var previousRangeCount;\n                            if (selectionSupportsMultipleRanges) {\n                                previousRangeCount = this.rangeCount;\n                            } else {\n                                this.removeAllRanges();\n                                previousRangeCount = 0;\n                            }\n                            // Clone the native range so that changing the selected range does not affect the selection.\n                            // This is contrary to the spec but is the only way to achieve consistency between browsers. See\n                            // issue 80.\n                            var clonedNativeRange = getNativeRange(range).cloneRange();\n                            try {\n                                this.nativeSelection.addRange(clonedNativeRange);\n                            } catch (ex) {\n                            }\n\n                            // Check whether adding the range was successful\n                            this.rangeCount = this.nativeSelection.rangeCount;\n\n                            if (this.rangeCount == previousRangeCount + 1) {\n                                // The range was added successfully\n\n                                // Check whether the range that we added to the selection is reflected in the last range extracted from\n                                // the selection\n                                if (api.config.checkSelectionRanges) {\n                                    var nativeRange = getSelectionRangeAt(this.nativeSelection, this.rangeCount - 1);\n                                    if (nativeRange && !rangesEqual(nativeRange, range)) {\n                                        // Happens in WebKit with, for example, a selection placed at the start of a text node\n                                        range = new WrappedRange(nativeRange);\n                                    }\n                                }\n                                this._ranges[this.rangeCount - 1] = range;\n                                updateAnchorAndFocusFromRange(this, range, selectionIsBackward(this.nativeSelection));\n                                this.isCollapsed = selectionIsCollapsed(this);\n                            } else {\n                                // The range was not added successfully. The simplest thing is to refresh\n                                this.refresh();\n                            }\n                        }\n                    }\n                };\n            } else {\n                selProto.addRange = function(range, direction) {\n                    if (isDirectionBackward(direction) && selectionHasExtend) {\n                        addRangeBackward(this, range);\n                    } else {\n                        this.nativeSelection.addRange(getNativeRange(range));\n                        this.refresh();\n                    }\n                };\n            }\n\n            selProto.setRanges = function(ranges) {\n                if (implementsControlRange && implementsDocSelection && ranges.length > 1) {\n                    createControlSelection(this, ranges);\n                } else {\n                    this.removeAllRanges();\n                    for (var i = 0, len = ranges.length; i < len; ++i) {\n                        this.addRange(ranges[i]);\n                    }\n                }\n            };\n        } else if (isHostMethod(testSelection, \"empty\") && isHostMethod(testRange, \"select\") &&\n                   implementsControlRange && useDocumentSelection) {\n\n            selProto.removeAllRanges = function() {\n                // Added try/catch as fix for issue #21\n                try {\n                    this.docSelection.empty();\n\n                    // Check for empty() not working (issue #24)\n                    if (this.docSelection.type != \"None\") {\n                        // Work around failure to empty a control selection by instead selecting a TextRange and then\n                        // calling empty()\n                        var doc;\n                        if (this.anchorNode) {\n                            doc = getDocument(this.anchorNode);\n                        } else if (this.docSelection.type == CONTROL) {\n                            var controlRange = this.docSelection.createRange();\n                            if (controlRange.length) {\n                                doc = getDocument( controlRange.item(0) );\n                            }\n                        }\n                        if (doc) {\n                            var textRange = getBody(doc).createTextRange();\n                            textRange.select();\n                            this.docSelection.empty();\n                        }\n                    }\n                } catch(ex) {}\n                updateEmptySelection(this);\n            };\n\n            selProto.addRange = function(range) {\n                if (this.docSelection.type == CONTROL) {\n                    addRangeToControlSelection(this, range);\n                } else {\n                    api.WrappedTextRange.rangeToTextRange(range).select();\n                    this._ranges[0] = range;\n                    this.rangeCount = 1;\n                    this.isCollapsed = this._ranges[0].collapsed;\n                    updateAnchorAndFocusFromRange(this, range, false);\n                }\n            };\n\n            selProto.setRanges = function(ranges) {\n                this.removeAllRanges();\n                var rangeCount = ranges.length;\n                if (rangeCount > 1) {\n                    createControlSelection(this, ranges);\n                } else if (rangeCount) {\n                    this.addRange(ranges[0]);\n                }\n            };\n        } else {\n            module.fail(\"No means of selecting a Range or TextRange was found\");\n            return false;\n        }\n\n        selProto.getRangeAt = function(index) {\n            if (index < 0 || index >= this.rangeCount) {\n                throw new DOMException(\"INDEX_SIZE_ERR\");\n            } else {\n                // Clone the range to preserve selection-range independence. See issue 80.\n                return this._ranges[index].cloneRange();\n            }\n        };\n\n        var refreshSelection;\n\n        if (useDocumentSelection) {\n            refreshSelection = function(sel) {\n                var range;\n                if (api.isSelectionValid(sel.win)) {\n                    range = sel.docSelection.createRange();\n                } else {\n                    range = getBody(sel.win.document).createTextRange();\n                    range.collapse(true);\n                }\n\n                if (sel.docSelection.type == CONTROL) {\n                    updateControlSelection(sel);\n                } else if (isTextRange(range)) {\n                    updateFromTextRange(sel, range);\n                } else {\n                    updateEmptySelection(sel);\n                }\n            };\n        } else if (isHostMethod(testSelection, \"getRangeAt\") && typeof testSelection.rangeCount == NUMBER) {\n            refreshSelection = function(sel) {\n                if (implementsControlRange && implementsDocSelection && sel.docSelection.type == CONTROL) {\n                    updateControlSelection(sel);\n                } else {\n                    sel._ranges.length = sel.rangeCount = sel.nativeSelection.rangeCount;\n                    if (sel.rangeCount) {\n                        for (var i = 0, len = sel.rangeCount; i < len; ++i) {\n                            sel._ranges[i] = new api.WrappedRange(sel.nativeSelection.getRangeAt(i));\n                        }\n                        updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], selectionIsBackward(sel.nativeSelection));\n                        sel.isCollapsed = selectionIsCollapsed(sel);\n                    } else {\n                        updateEmptySelection(sel);\n                    }\n                }\n            };\n        } else if (selectionHasAnchorAndFocus && typeof testSelection.isCollapsed == BOOLEAN && typeof testRange.collapsed == BOOLEAN && features.implementsDomRange) {\n            refreshSelection = function(sel) {\n                var range, nativeSel = sel.nativeSelection;\n                if (nativeSel.anchorNode) {\n                    range = getSelectionRangeAt(nativeSel, 0);\n                    sel._ranges = [range];\n                    sel.rangeCount = 1;\n                    updateAnchorAndFocusFromNativeSelection(sel);\n                    sel.isCollapsed = selectionIsCollapsed(sel);\n                } else {\n                    updateEmptySelection(sel);\n                }\n            };\n        } else {\n            module.fail(\"No means of obtaining a Range or TextRange from the user's selection was found\");\n            return false;\n        }\n\n        selProto.refresh = function(checkForChanges) {\n            var oldRanges = checkForChanges ? this._ranges.slice(0) : null;\n            var oldAnchorNode = this.anchorNode, oldAnchorOffset = this.anchorOffset;\n\n            refreshSelection(this);\n            if (checkForChanges) {\n                // Check the range count first\n                var i = oldRanges.length;\n                if (i != this._ranges.length) {\n                    return true;\n                }\n\n                // Now check the direction. Checking the anchor position is the same is enough since we're checking all the\n                // ranges after this\n                if (this.anchorNode != oldAnchorNode || this.anchorOffset != oldAnchorOffset) {\n                    return true;\n                }\n\n                // Finally, compare each range in turn\n                while (i--) {\n                    if (!rangesEqual(oldRanges[i], this._ranges[i])) {\n                        return true;\n                    }\n                }\n                return false;\n            }\n        };\n\n        // Removal of a single range\n        var removeRangeManually = function(sel, range) {\n            var ranges = sel.getAllRanges();\n            sel.removeAllRanges();\n            for (var i = 0, len = ranges.length; i < len; ++i) {\n                if (!rangesEqual(range, ranges[i])) {\n                    sel.addRange(ranges[i]);\n                }\n            }\n            if (!sel.rangeCount) {\n                updateEmptySelection(sel);\n            }\n        };\n\n        if (implementsControlRange && implementsDocSelection) {\n            selProto.removeRange = function(range) {\n                if (this.docSelection.type == CONTROL) {\n                    var controlRange = this.docSelection.createRange();\n                    var rangeElement = getSingleElementFromRange(range);\n\n                    // Create a new ControlRange containing all the elements in the selected ControlRange minus the\n                    // element contained by the supplied range\n                    var doc = getDocument(controlRange.item(0));\n                    var newControlRange = getBody(doc).createControlRange();\n                    var el, removed = false;\n                    for (var i = 0, len = controlRange.length; i < len; ++i) {\n                        el = controlRange.item(i);\n                        if (el !== rangeElement || removed) {\n                            newControlRange.add(controlRange.item(i));\n                        } else {\n                            removed = true;\n                        }\n                    }\n                    newControlRange.select();\n\n                    // Update the wrapped selection based on what's now in the native selection\n                    updateControlSelection(this);\n                } else {\n                    removeRangeManually(this, range);\n                }\n            };\n        } else {\n            selProto.removeRange = function(range) {\n                removeRangeManually(this, range);\n            };\n        }\n\n        // Detecting if a selection is backward\n        var selectionIsBackward;\n        if (!useDocumentSelection && selectionHasAnchorAndFocus && features.implementsDomRange) {\n            selectionIsBackward = winSelectionIsBackward;\n\n            selProto.isBackward = function() {\n                return selectionIsBackward(this);\n            };\n        } else {\n            selectionIsBackward = selProto.isBackward = function() {\n                return false;\n            };\n        }\n\n        // Create an alias for backwards compatibility. From 1.3, everything is \"backward\" rather than \"backwards\"\n        selProto.isBackwards = selProto.isBackward;\n\n        // Selection stringifier\n        // This is conformant to the old HTML5 selections draft spec but differs from WebKit and Mozilla's implementation.\n        // The current spec does not yet define this method.\n        selProto.toString = function() {\n            var rangeTexts = [];\n            for (var i = 0, len = this.rangeCount; i < len; ++i) {\n                rangeTexts[i] = \"\" + this._ranges[i];\n            }\n            return rangeTexts.join(\"\");\n        };\n\n        function assertNodeInSameDocument(sel, node) {\n            if (sel.win.document != getDocument(node)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n        }\n\n        // No current browser conforms fully to the spec for this method, so Rangy's own method is always used\n        selProto.collapse = function(node, offset) {\n            assertNodeInSameDocument(this, node);\n            var range = api.createRange(node);\n            range.collapseToPoint(node, offset);\n            this.setSingleRange(range);\n            this.isCollapsed = true;\n        };\n\n        selProto.collapseToStart = function() {\n            if (this.rangeCount) {\n                var range = this._ranges[0];\n                this.collapse(range.startContainer, range.startOffset);\n            } else {\n                throw new DOMException(\"INVALID_STATE_ERR\");\n            }\n        };\n\n        selProto.collapseToEnd = function() {\n            if (this.rangeCount) {\n                var range = this._ranges[this.rangeCount - 1];\n                this.collapse(range.endContainer, range.endOffset);\n            } else {\n                throw new DOMException(\"INVALID_STATE_ERR\");\n            }\n        };\n\n        // The spec is very specific on how selectAllChildren should be implemented so the native implementation is\n        // never used by Rangy.\n        selProto.selectAllChildren = function(node) {\n            assertNodeInSameDocument(this, node);\n            var range = api.createRange(node);\n            range.selectNodeContents(node);\n            this.setSingleRange(range);\n        };\n\n        selProto.deleteFromDocument = function() {\n            // Sepcial behaviour required for IE's control selections\n            if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {\n                var controlRange = this.docSelection.createRange();\n                var element;\n                while (controlRange.length) {\n                    element = controlRange.item(0);\n                    controlRange.remove(element);\n                    element.parentNode.removeChild(element);\n                }\n                this.refresh();\n            } else if (this.rangeCount) {\n                var ranges = this.getAllRanges();\n                if (ranges.length) {\n                    this.removeAllRanges();\n                    for (var i = 0, len = ranges.length; i < len; ++i) {\n                        ranges[i].deleteContents();\n                    }\n                    // The spec says nothing about what the selection should contain after calling deleteContents on each\n                    // range. Firefox moves the selection to where the final selected range was, so we emulate that\n                    this.addRange(ranges[len - 1]);\n                }\n            }\n        };\n\n        // The following are non-standard extensions\n        selProto.eachRange = function(func, returnValue) {\n            for (var i = 0, len = this._ranges.length; i < len; ++i) {\n                if ( func( this.getRangeAt(i) ) ) {\n                    return returnValue;\n                }\n            }\n        };\n\n        selProto.getAllRanges = function() {\n            var ranges = [];\n            this.eachRange(function(range) {\n                ranges.push(range);\n            });\n            return ranges;\n        };\n\n        selProto.setSingleRange = function(range, direction) {\n            this.removeAllRanges();\n            this.addRange(range, direction);\n        };\n\n        selProto.callMethodOnEachRange = function(methodName, params) {\n            var results = [];\n            this.eachRange( function(range) {\n                results.push( range[methodName].apply(range, params) );\n            } );\n            return results;\n        };\n        \n        function createStartOrEndSetter(isStart) {\n            return function(node, offset) {\n                var range;\n                if (this.rangeCount) {\n                    range = this.getRangeAt(0);\n                    range[\"set\" + (isStart ? \"Start\" : \"End\")](node, offset);\n                } else {\n                    range = api.createRange(this.win.document);\n                    range.setStartAndEnd(node, offset);\n                }\n                this.setSingleRange(range, this.isBackward());\n            };\n        }\n\n        selProto.setStart = createStartOrEndSetter(true);\n        selProto.setEnd = createStartOrEndSetter(false);\n        \n        // Add select() method to Range prototype. Any existing selection will be removed.\n        api.rangePrototype.select = function(direction) {\n            getSelection( this.getDocument() ).setSingleRange(this, direction);\n        };\n\n        selProto.changeEachRange = function(func) {\n            var ranges = [];\n            var backward = this.isBackward();\n\n            this.eachRange(function(range) {\n                func(range);\n                ranges.push(range);\n            });\n\n            this.removeAllRanges();\n            if (backward && ranges.length == 1) {\n                this.addRange(ranges[0], \"backward\");\n            } else {\n                this.setRanges(ranges);\n            }\n        };\n\n        selProto.containsNode = function(node, allowPartial) {\n            return this.eachRange( function(range) {\n                return range.containsNode(node, allowPartial);\n            }, true ) || false;\n        };\n\n        selProto.getBookmark = function(containerNode) {\n            return {\n                backward: this.isBackward(),\n                rangeBookmarks: this.callMethodOnEachRange(\"getBookmark\", [containerNode])\n            };\n        };\n\n        selProto.moveToBookmark = function(bookmark) {\n            var selRanges = [];\n            for (var i = 0, rangeBookmark, range; rangeBookmark = bookmark.rangeBookmarks[i++]; ) {\n                range = api.createRange(this.win);\n                range.moveToBookmark(rangeBookmark);\n                selRanges.push(range);\n            }\n            if (bookmark.backward) {\n                this.setSingleRange(selRanges[0], \"backward\");\n            } else {\n                this.setRanges(selRanges);\n            }\n        };\n\n        selProto.toHtml = function() {\n            var rangeHtmls = [];\n            this.eachRange(function(range) {\n                rangeHtmls.push( DomRange.toHtml(range) );\n            });\n            return rangeHtmls.join(\"\");\n        };\n\n        if (features.implementsTextRange) {\n            selProto.getNativeTextRange = function() {\n                var sel, textRange;\n                if ( (sel = this.docSelection) ) {\n                    var range = sel.createRange();\n                    if (isTextRange(range)) {\n                        return range;\n                    } else {\n                        throw module.createError(\"getNativeTextRange: selection is a control selection\"); \n                    }\n                } else if (this.rangeCount > 0) {\n                    return api.WrappedTextRange.rangeToTextRange( this.getRangeAt(0) );\n                } else {\n                    throw module.createError(\"getNativeTextRange: selection contains no range\");\n                }\n            };\n        }\n\n        function inspect(sel) {\n            var rangeInspects = [];\n            var anchor = new DomPosition(sel.anchorNode, sel.anchorOffset);\n            var focus = new DomPosition(sel.focusNode, sel.focusOffset);\n            var name = (typeof sel.getName == \"function\") ? sel.getName() : \"Selection\";\n\n            if (typeof sel.rangeCount != \"undefined\") {\n                for (var i = 0, len = sel.rangeCount; i < len; ++i) {\n                    rangeInspects[i] = DomRange.inspect(sel.getRangeAt(i));\n                }\n            }\n            return \"[\" + name + \"(Ranges: \" + rangeInspects.join(\", \") +\n                    \")(anchor: \" + anchor.inspect() + \", focus: \" + focus.inspect() + \"]\";\n        }\n\n        selProto.getName = function() {\n            return \"WrappedSelection\";\n        };\n\n        selProto.inspect = function() {\n            return inspect(this);\n        };\n\n        selProto.detach = function() {\n            actOnCachedSelection(this.win, \"delete\");\n            deleteProperties(this);\n        };\n\n        WrappedSelection.detachAll = function() {\n            actOnCachedSelection(null, \"deleteAll\");\n        };\n\n        WrappedSelection.inspect = inspect;\n        WrappedSelection.isDirectionBackward = isDirectionBackward;\n\n        api.Selection = WrappedSelection;\n\n        api.selectionPrototype = selProto;\n\n        api.addShimListener(function(win) {\n            if (typeof win.getSelection == \"undefined\") {\n                win.getSelection = function() {\n                    return getSelection(win);\n                };\n            }\n            win = null;\n        });\n    });\n    \n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Wait for document to load before initializing\n    var docReady = false;\n\n    var loadHandler = function(e) {\n        if (!docReady) {\n            docReady = true;\n            if (!api.initialized && api.config.autoInitialize) {\n                init();\n            }\n        }\n    };\n\n    if (isBrowser) {\n        // Test whether the document has already been loaded and initialize immediately if so\n        if (/^(?:complete|interactive)$/.test(document.readyState)) {\n            loadHandler();\n        } else {\n            if (isHostMethod(document, \"addEventListener\")) {\n                document.addEventListener(\"DOMContentLoaded\", loadHandler, false);\n            }\n\n            // Add a fallback in case the DOMContentLoaded event isn't supported\n            addListener(window, \"load\", loadHandler);\n        }\n    }\n\n    return api;\n}, /* build:replaceWithGlobalObject */this/* build:replaceWithGlobalObjectEnd */);"
  },
  {
    "path": "public/assets/js/source/util--scrollbar.js",
    "content": "/* Copyright (c) 2012, 2014 Hyunje Alex Jun and other contributors\n * Licensed under the MIT License\n */\n(function (factory) {\n  'use strict';\n\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS\n    factory(require('jquery'));\n  } else {\n    // Browser globals\n    factory(jQuery);\n  }\n})(function ($) {\n  'use strict';\n\n  function getInt(x) {\n    if (typeof x === 'string') {\n      return parseInt(x, 10);\n    } else {\n      return ~~x;\n    }\n  }\n\n  var defaultSettings = {\n    wheelSpeed: 1,\n    wheelPropagation: false,\n    swipePropagation: true,\n    minScrollbarLength: null,\n    maxScrollbarLength: null,\n    useBothWheelAxes: false,\n    useKeyboard: true,\n    suppressScrollX: false,\n    suppressScrollY: false,\n    scrollXMarginOffset: 0,\n    scrollYMarginOffset: 0,\n    includePadding: false\n  };\n\n  var incrementingId = 0;\n  var eventClassFactory = function () {\n    var id = incrementingId++;\n    return function (eventName) {\n      var className = '.perfect-scrollbar-' + id;\n      if (typeof eventName === 'undefined') {\n        return className;\n      } else {\n        return eventName + className;\n      }\n    };\n  };\n\n  var isWebkit = 'WebkitAppearance' in document.documentElement.style;\n\n  $.fn.perfectScrollbar = function (suppliedSettings, option) {\n\n    return this.each(function () {\n      var settings = $.extend(true, {}, defaultSettings);\n      var $this = $(this);\n      var isPluginAlive = function () { return !!$this; };\n\n      if (typeof suppliedSettings === \"object\") {\n        // Override default settings with any supplied\n        $.extend(true, settings, suppliedSettings);\n      } else {\n        // If no setting was supplied, then the first param must be the option\n        option = suppliedSettings;\n      }\n\n      // Catch options\n      if (option === 'update') {\n        if ($this.data('perfect-scrollbar-update')) {\n          $this.data('perfect-scrollbar-update')();\n        }\n        return $this;\n      }\n      else if (option === 'destroy') {\n        if ($this.data('perfect-scrollbar-destroy')) {\n          $this.data('perfect-scrollbar-destroy')();\n        }\n        return $this;\n      }\n\n      if ($this.data('perfect-scrollbar')) {\n        // if there's already perfect-scrollbar\n        return $this.data('perfect-scrollbar');\n      }\n\n\n      // Or generate new perfectScrollbar\n\n      $this.addClass('ps-container');\n\n      var containerWidth;\n      var containerHeight;\n      var contentWidth;\n      var contentHeight;\n\n      var isRtl = $this.css('direction') === \"rtl\";\n      var eventClass = eventClassFactory();\n      var ownerDocument = this.ownerDocument || document;\n\n      var $scrollbarXRail = $(\"<div class='ps-scrollbar-x-rail'>\").appendTo($this);\n      var $scrollbarX = $(\"<div class='ps-scrollbar-x'>\").appendTo($scrollbarXRail);\n      var scrollbarXActive;\n      var scrollbarXWidth;\n      var scrollbarXLeft;\n      var scrollbarXBottom = getInt($scrollbarXRail.css('bottom'));\n      var isScrollbarXUsingBottom = scrollbarXBottom === scrollbarXBottom; // !isNaN\n      var scrollbarXTop = isScrollbarXUsingBottom ? null : getInt($scrollbarXRail.css('top'));\n      var railBorderXWidth = getInt($scrollbarXRail.css('borderLeftWidth')) + getInt($scrollbarXRail.css('borderRightWidth'));\n      var railXMarginWidth = getInt($scrollbarXRail.css('marginLeft')) + getInt($scrollbarXRail.css('marginRight'));\n      var railXWidth;\n\n      var $scrollbarYRail = $(\"<div class='ps-scrollbar-y-rail'>\").appendTo($this);\n      var $scrollbarY = $(\"<div class='ps-scrollbar-y'>\").appendTo($scrollbarYRail);\n      var scrollbarYActive;\n      var scrollbarYHeight;\n      var scrollbarYTop;\n      var scrollbarYRight = getInt($scrollbarYRail.css('right'));\n      var isScrollbarYUsingRight = scrollbarYRight === scrollbarYRight; // !isNaN\n      var scrollbarYLeft = isScrollbarYUsingRight ? null : getInt($scrollbarYRail.css('left'));\n      var railBorderYWidth = getInt($scrollbarYRail.css('borderTopWidth')) + getInt($scrollbarYRail.css('borderBottomWidth'));\n      var railYMarginHeight = getInt($scrollbarYRail.css('marginTop')) + getInt($scrollbarYRail.css('marginBottom'));\n      var railYHeight;\n\n      function updateScrollTop(currentTop, deltaY) {\n        var newTop = currentTop + deltaY;\n        var maxTop = containerHeight - scrollbarYHeight;\n\n        if (newTop < 0) {\n          scrollbarYTop = 0;\n        } else if (newTop > maxTop) {\n          scrollbarYTop = maxTop;\n        } else {\n          scrollbarYTop = newTop;\n        }\n\n        var scrollTop = getInt(scrollbarYTop * (contentHeight - containerHeight) / (containerHeight - scrollbarYHeight));\n        $this.scrollTop(scrollTop);\n      }\n\n      function updateScrollLeft(currentLeft, deltaX) {\n        var newLeft = currentLeft + deltaX;\n        var maxLeft = containerWidth - scrollbarXWidth;\n\n        if (newLeft < 0) {\n          scrollbarXLeft = 0;\n        } else if (newLeft > maxLeft) {\n          scrollbarXLeft = maxLeft;\n        } else {\n          scrollbarXLeft = newLeft;\n        }\n\n        var scrollLeft = getInt(scrollbarXLeft * (contentWidth - containerWidth) / (containerWidth - scrollbarXWidth));\n        $this.scrollLeft(scrollLeft);\n      }\n\n      function getThumbSize(thumbSize) {\n        if (settings.minScrollbarLength) {\n          thumbSize = Math.max(thumbSize, settings.minScrollbarLength);\n        }\n        if (settings.maxScrollbarLength) {\n          thumbSize = Math.min(thumbSize, settings.maxScrollbarLength);\n        }\n        return thumbSize;\n      }\n\n      function updateCss() {\n        var xRailOffset = {width: railXWidth};\n        if (isRtl) {\n          xRailOffset.left = $this.scrollLeft() + containerWidth - contentWidth;\n        } else {\n          xRailOffset.left = $this.scrollLeft();\n        }\n        if (isScrollbarXUsingBottom) {\n          xRailOffset.bottom = scrollbarXBottom - $this.scrollTop();\n        } else {\n          xRailOffset.top = scrollbarXTop + $this.scrollTop();\n        }\n        $scrollbarXRail.css(xRailOffset);\n\n        var railYOffset = {top: $this.scrollTop(), height: railYHeight};\n\n        if (isScrollbarYUsingRight) {\n          if (isRtl) {\n            railYOffset.right = contentWidth - $this.scrollLeft() - scrollbarYRight - $scrollbarY.outerWidth();\n          } else {\n            railYOffset.right = scrollbarYRight - $this.scrollLeft();\n          }\n        } else {\n          if (isRtl) {\n            railYOffset.left = $this.scrollLeft() + containerWidth * 2 - contentWidth - scrollbarYLeft - $scrollbarY.outerWidth();\n          } else {\n            railYOffset.left = scrollbarYLeft + $this.scrollLeft();\n          }\n        }\n        $scrollbarYRail.css(railYOffset);\n\n        $scrollbarX.css({left: scrollbarXLeft, width: scrollbarXWidth - railBorderXWidth});\n        $scrollbarY.css({top: scrollbarYTop, height: scrollbarYHeight - railBorderYWidth});\n      }\n\n      function updateGeometry() {\n        // Hide scrollbars not to affect scrollWidth and scrollHeight\n        $this.removeClass('ps-active-x');\n        $this.removeClass('ps-active-y');\n\n        containerWidth = settings.includePadding ? $this.innerWidth() : $this.width();\n        containerHeight = settings.includePadding ? $this.innerHeight() : $this.height();\n        contentWidth = $this.prop('scrollWidth');\n        contentHeight = $this.prop('scrollHeight');\n\n        if (!settings.suppressScrollX && containerWidth + settings.scrollXMarginOffset < contentWidth) {\n          scrollbarXActive = true;\n          railXWidth = containerWidth - railXMarginWidth;\n          scrollbarXWidth = getThumbSize(getInt(railXWidth * containerWidth / contentWidth));\n          scrollbarXLeft = getInt($this.scrollLeft() * (railXWidth - scrollbarXWidth) / (contentWidth - containerWidth));\n        } else {\n          scrollbarXActive = false;\n          scrollbarXWidth = 0;\n          scrollbarXLeft = 0;\n          $this.scrollLeft(0);\n        }\n\n        if (!settings.suppressScrollY && containerHeight + settings.scrollYMarginOffset < contentHeight) {\n          scrollbarYActive = true;\n          railYHeight = containerHeight - railYMarginHeight;\n          scrollbarYHeight = getThumbSize(getInt(railYHeight * containerHeight / contentHeight));\n          scrollbarYTop = getInt($this.scrollTop() * (railYHeight - scrollbarYHeight) / (contentHeight - containerHeight));\n        } else {\n          scrollbarYActive = false;\n          scrollbarYHeight = 0;\n          scrollbarYTop = 0;\n          $this.scrollTop(0);\n        }\n\n        if (scrollbarXLeft >= railXWidth - scrollbarXWidth) {\n          scrollbarXLeft = railXWidth - scrollbarXWidth;\n        }\n        if (scrollbarYTop >= railYHeight - scrollbarYHeight) {\n          scrollbarYTop = railYHeight - scrollbarYHeight;\n        }\n\n        updateCss();\n\n        if (scrollbarXActive) {\n          $this.addClass('ps-active-x');\n        }\n        if (scrollbarYActive) {\n          $this.addClass('ps-active-y');\n        }\n      }\n\n      function bindMouseScrollXHandler() {\n        var currentLeft;\n        var currentPageX;\n\n        var mouseMoveHandler = function (e) {\n          updateScrollLeft(currentLeft, e.pageX - currentPageX);\n          updateGeometry();\n          e.stopPropagation();\n          e.preventDefault();\n        };\n\n        var mouseUpHandler = function (e) {\n          $scrollbarXRail.removeClass('in-scrolling');\n          $(ownerDocument).unbind(eventClass('mousemove'), mouseMoveHandler);\n        };\n\n        $scrollbarX.bind(eventClass('mousedown'), function (e) {\n          currentPageX = e.pageX;\n          currentLeft = $scrollbarX.position().left;\n          $scrollbarXRail.addClass('in-scrolling');\n\n          $(ownerDocument).bind(eventClass('mousemove'), mouseMoveHandler);\n          $(ownerDocument).one(eventClass('mouseup'), mouseUpHandler);\n\n          e.stopPropagation();\n          e.preventDefault();\n        });\n\n        currentLeft =\n        currentPageX = null;\n      }\n\n      function bindMouseScrollYHandler() {\n        var currentTop;\n        var currentPageY;\n\n        var mouseMoveHandler = function (e) {\n          updateScrollTop(currentTop, e.pageY - currentPageY);\n          updateGeometry();\n          e.stopPropagation();\n          e.preventDefault();\n        };\n\n        var mouseUpHandler = function (e) {\n          $scrollbarYRail.removeClass('in-scrolling');\n          $(ownerDocument).unbind(eventClass('mousemove'), mouseMoveHandler);\n        };\n\n        $scrollbarY.bind(eventClass('mousedown'), function (e) {\n          currentPageY = e.pageY;\n          currentTop = $scrollbarY.position().top;\n          $scrollbarYRail.addClass('in-scrolling');\n\n          $(ownerDocument).bind(eventClass('mousemove'), mouseMoveHandler);\n          $(ownerDocument).one(eventClass('mouseup'), mouseUpHandler);\n\n          e.stopPropagation();\n          e.preventDefault();\n        });\n\n        currentTop =\n        currentPageY = null;\n      }\n\n      function shouldPreventWheel(deltaX, deltaY) {\n        var scrollTop = $this.scrollTop();\n        if (deltaX === 0) {\n          if (!scrollbarYActive) {\n            return false;\n          }\n          if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= contentHeight - containerHeight && deltaY < 0)) {\n            return !settings.wheelPropagation;\n          }\n        }\n\n        var scrollLeft = $this.scrollLeft();\n        if (deltaY === 0) {\n          if (!scrollbarXActive) {\n            return false;\n          }\n          if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= contentWidth - containerWidth && deltaX > 0)) {\n            return !settings.wheelPropagation;\n          }\n        }\n        return true;\n      }\n\n      function shouldPreventSwipe(deltaX, deltaY) {\n        var scrollTop = $this.scrollTop();\n        var scrollLeft = $this.scrollLeft();\n        var magnitudeX = Math.abs(deltaX);\n        var magnitudeY = Math.abs(deltaY);\n\n        if (magnitudeY > magnitudeX) {\n          // user is perhaps trying to swipe up/down the page\n\n          if (((deltaY < 0) && (scrollTop === contentHeight - containerHeight)) ||\n              ((deltaY > 0) && (scrollTop === 0))) {\n            return !settings.swipePropagation;\n          }\n        } else if (magnitudeX > magnitudeY) {\n          // user is perhaps trying to swipe left/right across the page\n\n          if (((deltaX < 0) && (scrollLeft === contentWidth - containerWidth)) ||\n              ((deltaX > 0) && (scrollLeft === 0))) {\n            return !settings.swipePropagation;\n          }\n        }\n\n        return true;\n      }\n\n      function bindMouseWheelHandler() {\n        var shouldPrevent = false;\n\n        function getDeltaFromEvent(e) {\n          var deltaX = e.originalEvent.deltaX;\n          var deltaY = -1 * e.originalEvent.deltaY;\n\n          if (typeof deltaX === \"undefined\" || typeof deltaY === \"undefined\") {\n            // OS X Safari\n            deltaX = -1 * e.originalEvent.wheelDeltaX / 6;\n            deltaY = e.originalEvent.wheelDeltaY / 6;\n          }\n\n          if (e.originalEvent.deltaMode && e.originalEvent.deltaMode === 1) {\n            // Firefox in deltaMode 1: Line scrolling\n            deltaX *= 10;\n            deltaY *= 10;\n          }\n\n          if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {\n            // IE in some mouse drivers\n            deltaX = 0;\n            deltaY = e.originalEvent.wheelDelta;\n          }\n\n          return [deltaX, deltaY];\n        }\n\n        function mousewheelHandler(e) {\n          // FIXME: this is a quick fix for the select problem in FF and IE.\n          // If there comes an effective way to deal with the problem,\n          // this lines should be removed.\n          if (!isWebkit && $this.find('select:focus').length > 0) {\n            return;\n          }\n\n          var delta = getDeltaFromEvent(e);\n\n          var deltaX = delta[0];\n          var deltaY = delta[1];\n\n          shouldPrevent = false;\n          if (!settings.useBothWheelAxes) {\n            // deltaX will only be used for horizontal scrolling and deltaY will\n            // only be used for vertical scrolling - this is the default\n            $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));\n            $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));\n          } else if (scrollbarYActive && !scrollbarXActive) {\n            // only vertical scrollbar is active and useBothWheelAxes option is\n            // active, so let's scroll vertical bar using both mouse wheel axes\n            if (deltaY) {\n              $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));\n            } else {\n              $this.scrollTop($this.scrollTop() + (deltaX * settings.wheelSpeed));\n            }\n            shouldPrevent = true;\n          } else if (scrollbarXActive && !scrollbarYActive) {\n            // useBothWheelAxes and only horizontal bar is active, so use both\n            // wheel axes for horizontal bar\n            if (deltaX) {\n              $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));\n            } else {\n              $this.scrollLeft($this.scrollLeft() - (deltaY * settings.wheelSpeed));\n            }\n            shouldPrevent = true;\n          }\n\n          updateGeometry();\n\n          shouldPrevent = (shouldPrevent || shouldPreventWheel(deltaX, deltaY));\n          if (shouldPrevent) {\n            e.stopPropagation();\n            e.preventDefault();\n          }\n        }\n\n        if (typeof window.onwheel !== \"undefined\") {\n          $this.bind(eventClass('wheel'), mousewheelHandler);\n        } else if (typeof window.onmousewheel !== \"undefined\") {\n          $this.bind(eventClass('mousewheel'), mousewheelHandler);\n        }\n      }\n\n      function bindKeyboardHandler() {\n        var hovered = false;\n        $this.bind(eventClass('mouseenter'), function (e) {\n          hovered = true;\n        });\n        $this.bind(eventClass('mouseleave'), function (e) {\n          hovered = false;\n        });\n\n        var shouldPrevent = false;\n        $(ownerDocument).bind(eventClass('keydown'), function (e) {\n          if (e.isDefaultPrevented && e.isDefaultPrevented()) {\n            return;\n          }\n\n          if (!hovered) {\n            return;\n          }\n\n          var activeElement = document.activeElement ? document.activeElement : ownerDocument.activeElement;\n          // go deeper if element is a webcomponent\n          while (activeElement.shadowRoot) {\n            activeElement = activeElement.shadowRoot.activeElement;\n          }\n          if ($(activeElement).is(\":input,[contenteditable]\")) {\n            return;\n          }\n\n          var deltaX = 0;\n          var deltaY = 0;\n\n          switch (e.which) {\n          case 37: // left\n            deltaX = -30;\n            break;\n          case 38: // up\n            deltaY = 30;\n            break;\n          case 39: // right\n            deltaX = 30;\n            break;\n          case 40: // down\n            deltaY = -30;\n            break;\n          case 33: // page up\n            deltaY = 90;\n            break;\n          case 32: // space bar\n          case 34: // page down\n            deltaY = -90;\n            break;\n          case 35: // end\n            if (e.ctrlKey) {\n              deltaY = -contentHeight;\n            } else {\n              deltaY = -containerHeight;\n            }\n            break;\n          case 36: // home\n            if (e.ctrlKey) {\n              deltaY = $this.scrollTop();\n            } else {\n              deltaY = containerHeight;\n            }\n            break;\n          default:\n            return;\n          }\n\n          $this.scrollTop($this.scrollTop() - deltaY);\n          $this.scrollLeft($this.scrollLeft() + deltaX);\n\n          shouldPrevent = shouldPreventWheel(deltaX, deltaY);\n          if (shouldPrevent) {\n            e.preventDefault();\n          }\n        });\n      }\n\n      function bindRailClickHandler() {\n        function stopPropagation(e) { e.stopPropagation(); }\n\n        $scrollbarY.bind(eventClass('click'), stopPropagation);\n        $scrollbarYRail.bind(eventClass('click'), function (e) {\n          var halfOfScrollbarLength = getInt(scrollbarYHeight / 2);\n          var positionTop = e.pageY - $scrollbarYRail.offset().top - halfOfScrollbarLength;\n          var maxPositionTop = containerHeight - scrollbarYHeight;\n          var positionRatio = positionTop / maxPositionTop;\n\n          if (positionRatio < 0) {\n            positionRatio = 0;\n          } else if (positionRatio > 1) {\n            positionRatio = 1;\n          }\n\n          $this.scrollTop((contentHeight - containerHeight) * positionRatio);\n        });\n\n        $scrollbarX.bind(eventClass('click'), stopPropagation);\n        $scrollbarXRail.bind(eventClass('click'), function (e) {\n          var halfOfScrollbarLength = getInt(scrollbarXWidth / 2);\n          var positionLeft = e.pageX - $scrollbarXRail.offset().left - halfOfScrollbarLength;\n          var maxPositionLeft = containerWidth - scrollbarXWidth;\n          var positionRatio = positionLeft / maxPositionLeft;\n\n          if (positionRatio < 0) {\n            positionRatio = 0;\n          } else if (positionRatio > 1) {\n            positionRatio = 1;\n          }\n\n          $this.scrollLeft((contentWidth - containerWidth) * positionRatio);\n        });\n      }\n\n      function bindSelectionHandler() {\n        function getRangeNode() {\n          var selection = window.getSelection ? window.getSelection() :\n                          document.getSlection ? document.getSlection() : {rangeCount: 0};\n          if (selection.rangeCount === 0) {\n            return null;\n          } else {\n            return selection.getRangeAt(0).commonAncestorContainer;\n          }\n        }\n\n        var scrollingLoop = null;\n        var scrollDiff = {top: 0, left: 0};\n        function startScrolling() {\n          if (!scrollingLoop) {\n            scrollingLoop = setInterval(function () {\n              if (!isPluginAlive()) {\n                clearInterval(scrollingLoop);\n                return;\n              }\n\n              $this.scrollTop($this.scrollTop() + scrollDiff.top);\n              $this.scrollLeft($this.scrollLeft() + scrollDiff.left);\n              updateGeometry();\n            }, 50); // every .1 sec\n          }\n        }\n        function stopScrolling() {\n          if (scrollingLoop) {\n            clearInterval(scrollingLoop);\n            scrollingLoop = null;\n          }\n          $scrollbarXRail.removeClass('in-scrolling');\n          $scrollbarYRail.removeClass('in-scrolling');\n        }\n\n        var isSelected = false;\n        $(ownerDocument).bind(eventClass('selectionchange'), function (e) {\n          if ($.contains($this[0], getRangeNode())) {\n            isSelected = true;\n          } else {\n            isSelected = false;\n            stopScrolling();\n          }\n        });\n        $(window).bind(eventClass('mouseup'), function (e) {\n          if (isSelected) {\n            isSelected = false;\n            stopScrolling();\n          }\n        });\n\n        $(window).bind(eventClass('mousemove'), function (e) {\n          if (isSelected) {\n            var mousePosition = {x: e.pageX, y: e.pageY};\n            var containerOffset = $this.offset();\n            var containerGeometry = {\n              left: containerOffset.left,\n              right: containerOffset.left + $this.outerWidth(),\n              top: containerOffset.top,\n              bottom: containerOffset.top + $this.outerHeight()\n            };\n\n            if (mousePosition.x < containerGeometry.left + 3) {\n              scrollDiff.left = -5;\n              $scrollbarXRail.addClass('in-scrolling');\n            } else if (mousePosition.x > containerGeometry.right - 3) {\n              scrollDiff.left = 5;\n              $scrollbarXRail.addClass('in-scrolling');\n            } else {\n              scrollDiff.left = 0;\n            }\n\n            if (mousePosition.y < containerGeometry.top + 3) {\n              if (containerGeometry.top + 3 - mousePosition.y < 5) {\n                scrollDiff.top = -5;\n              } else {\n                scrollDiff.top = -20;\n              }\n              $scrollbarYRail.addClass('in-scrolling');\n            } else if (mousePosition.y > containerGeometry.bottom - 3) {\n              if (mousePosition.y - containerGeometry.bottom + 3 < 5) {\n                scrollDiff.top = 5;\n              } else {\n                scrollDiff.top = 20;\n              }\n              $scrollbarYRail.addClass('in-scrolling');\n            } else {\n              scrollDiff.top = 0;\n            }\n\n            if (scrollDiff.top === 0 && scrollDiff.left === 0) {\n              stopScrolling();\n            } else {\n              startScrolling();\n            }\n          }\n        });\n      }\n\n      function bindTouchHandler(supportsTouch, supportsIePointer) {\n        function applyTouchMove(differenceX, differenceY) {\n          $this.scrollTop($this.scrollTop() - differenceY);\n          $this.scrollLeft($this.scrollLeft() - differenceX);\n\n          updateGeometry();\n        }\n\n        var startOffset = {};\n        var startTime = 0;\n        var speed = {};\n        var easingLoop = null;\n        var inGlobalTouch = false;\n        var inLocalTouch = false;\n\n        function globalTouchStart(e) {\n          inGlobalTouch = true;\n        }\n        function globalTouchEnd(e) {\n          inGlobalTouch = false;\n        }\n\n        function getTouch(e) {\n          if (e.originalEvent.targetTouches) {\n            return e.originalEvent.targetTouches[0];\n          } else {\n            // Maybe IE pointer\n            return e.originalEvent;\n          }\n        }\n        function shouldHandle(e) {\n          var event = e.originalEvent;\n          if (event.targetTouches && event.targetTouches.length === 1) {\n            return true;\n          }\n          if (event.pointerType && event.pointerType !== 'mouse' && event.pointerType !== event.MSPOINTER_TYPE_MOUSE) {\n            return true;\n          }\n          return false;\n        }\n        function touchStart(e) {\n          if (shouldHandle(e)) {\n            inLocalTouch = true;\n\n            var touch = getTouch(e);\n\n            startOffset.pageX = touch.pageX;\n            startOffset.pageY = touch.pageY;\n\n            startTime = (new Date()).getTime();\n\n            if (easingLoop !== null) {\n              clearInterval(easingLoop);\n            }\n\n            e.stopPropagation();\n          }\n        }\n        function touchMove(e) {\n          if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {\n            var touch = getTouch(e);\n\n            var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};\n\n            var differenceX = currentOffset.pageX - startOffset.pageX;\n            var differenceY = currentOffset.pageY - startOffset.pageY;\n\n            applyTouchMove(differenceX, differenceY);\n            startOffset = currentOffset;\n\n            var currentTime = (new Date()).getTime();\n\n            var timeGap = currentTime - startTime;\n            if (timeGap > 0) {\n              speed.x = differenceX / timeGap;\n              speed.y = differenceY / timeGap;\n              startTime = currentTime;\n            }\n\n            if (shouldPreventSwipe(differenceX, differenceY)) {\n              e.stopPropagation();\n              e.preventDefault();\n            }\n          }\n        }\n        function touchEnd(e) {\n          if (!inGlobalTouch && inLocalTouch) {\n            inLocalTouch = false;\n\n            clearInterval(easingLoop);\n            easingLoop = setInterval(function () {\n              if (!isPluginAlive()) {\n                clearInterval(easingLoop);\n                return;\n              }\n\n              if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {\n                clearInterval(easingLoop);\n                return;\n              }\n\n              applyTouchMove(speed.x * 30, speed.y * 30);\n\n              speed.x *= 0.8;\n              speed.y *= 0.8;\n            }, 10);\n          }\n        }\n\n        if (supportsTouch) {\n          $(window).bind(eventClass(\"touchstart\"), globalTouchStart);\n          $(window).bind(eventClass(\"touchend\"), globalTouchEnd);\n          $this.bind(eventClass(\"touchstart\"), touchStart);\n          $this.bind(eventClass(\"touchmove\"), touchMove);\n          $this.bind(eventClass(\"touchend\"), touchEnd);\n        }\n\n        if (supportsIePointer) {\n          if (window.PointerEvent) {\n            $(window).bind(eventClass(\"pointerdown\"), globalTouchStart);\n            $(window).bind(eventClass(\"pointerup\"), globalTouchEnd);\n            $this.bind(eventClass(\"pointerdown\"), touchStart);\n            $this.bind(eventClass(\"pointermove\"), touchMove);\n            $this.bind(eventClass(\"pointerup\"), touchEnd);\n          } else if (window.MSPointerEvent) {\n            $(window).bind(eventClass(\"MSPointerDown\"), globalTouchStart);\n            $(window).bind(eventClass(\"MSPointerUp\"), globalTouchEnd);\n            $this.bind(eventClass(\"MSPointerDown\"), touchStart);\n            $this.bind(eventClass(\"MSPointerMove\"), touchMove);\n            $this.bind(eventClass(\"MSPointerUp\"), touchEnd);\n          }\n        }\n      }\n\n      function bindScrollHandler() {\n        $this.bind(eventClass('scroll'), function (e) {\n          updateGeometry();\n        });\n      }\n\n      function destroy() {\n        $this.unbind(eventClass());\n        $(window).unbind(eventClass());\n        $(ownerDocument).unbind(eventClass());\n        $this.data('perfect-scrollbar', null);\n        $this.data('perfect-scrollbar-update', null);\n        $this.data('perfect-scrollbar-destroy', null);\n        $scrollbarX.remove();\n        $scrollbarY.remove();\n        $scrollbarXRail.remove();\n        $scrollbarYRail.remove();\n\n        // clean all variables\n        $this =\n        $scrollbarXRail =\n        $scrollbarYRail =\n        $scrollbarX =\n        $scrollbarY =\n        scrollbarXActive =\n        scrollbarYActive =\n        containerWidth =\n        containerHeight =\n        contentWidth =\n        contentHeight =\n        scrollbarXWidth =\n        scrollbarXLeft =\n        scrollbarXBottom =\n        isScrollbarXUsingBottom =\n        scrollbarXTop =\n        scrollbarYHeight =\n        scrollbarYTop =\n        scrollbarYRight =\n        isScrollbarYUsingRight =\n        scrollbarYLeft =\n        isRtl =\n        eventClass = null;\n      }\n\n      var supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);\n      var supportsIePointer = window.navigator.msMaxTouchPoints !== null;\n\n      function initialize() {\n        updateGeometry();\n        bindScrollHandler();\n        bindMouseScrollXHandler();\n        bindMouseScrollYHandler();\n        bindRailClickHandler();\n        bindSelectionHandler();\n        bindMouseWheelHandler();\n\n        if (supportsTouch || supportsIePointer) {\n          bindTouchHandler(supportsTouch, supportsIePointer);\n        }\n        if (settings.useKeyboard) {\n          bindKeyboardHandler();\n        }\n        $this.data('perfect-scrollbar', $this);\n        $this.data('perfect-scrollbar-update', updateGeometry);\n        $this.data('perfect-scrollbar-destroy', destroy);\n      }\n\n      initialize();\n\n      return $this;\n    });\n  };\n});\n"
  },
  {
    "path": "public/assets/js/source/util--slider.js",
    "content": "/**\n *   Unslider by @idiot\n */\n\n(function($, f) {\n\t//  If there's no jQuery, Unslider can't work, so kill the operation.\n\tif(!$) return f;\n\n\tvar Unslider = function() {\n\t\t//  Set up our elements\n\t\tthis.el = f;\n\t\tthis.items = f;\n\n\t\t//  Dimensions\n\t\tthis.sizes = [];\n\t\tthis.max = [0,0];\n\n\t\t//  Current inded\n\t\tthis.current = 0;\n\n\t\t//  Start/stop timer\n\t\tthis.interval = f;\n\n\t\t//  Set some options\n\t\tthis.opts = {\n\t\t\tspeed: 500,\n\t\t\tdelay: 3000, // f for no autoplay\n\t\t\tcomplete: f, // when a slide's finished\n\t\t\tkeys: !f, // keyboard shortcuts - disable if it breaks things\n\t\t\tdots: f, // display â€¢â€¢â€¢â€¢oâ€¢ pagination\n\t\t\tfluid: f // is it a percentage width?,\n\t\t};\n\n\t\t//  Create a deep clone for methods where context changes\n\t\tvar _ = this;\n\n\t\tthis.init = function(el, opts) {\n\t\t\tthis.el = el;\n\t\t\tthis.ul = el.children('ul');\n\t\t\tthis.max = [el.outerWidth(), el.outerHeight()];\n\t\t\tthis.items = this.ul.children('li').each(this.calculate);\n\n\t\t\t//  Check whether we're passing any options in to Unslider\n\t\t\tthis.opts = $.extend(this.opts, opts);\n\n\t\t\t//  Set up the Unslider\n\t\t\tthis.setup();\n\n\t\t\treturn this;\n\t\t};\n\n\t\t//  Get the width for an element\n\t\t//  Pass a jQuery element as the context with .call(), and the index as a parameter: Unslider.calculate.call($('li:first'), 0)\n\t\tthis.calculate = function(index) {\n\t\t\tvar me = $(this),\n\t\t\t\twidth = me.outerWidth(), height = me.outerHeight();\n\n\t\t\t//  Add it to the sizes list\n\t\t\t_.sizes[index] = [width, height];\n\n\t\t\t//  Set the max values\n\t\t\tif(width > _.max[0]) _.max[0] = width;\n\t\t\tif(height > _.max[1]) _.max[1] = height;\n\t\t};\n\n\t\t//  Work out what methods need calling\n\t\tthis.setup = function() {\n\t\t\t//  Set the main element\n\t\t\tthis.el.css({\n\t\t\t\toverflow: 'hidden',\n\t\t\t\twidth: _.max[0],\n\t\t\t\theight: this.items.first().outerHeight()\n\t\t\t});\n\n\t\t\t//  Set the relative widths\n\t\t\tthis.ul.css({width: (this.items.length * 100) + '%', position: 'relative'});\n\t\t\tthis.items.css('width', (100 / this.items.length) + '%');\n\n\t\t\tif(this.opts.delay !== f) {\n\t\t\t\tthis.start();\n\t\t\t\tthis.el.hover(this.stop, this.start);\n\t\t\t}\n\n\t\t\t//  Custom keyboard support\n\t\t\tthis.opts.keys && $(document).keydown(this.keys);\n\n\t\t\t//  Dot pagination\n\t\t\tthis.opts.dots && this.dots();\n\n\t\t\t//  Little patch for fluid-width sliders. Screw those guys.\n\t\t\tif(this.opts.fluid) {\n\t\t\t\tvar resize = function() {\n\t\t\t\t\t_.el.css('width', Math.min(Math.round((_.el.outerWidth() / _.el.parent().outerWidth()) * 100), 100) + '%');\n\t\t\t\t};\n\n\t\t\t\tresize();\n\t\t\t\t$(window).resize(resize);\n\t\t\t}\n\n\t\t\tif(this.opts.arrows) {\n\t\t\t\tthis.el.parent().append('<p class=\"arrows\"><span class=\"prev\">â†</span><span class=\"next\">â†’</span></p>')\n\t\t\t\t\t.find('.arrows span').click(function() {\n\t\t\t\t\t\t$.isFunction(_[this.className]) && _[this.className]();\n\t\t\t\t\t});\n\t\t\t};\n\n\t\t\t//  Swipe support\n\t\t\tif($.event.swipe) {\n\t\t\t\tthis.el.on('swipeleft', _.prev).on('swiperight', _.next);\n\t\t\t}\n\t\t};\n\n\t\t//  Move Unslider to a slide index\n\t\tthis.move = function(index, cb) {\n\t\t\t//  If it's out of bounds, go to the first slide\n\t\t\tif(!this.items.eq(index).length) index = 0;\n\t\t\tif(index < 0) index = (this.items.length - 1);\n\n\t\t\tvar target = this.items.eq(index);\n\t\t\tvar obj = {height: target.outerHeight()};\n\t\t\tvar speed = cb ? 5 : this.opts.speed;\n\n\t\t\tif(!this.ul.is(':animated')) {\n\t\t\t\t//  Handle those pesky dots\n\t\t\t\t_.el.find('.dot:eq(' + index + ')').addClass('active').siblings().removeClass('active');\n\n\t\t\t\tthis.el.animate(obj, speed) && this.ul.animate($.extend({left: '-' + index + '00%'}, obj), speed, function(data) {\n\t\t\t\t\t_.current = index;\n\t\t\t\t\t$.isFunction(_.opts.complete) && !cb && _.opts.complete(_.el);\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\t//  Autoplay functionality\n\t\tthis.start = function() {\n\t\t\t_.interval = setInterval(function() {\n\t\t\t\t_.move(_.current + 1);\n\t\t\t}, _.opts.delay);\n\t\t};\n\n\t\t//  Stop autoplay\n\t\tthis.stop = function() {\n\t\t\t_.interval = clearInterval(_.interval);\n\t\t\treturn _;\n\t\t};\n\n\t\t//  Keypresses\n\t\tthis.keys = function(e) {\n\t\t\tvar key = e.which;\n\t\t\tvar map = {\n\t\t\t\t//  Prev/next\n\t\t\t\t37: _.prev,\n\t\t\t\t39: _.next,\n\n\t\t\t\t//  Esc\n\t\t\t\t27: _.stop\n\t\t\t};\n\n\t\t\tif($.isFunction(map[key])) {\n\t\t\t\tmap[key]();\n\t\t\t}\n\t\t};\n\n\t\t//  Arrow navigation\n\t\tthis.next = function() { return _.stop().move(_.current + 1) };\n\t\tthis.prev = function() { return _.stop().move(_.current - 1) };\n\n\t\tthis.dots = function() {\n\t\t\t//  Create the HTML\n\t\t\tvar html = '<ol class=\"dots\">';\n\t\t\t\t$.each(this.items, function(index) { html += '<li class=\"dot' + (index < 1 ? ' active' : '') + '\">' + (index + 1) + '</li>'; });\n\t\t\t\thtml += '</ol>';\n\n\t\t\t//  Add it to the Unslider\n\t\t\tthis.el.addClass('has-dots').append(html).find('.dot').click(function() {\n\t\t\t\t_.move($(this).index());\n\t\t\t});\n\t\t};\n\t};\n\n\t//  Create a jQuery plugin\n\t$.fn.unslider = function(o) {\n\t\tvar len = this.length;\n\n\t\t//  Enable multiple-slider support\n\t\treturn this.each(function(index) {\n\t\t\t//  Cache a copy of $(this), so it\n\t\t\tvar me = $(this);\n\t\t\tvar instance = (new Unslider).init(me, o);\n\n\t\t\t//  Invoke an Unslider instance\n\t\t\tme.data('unslider' + (len > 1 ? '-' + (index + 1) : ''), instance);\n\t\t});\n\t};\n})(window.jQuery, false);"
  },
  {
    "path": "public/assets/js/source/util--sweet-alert.js",
    "content": "// SweetAlert\n// 2014 (c) - Tristan Edwards\n// github.com/t4t5/sweetalert\n;(function(window, document) {\n\n  var modalClass   = '.sweet-alert',\n      overlayClass = '.sweet-overlay',\n      alertTypes   = ['error', 'warning', 'info', 'success'],\n      defaultParams = {\n        title: '',\n        text: '',\n        type: null,\n        allowOutsideClick: false,\n        showCancelButton: false,\n        closeOnConfirm: true,\n        closeOnCancel: true,\n        confirmButtonText: 'OK',\n        confirmButtonColor: '#AEDEF4',\n        cancelButtonText: lasso_editor.strings.cancel,\n        imageUrl: null,\n        imageSize: null,\n        timer: null\n      };\n\n\n  /*\n   * Manipulate DOM\n   */\n\n  var getModal = function() {\n      return document.querySelector(modalClass);\n    },\n    getOverlay = function() {\n      return document.querySelector(overlayClass);\n    },\n    hasClass = function(elem, className) {\n      return new RegExp(' ' + className + ' ').test(' ' + elem.className + ' ');\n    },\n    addClass = function(elem, className) {\n      if (!hasClass(elem, className)) {\n        elem.className += ' ' + className;\n      }\n    },\n    removeClass = function(elem, className) {\n      var newClass = ' ' + elem.className.replace(/[\\t\\r\\n]/g, ' ') + ' ';\n      if (hasClass(elem, className)) {\n        while (newClass.indexOf(' ' + className + ' ') >= 0) {\n          newClass = newClass.replace(' ' + className + ' ', ' ');\n        }\n        elem.className = newClass.replace(/^\\s+|\\s+$/g, '');\n      }\n    },\n    escapeHtml = function(str) {\n      var div = document.createElement('div');\n      div.appendChild(document.createTextNode(str));\n      return div.innerHTML;\n    },\n    _show = function(elem) {\n      elem.style.opacity = '';\n      elem.style.display = 'block';\n    },\n    show = function(elems) {\n      if (elems && !elems.length) {\n        return _show(elems);\n      }\n      for (var i = 0; i < elems.length; ++i) {\n        _show(elems[i]);\n      }\n    },\n    _hide = function(elem) {\n      elem.style.opacity = '';\n      elem.style.display = 'none';\n    },\n    hide = function(elems) {\n      if (elems && !elems.length) {\n        return _hide(elems);\n      }\n      for (var i = 0; i < elems.length; ++i) {\n        _hide(elems[i]);\n      }\n    },\n    isDescendant = function(parent, child) {\n      var node = child.parentNode;\n      while (node !== null) {\n        if (node === parent) {\n          return true;\n        }\n        node = node.parentNode;\n      }\n      return false;\n    },\n    getTopMargin = function(elem) {\n      elem.style.left = '-9999px';\n      elem.style.display = 'block';\n\n      var height = elem.clientHeight,\n          padding;\n      if (typeof getComputedStyle !== \"undefined\") { /* IE 8 */\n        padding = parseInt(getComputedStyle(elem).getPropertyValue('padding'), 10);\n      } else{\n        padding = parseInt(elem.currentStyle.padding);\n      }\n\n      elem.style.left = '';\n      elem.style.display = 'none';\n      return ('-' + parseInt(height / 2 + padding) + 'px');\n    },\n    fadeIn = function(elem, interval) {\n      if (+elem.style.opacity < 1) {\n        interval = interval || 16;\n        elem.style.opacity = 0;\n        elem.style.display = 'block';\n        var last = +new Date();\n        var tick = function() {\n          elem.style.opacity = +elem.style.opacity + (new Date() - last) / 100;\n          last = +new Date();\n\n          if (+elem.style.opacity < 1) {\n            setTimeout(tick, interval);\n          }\n        };\n        tick();\n      }\n      elem.style.display = 'block'; //fallback IE8\n    },\n    fadeOut = function(elem, interval) {\n      interval = interval || 16;\n      elem.style.opacity = 1;\n      var last = +new Date();\n      var tick = function() {\n        elem.style.opacity = +elem.style.opacity - (new Date() - last) / 100;\n        last = +new Date();\n\n        if (+elem.style.opacity > 0) {\n          setTimeout(tick, interval);\n        } else {\n          elem.style.display = 'none';\n        }\n      };\n      tick();\n    },\n    fireClick = function(node) {\n      // Taken from http://www.nonobtrusive.com/2011/11/29/programatically-fire-crossbrowser-click-event-with-javascript/\n      // Then fixed for today's Chrome browser.\n      if (MouseEvent) {\n        // Up-to-date approach\n        var mevt = new MouseEvent('click', {\n          view: window,\n          bubbles: false,\n          cancelable: true\n        });\n        node.dispatchEvent(mevt);\n      } else if ( document.createEvent ) {\n        // Fallback\n        var evt = document.createEvent('MouseEvents');\n        evt.initEvent('click', false, false);\n        node.dispatchEvent(evt);\n      } else if( document.createEventObject ) {\n        node.fireEvent('onclick') ;\n      } else if (typeof node.onclick === 'function' ) {\n        node.onclick();\n      }\n    },\n    stopEventPropagation = function(e) {\n      // In particular, make sure the space bar doesn't scroll the main window.\n      if (typeof e.stopPropagation === 'function') {\n        e.stopPropagation();\n        e.preventDefault();\n      } else if (window.event && window.event.hasOwnProperty('cancelBubble')) {\n        window.event.cancelBubble = true;\n      }\n    };\n\n  // Remember state in cases where opening and handling a modal will fiddle with it.\n  var previousActiveElement,\n      previousDocumentClick,\n      previousWindowKeyDown,\n      lastFocusedButton;\n\n  /*\n   * Add modal + overlay to DOM\n   */\n\n  window.sweetAlertInitialize = function() {\n    var sweetHTML = '<div class=\"sweet-overlay\" tabIndex=\"-1\"></div><div class=\"sweet-alert\" tabIndex=\"-1\"><div class=\"icon error\"><span class=\"x-mark\"><span class=\"line left\"></span><span class=\"line right\"></span></span></div><div class=\"icon warning\"> <span class=\"body\"></span> <span class=\"dot\"></span> </div> <div class=\"icon info\"></div> <div class=\"icon success\"> <span class=\"line tip\"></span> <span class=\"line long\"></span> <div class=\"placeholder\"></div> <div class=\"fix\"></div> </div> <div class=\"icon custom\"></div> <h2>Title</h2><p>Text</p><button class=\"cancel\" tabIndex=\"2\">'+lasso_editor.strings.cancel+'</button><button class=\"confirm\" tabIndex=\"1\">OK</button></div>',\n        sweetWrap = document.createElement('div');\n\n    sweetWrap.innerHTML = sweetHTML;\n\n    // For readability: check sweet-alert.html\n    document.body.appendChild(sweetWrap);\n  };\n\n  /*\n   * Global sweetAlert function\n   */\n\n  window.sweetAlert = window.swal = function() {\n    // Copy arguments to the local args variable\n    var args = arguments;\n    if (getModal() !== null) {\n        // If getModal returns values then continue\n        modalDependant.apply(this, args);\n    } else {\n        // If getModal returns null i.e. no matches, then set up a interval event to check the return value until it is not null\t\n        var modalCheckInterval = setInterval(function() {\n          if (getModal() !== null) {\n            clearInterval(modalCheckInterval);\n            modalDependant.apply(this, args);\n          }\n      }, 100);\n    }\n  };\n        \n  function modalDependant() {\n\n    if (arguments[0] === undefined) {\n      window.console.error('sweetAlert expects at least 1 attribute!');\n      return false;\n    }\n\n    var params = extend({}, defaultParams);\n\n    switch (typeof arguments[0]) {\n\n      case 'string':\n        params.title = arguments[0];\n        params.text  = arguments[1] || '';\n        params.type  = arguments[2] || '';\n\n        break;\n\n      case 'object':\n        if (arguments[0].title === undefined) {\n          window.console.error('Missing \"title\" argument!');\n          return false;\n        }\n\n        params.title              = arguments[0].title;\n        params.text               = arguments[0].text || defaultParams.text;\n        params.type               = arguments[0].type || defaultParams.type;\n        params.customClass        = arguments[0].customClass || params.customClass;\n        params.allowOutsideClick  = arguments[0].allowOutsideClick || defaultParams.allowOutsideClick;\n        params.showCancelButton   = arguments[0].showCancelButton !== undefined ? arguments[0].showCancelButton : defaultParams.showCancelButton;\n        params.closeOnConfirm     = arguments[0].closeOnConfirm !== undefined ? arguments[0].closeOnConfirm : defaultParams.closeOnConfirm;\n        params.closeOnCancel      = arguments[0].closeOnCancel !== undefined ? arguments[0].closeOnCancel : defaultParams.closeOnCancel;\n        params.timer              = arguments[0].timer || defaultParams.timer;\n\n        // Show \"Confirm\" instead of \"OK\" if cancel button is visible\n        params.confirmButtonText  = (defaultParams.showCancelButton) ? 'Confirm' : defaultParams.confirmButtonText;\n        params.confirmButtonText  = arguments[0].confirmButtonText || defaultParams.confirmButtonText;\n        params.confirmButtonColor = arguments[0].confirmButtonColor || defaultParams.confirmButtonColor;\n        params.cancelButtonText   = arguments[0].cancelButtonText || defaultParams.cancelButtonText;\n        params.imageUrl           = arguments[0].imageUrl || defaultParams.imageUrl;\n        params.imageSize          = arguments[0].imageSize || defaultParams.imageSize;\n        params.doneFunction       = arguments[1] || null;\n\n        break;\n\n      default:\n        window.console.error('Unexpected type of argument! Expected \"string\" or \"object\", got ' + typeof arguments[0]);\n        return false;\n\n    }\n\n    setParameters(params);\n    fixVerticalPosition();\n    openModal();\n\n\n    // Modal interactions\n    var modal = getModal();\n\n    // Mouse interactions\n    var onButtonEvent = function(event) {\n      var e = event || window.event;\n      var target = e.target || e.srcElement,\n          targetedConfirm    = (target.className === 'confirm'),\n          modalIsVisible     = hasClass(modal, 'visible'),\n          doneFunctionExists = (params.doneFunction && modal.getAttribute('data-has-done-function') === 'true');\n\n      switch (e.type) {\n        case (\"mouseover\"):\n          if (targetedConfirm) {\n            target.style.backgroundColor = colorLuminance(params.confirmButtonColor, -0.04);\n          }\n          break;\n        case (\"mouseout\"):\n          if (targetedConfirm) {\n            target.style.backgroundColor = params.confirmButtonColor;\n          }\n          break;\n        case (\"mousedown\"):\n          if (targetedConfirm) {\n            target.style.backgroundColor = colorLuminance(params.confirmButtonColor, -0.14);\n          }\n          break;\n        case (\"mouseup\"):\n          if (targetedConfirm) {\n            target.style.backgroundColor = colorLuminance(params.confirmButtonColor, -0.04);\n          }\n          break;\n        case (\"focus\"):\n          var $confirmButton = modal.querySelector('button.confirm'),\n              $cancelButton  = modal.querySelector('button.cancel');\n\n          if (targetedConfirm) {\n            $cancelButton.style.boxShadow = 'none';\n          } else {\n            $confirmButton.style.boxShadow = 'none';\n          }\n          break;\n        case (\"click\"):\n          if (targetedConfirm && doneFunctionExists && modalIsVisible) { // Clicked \"confirm\"\n\n            params.doneFunction(true);\n\n            if (params.closeOnConfirm) {\n              closeModal();\n            }\n          } else if (doneFunctionExists && modalIsVisible) { // Clicked \"cancel\"\n\n            // Check if callback function expects a parameter (to track cancel actions)\n            var functionAsStr          = String(params.doneFunction).replace(/\\s/g, '');\n            var functionHandlesCancel  = functionAsStr.substring(0, 9) === \"function(\" && functionAsStr.substring(9, 10) !== \")\";\n\n            if (functionHandlesCancel) {\n              params.doneFunction(false);\n            }\n\n            if (params.closeOnCancel) {\n              closeModal();\n            }\n          } else {\n            closeModal();\n          }\n\n          break;\n      }\n    };\n\n    var $buttons = modal.querySelectorAll('button');\n    for (var i = 0; i < $buttons.length; i++) {\n      $buttons[i].onclick     = onButtonEvent;\n      $buttons[i].onmouseover = onButtonEvent;\n      $buttons[i].onmouseout  = onButtonEvent;\n      $buttons[i].onmousedown = onButtonEvent;\n      //$buttons[i].onmouseup   = onButtonEvent;\n      $buttons[i].onfocus     = onButtonEvent;\n    }\n\n    // Remember the current document.onclick event.\n    previousDocumentClick = document.onclick;\n    document.onclick = function(event) {\n      var e = event || window.event;\n      var target = e.target || e.srcElement;\n\n      var clickedOnModal = (modal === target),\n          clickedOnModalChild = isDescendant(modal, target),\n          modalIsVisible = hasClass(modal, 'visible'),\n          outsideClickIsAllowed = modal.getAttribute('data-allow-ouside-click') === 'true';\n\n      if (!clickedOnModal && !clickedOnModalChild && modalIsVisible && outsideClickIsAllowed) {\n        closeModal();\n      }\n    };\n\n\n    // Keyboard interactions\n    var $okButton = modal.querySelector('button.confirm'),\n        $cancelButton = modal.querySelector('button.cancel'),\n        $modalButtons = modal.querySelectorAll('button:not([type=hidden])');\n\n\n    function handleKeyDown(event) {\n      var e = event || window.event;\n      var keyCode = e.keyCode || e.which;\n\n      if ([9,13,32,27].indexOf(keyCode) === -1) {\n        // Don't do work on keys we don't care about.\n        return;\n      }\n\n      var $targetElement = e.target || e.srcElement;\n\n      var btnIndex = -1; // Find the button - note, this is a nodelist, not an array.\n      for (var i = 0; i < $modalButtons.length; i++) {\n        if ($targetElement === $modalButtons[i]) {\n          btnIndex = i;\n          break;\n        }\n      }\n\n      if (keyCode === 9) {\n        // TAB\n        if (btnIndex === -1) {\n          // No button focused. Jump to the confirm button.\n          $targetElement = $okButton;\n        } else {\n          // Cycle to the next button\n          if (btnIndex === $modalButtons.length - 1) {\n            $targetElement = $modalButtons[0];\n          } else {\n            $targetElement = $modalButtons[btnIndex + 1];\n          }\n        }\n\n        stopEventPropagation(e);\n        $targetElement.focus();\n        setFocusStyle($targetElement, params.confirmButtonColor); // TODO\n\n      } else {\n        if (keyCode === 13 || keyCode === 32) {\n            if (btnIndex === -1) {\n              // ENTER/SPACE clicked outside of a button.\n              $targetElement = $okButton;\n            } else {\n              // Do nothing - let the browser handle it.\n              $targetElement = undefined;\n            }\n        } else if (keyCode === 27 && !($cancelButton.hidden || $cancelButton.style.display === 'none')) {\n          // ESC to cancel only if there's a cancel button displayed (like the alert() window).\n          $targetElement = $cancelButton;\n        } else {\n          // Fallback - let the browser handle it.\n          $targetElement = undefined;\n        }\n\n        if ($targetElement !== undefined) {\n          fireClick($targetElement, e);\n        }\n      }\n    }\n\n    previousWindowKeyDown = window.onkeydown;\n    window.onkeydown = handleKeyDown;\n\n    function handleOnBlur(event) {\n      var e = event || window.event;\n      var $targetElement = e.target || e.srcElement,\n          $focusElement = e.relatedTarget,\n          modalIsVisible = hasClass(modal, 'visible');\n\n      if (modalIsVisible) {\n        var btnIndex = -1; // Find the button - note, this is a nodelist, not an array.\n\n        if ($focusElement !== null) {\n          // If we picked something in the DOM to focus to, let's see if it was a button.\n          for (var i = 0; i < $modalButtons.length; i++) {\n            if ($focusElement === $modalButtons[i]) {\n              btnIndex = i;\n              break;\n            }\n          }\n\n          if (btnIndex === -1) {\n            // Something in the dom, but not a visible button. Focus back on the button.\n            //$targetElement.focus();\n          }\n        } else {\n          // Exiting the DOM (e.g. clicked in the URL bar);\n          lastFocusedButton = $targetElement;\n        }\n      }\n    }\n\n    $okButton.onblur = handleOnBlur;\n    $cancelButton.onblur = handleOnBlur;\n\n    /*window.onfocus = function() {\n      // When the user has focused away and focused back from the whole window.\n      window.setTimeout(function() {\n        // Put in a timeout to jump out of the event sequence. Calling focus() in the event\n        // sequence confuses things.\n        if (lastFocusedButton !== undefined) {\n          lastFocusedButton.focus();\n          lastFocusedButton = undefined;\n        }\n      }, 0);\n    };*/\n  }\n\n  /**\n   * Set default params for each popup\n   * @param {Object} userParams\n   */\n  window.swal.setDefaults = function(userParams) {\n    if (!userParams) {\n      throw new Error('userParams is required');\n    }\n    if (typeof userParams !== 'object') {\n      throw new Error('userParams has to be a object');\n    }\n\n    extend(defaultParams, userParams);\n  };\n\n  /*\n   * Set type, text and actions on modal\n   */\n\n  function setParameters(params) {\n    var modal = getModal();\n\n    var $title = modal.querySelector('h2'),\n        $text = modal.querySelector('p'),\n        $cancelBtn = modal.querySelector('button.cancel'),\n        $confirmBtn = modal.querySelector('button.confirm');\n\n    // Title\n    $title.innerHTML = escapeHtml(params.title).split(\"\\n\").join(\"<br>\");\n\n    // Text\n    $text.innerHTML = params.text;////escapeHtml(params.text || '').split(\"\\n\").join(\"<br>\");\n    if (params.text) {\n      show($text);\n    }\n\n    //Custom Class\n    if (params.customClass) {\n      addClass(modal, params.customClass);\n    }\n\n    // Icon\n    hide(modal.querySelectorAll('.icon'));\n    if (params.type) {\n      var validType = false;\n      for (var i = 0; i < alertTypes.length; i++) {\n        if (params.type === alertTypes[i]) {\n          validType = true;\n          break;\n        }\n      }\n      if (!validType) {\n        window.console.error('Unknown alert type: ' + params.type);\n        return false;\n      }\n      var $icon = modal.querySelector('.icon.' + params.type);\n      show($icon);\n\n      // Animate icon\n      switch (params.type) {\n        case \"success\":\n          addClass($icon, 'animate');\n          addClass($icon.querySelector('.tip'), 'animateSuccessTip');\n          addClass($icon.querySelector('.long'), 'animateSuccessLong');\n          break;\n        case \"error\":\n          addClass($icon, 'animateErrorIcon');\n          addClass($icon.querySelector('.x-mark'), 'animateXMark');\n          break;\n        case \"warning\":\n          addClass($icon, 'pulseWarning');\n          addClass($icon.querySelector('.body'), 'pulseWarningIns');\n          addClass($icon.querySelector('.dot'), 'pulseWarningIns');\n          break;\n      }\n\n    }\n\n    // Custom image\n    if (params.imageUrl) {\n      var $customIcon = modal.querySelector('.icon.custom');\n\n      $customIcon.style.backgroundImage = 'url(' + params.imageUrl + ')';\n      show($customIcon);\n\n      var _imgWidth  = 80,\n          _imgHeight = 80;\n\n      if (params.imageSize) {\n        var imgWidth  = params.imageSize.split('x')[0];\n        var imgHeight = params.imageSize.split('x')[1];\n\n        if (!imgWidth || !imgHeight) {\n          window.console.error(\"Parameter imageSize expects value with format WIDTHxHEIGHT, got \" + params.imageSize);\n        } else {\n          _imgWidth  = imgWidth;\n          _imgHeight = imgHeight;\n\n          $customIcon.css({\n            'width': imgWidth + 'px',\n            'height': imgHeight + 'px'\n          });\n        }\n      }\n      $customIcon.setAttribute('style', $customIcon.getAttribute('style') + 'width:' + _imgWidth + 'px; height:' + _imgHeight + 'px');\n    }\n\n    // Cancel button\n    modal.setAttribute('data-has-cancel-button', params.showCancelButton);\n    if (params.showCancelButton) {\n      $cancelBtn.style.display = 'inline-block';\n    } else {\n      hide($cancelBtn);\n    }\n\n    // Edit text on cancel and confirm buttons\n    if (params.cancelButtonText) {\n      $cancelBtn.innerHTML = escapeHtml(params.cancelButtonText);\n    }\n    if (params.confirmButtonText) {\n      $confirmBtn.innerHTML = escapeHtml(params.confirmButtonText);\n    }\n\n    // Set confirm button to selected background color\n    $confirmBtn.style.backgroundColor = params.confirmButtonColor;\n\n    // Set box-shadow to default focused button\n    setFocusStyle($confirmBtn, params.confirmButtonColor);\n\n    // Allow outside click?\n    modal.setAttribute('data-allow-ouside-click', params.allowOutsideClick);\n\n    // Done-function\n    var hasDoneFunction = (params.doneFunction) ? true : false;\n    modal.setAttribute('data-has-done-function', hasDoneFunction);\n\n    // Close timer\n    modal.setAttribute('data-timer', params.timer);\n  }\n\n\n  /*\n   * Set hover, active and focus-states for buttons (source: http://www.sitepoint.com/javascript-generate-lighter-darker-color)\n   */\n\n  function colorLuminance(hex, lum) {\n    // Validate hex string\n    hex = String(hex).replace(/[^0-9a-f]/gi, '');\n    if (hex.length < 6) {\n      hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];\n    }\n    lum = lum || 0;\n\n    // Convert to decimal and change luminosity\n    var rgb = \"#\", c, i;\n    for (i = 0; i < 3; i++) {\n      c = parseInt(hex.substr(i*2,2), 16);\n      c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);\n      rgb += (\"00\"+c).substr(c.length);\n    }\n\n    return rgb;\n  }\n\n  function extend(a, b){\n    for (var key in b) {\n      if (b.hasOwnProperty(key)) {\n        a[key] = b[key];\n      }\n    }\n\n    return a;\n  }\n\n  function hexToRgb(hex) {\n    var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n    return result ? parseInt(result[1], 16) + ', ' + parseInt(result[2], 16) + ', ' + parseInt(result[3], 16) : null;\n  }\n\n  // Add box-shadow style to button (depending on its chosen bg-color)\n  function setFocusStyle($button, bgColor) {\n    var rgbColor = hexToRgb(bgColor);\n    $button.style.boxShadow = '0 0 2px rgba(' + rgbColor +', 0.8), inset 0 0 0 1px rgba(0, 0, 0, 0.05)';\n  }\n\n\n\n  /*\n   * Animations\n   */\n\n  function openModal() {\n    var modal = getModal();\n    fadeIn(getOverlay(), 10);\n    show(modal);\n    addClass(modal, 'showSweetAlert');\n    removeClass(modal, 'hideSweetAlert');\n\n    previousActiveElement = document.activeElement;\n    var $okButton = modal.querySelector('button.confirm');\n    $okButton.focus();\n\n    setTimeout(function() {\n      addClass(modal, 'visible');\n    }, 500);\n\n    var timer = modal.getAttribute('data-timer');\n\n    if (timer !== \"null\" && timer !== \"\") {\n      modal.timeout = setTimeout(function() {\n        closeModal();\n      }, timer);\n    }\n  }\n\n  function closeModal() {\n    var modal = getModal();\n    fadeOut(getOverlay(), 5);\n    fadeOut(modal, 5);\n    removeClass(modal, 'showSweetAlert');\n    addClass(modal, 'hideSweetAlert');\n    removeClass(modal, 'visible');\n\n\n    // Reset icon animations\n\n    var $successIcon = modal.querySelector('.icon.success');\n    removeClass($successIcon, 'animate');\n    removeClass($successIcon.querySelector('.tip'), 'animateSuccessTip');\n    removeClass($successIcon.querySelector('.long'), 'animateSuccessLong');\n\n    var $errorIcon = modal.querySelector('.icon.error');\n    removeClass($errorIcon, 'animateErrorIcon');\n    removeClass($errorIcon.querySelector('.x-mark'), 'animateXMark');\n\n    var $warningIcon = modal.querySelector('.icon.warning');\n    removeClass($warningIcon, 'pulseWarning');\n    removeClass($warningIcon.querySelector('.body'), 'pulseWarningIns');\n    removeClass($warningIcon.querySelector('.dot'), 'pulseWarningIns');\n\n\n    // Reset the page to its previous state\n    window.onkeydown = previousWindowKeyDown;\n    document.onclick = previousDocumentClick;\n    if (previousActiveElement) {\n      previousActiveElement.focus();\n    }\n    lastFocusedButton = undefined;\n    clearTimeout(modal.timeout);\n  }\n\n\n  /*\n   * Set \"margin-top\"-property on modal based on its computed height\n   */\n\n  function fixVerticalPosition() {\n    var modal = getModal();\n\n    modal.style.marginTop = getTopMargin(getModal());\n  }\n\n\n\n  /*\n   * If library is injected after page has loaded\n   */\n\n  (function () {\n\t  if (document.readyState === \"complete\" || document.readyState === \"interactive\" && document.body) {\n\t\t  window.sweetAlertInitialize();\n\t  } else {\n\t\t  if (document.addEventListener) {\n\t\t\t  document.addEventListener('DOMContentLoaded', function factorial() {\n\t\t\t\t  document.removeEventListener('DOMContentLoaded', arguments.callee, false);\n\t\t\t\t  window.sweetAlertInitialize();\n\t\t\t  }, false);\n\t\t  } else if (document.attachEvent) {\n\t\t\t  document.attachEvent('onreadystatechange', function() {\n\t\t\t\t  if (document.readyState === 'complete') {\n\t\t\t\t\t  document.detachEvent('onreadystatechange', arguments.callee);\n\t\t\t\t\t  window.sweetAlertInitialize();\n\t\t\t\t  }\n\t\t\t  });\n\t\t  }\n\t  }\n  })();\n\n})(window, document);\n"
  },
  {
    "path": "public/assets/js/source/util--tagit.js",
    "content": "/*\n* jQuery UI Tag-it!\n*\n* @version v2.0 (06/2011)\n*\n* Copyright 2011, Levy Carneiro Jr.\n* Released under the MIT license.\n* http://aehlke.github.com/tag-it/LICENSE\n*\n* Homepage:\n*   http://aehlke.github.com/tag-it/\n*\n* Authors:\n*   Levy Carneiro Jr.\n*   Martin Rehfeld\n*   Tobias Schmidt\n*   Skylar Challand\n*   Alex Ehlke\n*\n* Maintainer:\n*   Alex Ehlke - Twitter: @aehlke\n*\n* Dependencies:\n*   jQuery v1.4+\n*   jQuery UI v1.8+\n*/\n(function($) {\n\n    $.widget('ui.tagit', {\n        options: {\n            allowDuplicates   : false,\n            caseSensitive     : true,\n            fieldName         : 'tags',\n            placeholderText   : null,   // Sets `placeholder` attr on input field.\n            readOnly          : false,  // Disables editing.\n            removeConfirmation: false,  // Require confirmation to remove tags.\n            tagLimit          : null,   // Max number of tags allowed (null for unlimited).\n\n            // Used for autocomplete, unless you override `autocomplete.source`.\n            availableTags     : [],\n\n            // Use to override or add any options to the autocomplete widget.\n            //\n            // By default, autocomplete.source will map to availableTags,\n            // unless overridden.\n            autocomplete: {},\n\n            // Shows autocomplete before the user even types anything.\n            showAutocompleteOnFocus: true,\n\n            // When enabled, quotes are unneccesary for inputting multi-word tags.\n            allowSpaces: false,\n\n            // The below options are for using a single field instead of several\n            // for our form values.\n            //\n            // When enabled, will use a single hidden field for the form,\n            // rather than one per tag. It will delimit tags in the field\n            // with singleFieldDelimiter.\n            //\n            // The easiest way to use singleField is to just instantiate tag-it\n            // on an INPUT element, in which case singleField is automatically\n            // set to true, and singleFieldNode is set to that element. This\n            // way, you don't need to fiddle with these options.\n            singleField: false,\n\n            // This is just used when preloading data from the field, and for\n            // populating the field with delimited tags as the user adds them.\n            singleFieldDelimiter: ',',\n\n            // Set this to an input DOM node to use an existing form field.\n            // Any text in it will be erased on init. But it will be\n            // populated with the text of tags as they are created,\n            // delimited by singleFieldDelimiter.\n            //\n            // If this is not set, we create an input node for it,\n            // with the name given in settings.fieldName.\n            singleFieldNode: null,\n\n            // Whether to animate tag removals or not.\n            animate: true,\n\n            // Optionally set a tabindex attribute on the input that gets\n            // created for tag-it.\n            tabIndex: null,\n\n            // Event callbacks.\n            beforeTagAdded      : null,\n            afterTagAdded       : null,\n\n            beforeTagRemoved    : null,\n            afterTagRemoved     : null,\n\n            onTagClicked        : null,\n            onTagLimitExceeded  : null,\n\n\n            // DEPRECATED:\n            //\n            // /!\\ These event callbacks are deprecated and WILL BE REMOVED at some\n            // point in the future. They're here for backwards-compatibility.\n            // Use the above before/after event callbacks instead.\n            onTagAdded  : null,\n            onTagRemoved: null,\n            // `autocomplete.source` is the replacement for tagSource.\n            tagSource: null\n            // Do not use the above deprecated options.\n        },\n\n        _create: function() {\n            // for handling static scoping inside callbacks\n            var that = this;\n\n            // There are 2 kinds of DOM nodes this widget can be instantiated on:\n            //     1. UL, OL, or some element containing either of these.\n            //     2. INPUT, in which case 'singleField' is overridden to true,\n            //        a UL is created and the INPUT is hidden.\n            if (this.element.is('input')) {\n                this.tagList = $('<ul></ul>').insertAfter(this.element);\n                this.options.singleField = true;\n                this.options.singleFieldNode = this.element;\n                this.element.addClass('tagit-hidden-field');\n            } else {\n                this.tagList = this.element.find('ul, ol').andSelf().last();\n            }\n\n            this.tagInput = $('<input type=\"text\" />').addClass('ui-widget-content');\n\n            if (this.options.readOnly) this.tagInput.attr('disabled', 'disabled');\n\n            if (this.options.tabIndex) {\n                this.tagInput.attr('tabindex', this.options.tabIndex);\n            }\n\n            if (this.options.placeholderText) {\n                this.tagInput.attr('placeholder', this.options.placeholderText);\n            }\n\n            if (!this.options.autocomplete.source) {\n                this.options.autocomplete.source = function(search, showChoices) {\n                    var filter = search.term.toLowerCase();\n\t\t\t\t\tif (this.options.availableTags) {\n\t\t\t\t\t\tvar choices = $.grep(this.options.availableTags.split(\",\"), function(element) {\n\t\t\t\t\t\t\t// Only match autocomplete options that begin with the search term.\n\t\t\t\t\t\t\t// (Case insensitive.)\n\t\t\t\t\t\t\treturn (element.toLowerCase().indexOf(filter) === 0);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (!this.options.allowDuplicates) {\n\t\t\t\t\t\t\tchoices = this._subtractArray(choices, this.assignedTags());\n\t\t\t\t\t\t}\n\t\t\t\t\t\tshowChoices(choices);\n\t\t\t\t\t}\n                };\n            }\n\n            if (this.options.showAutocompleteOnFocus) {\n                this.tagInput.focus(function(event, ui) {\n                    that._showAutocomplete();\n                });\n\n                if (typeof this.options.autocomplete.minLength === 'undefined') {\n                    this.options.autocomplete.minLength = 0;\n                }\n            }\n\n            // Bind autocomplete.source callback functions to this context.\n            if ($.isFunction(this.options.autocomplete.source)) {\n                this.options.autocomplete.source = $.proxy(this.options.autocomplete.source, this);\n            }\n\n            // DEPRECATED.\n            if ($.isFunction(this.options.tagSource)) {\n                this.options.tagSource = $.proxy(this.options.tagSource, this);\n            }\n\n            this.tagList\n                .addClass('tagit')\n                .addClass('ui-widget ui-widget-content ui-corner-all')\n                // Create the input field.\n                .append($('<li class=\"tagit-new\"></li>').append(this.tagInput))\n                .click(function(e) {\n                    var target = $(e.target);\n                    if (target.hasClass('tagit-label')) {\n                        var tag = target.closest('.tagit-choice');\n                        if (!tag.hasClass('removed')) {\n                            that._trigger('onTagClicked', e, {tag: tag, tagLabel: that.tagLabel(tag)});\n                        }\n                    } else {\n                        // Sets the focus() to the input field, if the user\n                        // clicks anywhere inside the UL. This is needed\n                        // because the input field needs to be of a small size.\n                        that.tagInput.focus();\n                    }\n                });\n\n            // Single field support.\n            var addedExistingFromSingleFieldNode = false;\n            if (this.options.singleField) {\n                if (this.options.singleFieldNode) {\n                    // Add existing tags from the input field.\n                    var node = $(this.options.singleFieldNode);\n                    var tags = node.val().split(this.options.singleFieldDelimiter);\n                    node.val('');\n                    $.each(tags, function(index, tag) {\n                        that.createTag(tag, null, true);\n                        addedExistingFromSingleFieldNode = true;\n                    });\n                } else {\n                    // Create our single field input after our list.\n                    this.options.singleFieldNode = $('<input type=\"hidden\" style=\"display:none;\" value=\"\" name=\"' + this.options.fieldName + '\" />');\n                    this.tagList.after(this.options.singleFieldNode);\n                }\n            }\n\n            // Add existing tags from the list, if any.\n            if (!addedExistingFromSingleFieldNode) {\n                this.tagList.children('li').each(function() {\n                    if (!$(this).hasClass('tagit-new')) {\n                        that.createTag($(this).text(), $(this).attr('class'), true);\n                        $(this).remove();\n                    }\n                });\n            }\n\n            // Events.\n            this.tagInput\n                .keydown(function(event) {\n                    // Backspace is not detected within a keypress, so it must use keydown.\n                    if (event.which == $.ui.keyCode.BACKSPACE && that.tagInput.val() === '') {\n                        var tag = that._lastTag();\n                        if (!that.options.removeConfirmation || tag.hasClass('remove')) {\n                            // When backspace is pressed, the last tag is deleted.\n                            that.removeTag(tag);\n                        } else if (that.options.removeConfirmation) {\n                            tag.addClass('remove ui-state-highlight');\n                        }\n                    } else if (that.options.removeConfirmation) {\n                        that._lastTag().removeClass('remove ui-state-highlight');\n                    }\n\n                    // Comma/Space/Enter are all valid delimiters for new tags,\n                    // except when there is an open quote or if setting allowSpaces = true.\n                    // Tab will also create a tag, unless the tag input is empty,\n                    // in which case it isn't caught.\n                    if (\n                        (event.which === $.ui.keyCode.COMMA && event.shiftKey === false) ||\n                        event.which === $.ui.keyCode.ENTER ||\n                        (\n                            event.which == $.ui.keyCode.TAB &&\n                            that.tagInput.val() !== ''\n                        ) ||\n                        (\n                            event.which == $.ui.keyCode.SPACE &&\n                            that.options.allowSpaces !== true &&\n                            (\n                                $.trim(that.tagInput.val()).replace( /^s*/, '' ).charAt(0) != '\"' ||\n                                (\n                                    $.trim(that.tagInput.val()).charAt(0) == '\"' &&\n                                    $.trim(that.tagInput.val()).charAt($.trim(that.tagInput.val()).length - 1) == '\"' &&\n                                    $.trim(that.tagInput.val()).length - 1 !== 0\n                                )\n                            )\n                        )\n                    ) {\n                        // Enter submits the form if there's no text in the input.\n                        if (!(event.which === $.ui.keyCode.ENTER && that.tagInput.val() === '')) {\n                            event.preventDefault();\n                        }\n\n                        // Autocomplete will create its own tag from a selection and close automatically.\n                        if (!(that.options.autocomplete.autoFocus && that.tagInput.data('autocomplete-open'))) {\n                            that.tagInput.autocomplete('close');\n                            that.createTag(that._cleanedInput());\n                        }\n                    }\n                }).blur(function(e){\n                    // Create a tag when the element loses focus.\n                    // If autocomplete is enabled and suggestion was clicked, don't add it.\n                    if (!that.tagInput.data('autocomplete-open')) {\n                        that.createTag(that._cleanedInput());\n                    }\n                });\n\n            // Autocomplete.\n            if (this.options.availableTags || this.options.tagSource || this.options.autocomplete.source) {\n                var autocompleteOptions = {\n                    select: function(event, ui) {\n                        that.createTag(ui.item.value);\n                        // Preventing the tag input to be updated with the chosen value.\n                        return false;\n                    }\n                };\n                $.extend(autocompleteOptions, this.options.autocomplete);\n\n                // tagSource is deprecated, but takes precedence here since autocomplete.source is set by default,\n                // while tagSource is left null by default.\n                autocompleteOptions.source = this.options.tagSource || autocompleteOptions.source;\n\n                this.tagInput.autocomplete(autocompleteOptions).bind('autocompleteopen.tagit', function(event, ui) {\n                    that.tagInput.data('autocomplete-open', true);\n                }).bind('autocompleteclose.tagit', function(event, ui) {\n                    that.tagInput.data('autocomplete-open', false);\n                });\n\n                this.tagInput.autocomplete('widget').addClass('tagit-autocomplete');\n            }\n        },\n\n        destroy: function() {\n            $.Widget.prototype.destroy.call(this);\n\n            this.element.unbind('.tagit');\n            this.tagList.unbind('.tagit');\n\n            this.tagInput.removeData('autocomplete-open');\n\n            this.tagList.removeClass([\n                'tagit',\n                'ui-widget',\n                'ui-widget-content',\n                'ui-corner-all',\n                'tagit-hidden-field'\n            ].join(' '));\n\n            if (this.element.is('input')) {\n                this.element.removeClass('tagit-hidden-field');\n                this.tagList.remove();\n            } else {\n                this.element.children('li').each(function() {\n                    if ($(this).hasClass('tagit-new')) {\n                        $(this).remove();\n                    } else {\n                        $(this).removeClass([\n                            'tagit-choice',\n                            'ui-widget-content',\n                            'ui-state-default',\n                            'ui-state-highlight',\n                            'ui-corner-all',\n                            'remove',\n                            'tagit-choice-editable',\n                            'tagit-choice-read-only'\n                        ].join(' '));\n\n                        $(this).text($(this).children('.tagit-label').text());\n                    }\n                });\n\n                if (this.singleFieldNode) {\n                    this.singleFieldNode.remove();\n                }\n            }\n\n            return this;\n        },\n\n        _cleanedInput: function() {\n            // Returns the contents of the tag input, cleaned and ready to be passed to createTag\n            return $.trim(this.tagInput.val().replace(/^\"(.*)\"$/, '$1'));\n        },\n\n        _lastTag: function() {\n            return this.tagList.find('.tagit-choice:last:not(.removed)');\n        },\n\n        _tags: function() {\n            return this.tagList.find('.tagit-choice:not(.removed)');\n        },\n\n        assignedTags: function() {\n            // Returns an array of tag string values\n            var that = this;\n            var tags = [];\n            if (this.options.singleField) {\n                tags = $(this.options.singleFieldNode).val().split(this.options.singleFieldDelimiter);\n                if (tags[0] === '') {\n                    tags = [];\n                }\n            } else {\n                this._tags().each(function() {\n                    tags.push(that.tagLabel(this));\n                });\n            }\n            return tags;\n        },\n\n        _updateSingleTagsField: function(tags) {\n            // Takes a list of tag string values, updates this.options.singleFieldNode.val to the tags delimited by this.options.singleFieldDelimiter\n            $(this.options.singleFieldNode).val(tags.join(this.options.singleFieldDelimiter)).trigger('change');\n        },\n\n        _subtractArray: function(a1, a2) {\n            var result = [];\n            for (var i = 0; i < a1.length; i++) {\n                if ($.inArray(a1[i], a2) == -1) {\n                    result.push(a1[i]);\n                }\n            }\n            return result;\n        },\n\n        tagLabel: function(tag) {\n            // Returns the tag's string label.\n            if (this.options.singleField) {\n                return $(tag).find('.tagit-label:first').text();\n            } else {\n                return $(tag).find('input:first').val();\n            }\n        },\n\n        _showAutocomplete: function() {\n            this.tagInput.autocomplete('search', '');\n        },\n\n        _findTagByLabel: function(name) {\n            var that = this;\n            var tag = null;\n            this._tags().each(function(i) {\n                if (that._formatStr(name) == that._formatStr(that.tagLabel(this))) {\n                    tag = $(this);\n                    return false;\n                }\n            });\n            return tag;\n        },\n\n        _isNew: function(name) {\n            return !this._findTagByLabel(name);\n        },\n\n        _formatStr: function(str) {\n            if (this.options.caseSensitive) {\n                return str;\n            }\n            return $.trim(str.toLowerCase());\n        },\n\n        _effectExists: function(name) {\n            return Boolean($.effects && ($.effects[name] || ($.effects.effect && $.effects.effect[name])));\n        },\n\n        createTag: function(value, additionalClass, duringInitialization) {\n            var that = this;\n\n            value = $.trim(value);\n\n            if(this.options.preprocessTag) {\n                value = this.options.preprocessTag(value);\n            }\n\n            if (value === '') {\n                return false;\n            }\n\n            if (!this.options.allowDuplicates && !this._isNew(value)) {\n                var existingTag = this._findTagByLabel(value);\n                if (this._trigger('onTagExists', null, {\n                    existingTag: existingTag,\n                    duringInitialization: duringInitialization\n                }) !== false) {\n                    if (this._effectExists('highlight')) {\n                        existingTag.effect('highlight');\n                    }\n                }\n                return false;\n            }\n\n            if (this.options.tagLimit && this._tags().length >= this.options.tagLimit) {\n                this._trigger('onTagLimitExceeded', null, {duringInitialization: duringInitialization});\n                return false;\n            }\n\n            var label = $(this.options.onTagClicked ? '<a class=\"tagit-label\"></a>' : '<span class=\"tagit-label\"></span>').text(value);\n\n            // Create tag.\n            var tag = $('<li></li>')\n                .addClass('tagit-choice ui-widget-content ui-state-default ui-corner-all')\n                .addClass(additionalClass)\n                .append(label);\n\n            if (this.options.readOnly){\n                tag.addClass('tagit-choice-read-only');\n            } else {\n                tag.addClass('tagit-choice-editable');\n                // Button for removing the tag.\n                var removeTagIcon = $('<span></span>')\n                    .addClass('ui-icon ui-icon-close');\n                var removeTag = $('<a><span class=\"text-icon\">\\xd7</span></a>') // \\xd7 is an X\n                    .addClass('tagit-close')\n                    .append(removeTagIcon)\n                    .click(function(e) {\n                        // Removes a tag when the little 'x' is clicked.\n                        that.removeTag(tag);\n                    });\n                tag.append(removeTag);\n            }\n\n            // Unless options.singleField is set, each tag has a hidden input field inline.\n            if (!this.options.singleField) {\n                var escapedValue = label.html();\n                tag.append('<input type=\"hidden\" value=\"' + escapedValue + '\" name=\"' + this.options.fieldName + '\" class=\"tagit-hidden-field\" />');\n            }\n\n            if (this._trigger('beforeTagAdded', null, {\n                tag: tag,\n                tagLabel: this.tagLabel(tag),\n                duringInitialization: duringInitialization\n            }) === false) {\n                return;\n            }\n\n            if (this.options.singleField) {\n                var tags = this.assignedTags();\n                tags.push(value);\n                this._updateSingleTagsField(tags);\n            }\n\n            // DEPRECATED.\n            this._trigger('onTagAdded', null, tag);\n\n            this.tagInput.val('');\n\n            // Insert tag.\n            this.tagInput.parent().before(tag);\n\n            this._trigger('afterTagAdded', null, {\n                tag: tag,\n                tagLabel: this.tagLabel(tag),\n                duringInitialization: duringInitialization\n            });\n\n            if (this.options.showAutocompleteOnFocus && !duringInitialization) {\n                setTimeout(function () { that._showAutocomplete(); }, 0);\n            }\n        },\n\n        removeTag: function(tag, animate) {\n            animate = typeof animate === 'undefined' ? this.options.animate : animate;\n\n            tag = $(tag);\n\n            // DEPRECATED.\n            this._trigger('onTagRemoved', null, tag);\n\n            if (this._trigger('beforeTagRemoved', null, {tag: tag, tagLabel: this.tagLabel(tag)}) === false) {\n                return;\n            }\n\n            if (this.options.singleField) {\n                var tags = this.assignedTags();\n                var removedTagLabel = this.tagLabel(tag);\n                tags = $.grep(tags, function(el){\n                    return el != removedTagLabel;\n                });\n                this._updateSingleTagsField(tags);\n            }\n\n            if (animate) {\n                tag.addClass('removed'); // Excludes this tag from _tags.\n                var hide_args = this._effectExists('blind') ? ['blind', {direction: 'horizontal'}, 'fast'] : ['fast'];\n\n                var thisTag = this;\n                hide_args.push(function() {\n                    tag.remove();\n                    thisTag._trigger('afterTagRemoved', null, {tag: tag, tagLabel: thisTag.tagLabel(tag)});\n                });\n\n                tag.fadeOut('fast').hide.apply(tag, hide_args).dequeue();\n            } else {\n                tag.remove();\n                this._trigger('afterTagRemoved', null, {tag: tag, tagLabel: this.tagLabel(tag)});\n            }\n\n        },\n\n        removeTagByLabel: function(tagLabel, animate) {\n            var toRemove = this._findTagByLabel(tagLabel);\n            if (!toRemove) {\n                throw \"No such tag exists with the name '\" + tagLabel + \"'\";\n            }\n            this.removeTag(toRemove, animate);\n        },\n\n        removeAll: function() {\n            // Removes all tags.\n            var that = this;\n            this._tags().each(function(index, tag) {\n                that.removeTag(tag, false);\n            });\n        }\n\n    });\n})(jQuery);"
  },
  {
    "path": "public/assets/js/source/util--touch-punch.js",
    "content": "/*!\n * jQuery UI Touch Punch 0.2.3\n *\n * Copyright 2011–2014, Dave Furfero\n * Dual licensed under the MIT or GPL Version 2 licenses.\n *\n * Depends:\n *  jquery.ui.widget.js\n *  jquery.ui.mouse.js\n */\n(function ($) {\n\n  // Detect touch support\n  $.support.touch = 'ontouchend' in document;\n\n  // Ignore browsers without touch support\n  if (!$.support.touch) {\n    return;\n  }\n\n  var mouseProto = $.ui.mouse.prototype,\n      _mouseInit = mouseProto._mouseInit,\n      _mouseDestroy = mouseProto._mouseDestroy,\n      touchHandled;\n\n  /**\n   * Simulate a mouse event based on a corresponding touch event\n   * @param {Object} event A touch event\n   * @param {String} simulatedType The corresponding mouse event\n   */\n  function simulateMouseEvent (event, simulatedType) {\n\n    // Ignore multi-touch events\n    if (event.originalEvent.touches.length > 1) {\n      return;\n    }\n\n    event.preventDefault();\n\n    var touch = event.originalEvent.changedTouches[0],\n        simulatedEvent = document.createEvent('MouseEvents');\n    \n    // Initialize the simulated mouse event using the touch event's coordinates\n    simulatedEvent.initMouseEvent(\n      simulatedType,    // type\n      true,             // bubbles                    \n      true,             // cancelable                 \n      window,           // view                       \n      1,                // detail                     \n      touch.screenX,    // screenX                    \n      touch.screenY,    // screenY                    \n      touch.clientX,    // clientX                    \n      touch.clientY,    // clientY                    \n      false,            // ctrlKey                    \n      false,            // altKey                     \n      false,            // shiftKey                   \n      false,            // metaKey                    \n      0,                // button                     \n      null              // relatedTarget              \n    );\n\n    // Dispatch the simulated event to the target element\n    event.target.dispatchEvent(simulatedEvent);\n  }\n\n  /**\n   * Handle the jQuery UI widget's touchstart events\n   * @param {Object} event The widget element's touchstart event\n   */\n  mouseProto._touchStart = function (event) {\n\n    var self = this;\n\n    // Ignore the event if another widget is already being handled\n    if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {\n      return;\n    }\n\n    // Set the flag to prevent other widgets from inheriting the touch event\n    touchHandled = true;\n\n    // Track movement to determine if interaction was a click\n    self._touchMoved = false;\n\n    // Simulate the mouseover event\n    simulateMouseEvent(event, 'mouseover');\n\n    // Simulate the mousemove event\n    simulateMouseEvent(event, 'mousemove');\n\n    // Simulate the mousedown event\n    simulateMouseEvent(event, 'mousedown');\n  };\n\n  /**\n   * Handle the jQuery UI widget's touchmove events\n   * @param {Object} event The document's touchmove event\n   */\n  mouseProto._touchMove = function (event) {\n\n    // Ignore event if not handled\n    if (!touchHandled) {\n      return;\n    }\n\n    // Interaction was not a click\n    this._touchMoved = true;\n\n    // Simulate the mousemove event\n    simulateMouseEvent(event, 'mousemove');\n  };\n\n  /**\n   * Handle the jQuery UI widget's touchend events\n   * @param {Object} event The document's touchend event\n   */\n  mouseProto._touchEnd = function (event) {\n\n    // Ignore event if not handled\n    if (!touchHandled) {\n      return;\n    }\n\n    // Simulate the mouseup event\n    simulateMouseEvent(event, 'mouseup');\n\n    // Simulate the mouseout event\n    simulateMouseEvent(event, 'mouseout');\n\n    // If the touch interaction did not move, it should trigger a click\n    if (!this._touchMoved) {\n\n      // Simulate the click event\n      simulateMouseEvent(event, 'click');\n    }\n\n    // Unset the flag to allow other widgets to inherit the touch event\n    touchHandled = false;\n  };\n\n  /**\n   * A duck punch of the $.ui.mouse _mouseInit method to support touch events.\n   * This method extends the widget with bound touch event handlers that\n   * translate touch events to mouse events and pass them to the widget's\n   * original mouse event handling methods.\n   */\n  mouseProto._mouseInit = function () {\n    \n    var self = this;\n\n    // Delegate the touch handlers to the widget's element\n    self.element.bind({\n      touchstart: $.proxy(self, '_touchStart'),\n      touchmove: $.proxy(self, '_touchMove'),\n      touchend: $.proxy(self, '_touchEnd')\n    });\n\n    // Call the original $.ui.mouse init method\n    _mouseInit.call(self);\n  };\n\n  /**\n   * Remove the touch event handlers\n   */\n  mouseProto._mouseDestroy = function () {\n    \n    var self = this;\n\n    // Delegate the touch handlers to the widget's element\n    self.element.unbind({\n      touchstart: $.proxy(self, '_touchStart'),\n      touchmove: $.proxy(self, '_touchMove'),\n      touchend: $.proxy(self, '_touchEnd')\n    });\n\n    // Call the original $.ui.mouse destroy method\n    _mouseDestroy.call(self);\n  };\n\n})(jQuery);"
  },
  {
    "path": "public/assets/js/source/util--undo.js",
    "content": "/* ways to inject JS Codes\n\nlasso_editor.setupHookArray\nlasso_editor.enterEditorHookArray\nlasso_editor.enterEditorHookArray2\nlasso_editor.exitEditorHookArray\nlasso_editor.saveSuccessHookArray\n\n*/\n\n\n\n\n/*\n * Undo.js - A undo/redo framework for JavaScript\n * \n * http://jzaefferer.github.com/undo\n *\n * Copyright (c) 2011 Jörn Zaefferer\n * MIT licensed.\n */\n(function() {\n\n// based on Backbone.js' inherits\t\nvar ctor = function(){};\nvar inherits = function(parent, protoProps) {\n\tvar child;\n\n\tif (protoProps && protoProps.hasOwnProperty('constructor')) {\n\t\tchild = protoProps.constructor;\n\t} else {\n\t\tchild = function(){ return parent.apply(this, arguments); };\n\t}\n\n\tctor.prototype = parent.prototype;\n\tchild.prototype = new ctor();\n\t\n\tif (protoProps) extend(child.prototype, protoProps);\n\t\n\tchild.prototype.constructor = child;\n\tchild.__super__ = parent.prototype;\n\treturn child;\n};\n\nfunction extend(target, ref) {\n\tvar name, value;\n\tfor ( name in ref ) {\n\t\tvalue = ref[name];\n\t\tif (value !== undefined) {\n\t\t\ttarget[ name ] = value;\n\t\t}\n\t}\n\treturn target;\n};\n\nvar Undo;\nif (typeof exports !== 'undefined') {\n\tUndo = exports;\n} else {\n\tUndo = this.Undo = {};\n}\n\nUndo.Stack = function() {\n\tthis.commands = [];\n\tthis.stackPosition = -1;\n\tthis.savePosition = -1;\n};\n\nextend(Undo.Stack.prototype, {\n\texecute: function(command) {\n\t\tthis._clearRedo();\n\t\tcommand.execute();\n\t\tthis.commands.push(command);\n\t\tif (this.commands.length>15) {\n\t\t\tthis.commands.shift();\n\t\t} else {\n\t\t\tthis.stackPosition++;\n\t\t}\n\t\t\n\t\tthis.changed();\n\t},\n\tundo: function() {\n\t\tthis.commands[this.stackPosition].undo();\n\t\tthis.stackPosition--;\n\t\t//this.commands.pop();\n\t\tthis.changed();\n\t},\n\tcanUndo: function() {\n\t\treturn this.stackPosition >= 0;\n\t},\n\tredo: function() {\n\t\tthis.stackPosition++;\n\t\tthis.commands[this.stackPosition].redo();\n\t\tthis.changed();\n\t},\n\tcanRedo: function() {\n\t\treturn this.stackPosition < this.commands.length - 1;\n\t},\n\tsave: function() {\n\t\tthis.savePosition = this.stackPosition;\n\t\tthis.changed();\n\t},\n\tdirty: function() {\n\t\treturn (this.stackPosition != this.savePosition) || lasso_editor.dirtyByComponent;\n\t},\n\t_clearRedo: function() {\n\t\t// TODO there's probably a more efficient way for this\n\t\tthis.commands = this.commands.slice(0, this.stackPosition + 1);\n\t},\n\tchanged: function() {\n\t\t// do nothing, override\n\t}\n});\n\nUndo.Command = function(name) {\n\tthis.name = name;\n}\n\nvar up = new Error(\"override me!\");\n\nextend(Undo.Command.prototype, {\n\texecute: function() {\n\t\tthrow up;\n\t},\n\tundo: function() {\n\t\tthrow up;\n\t},\n\tredo: function() {\n\t\tthis.execute();\n\t}\n});\n\nUndo.Command.extend = function(protoProps) {\n\tvar child = inherits(this, protoProps);\n\tchild.extend = Undo.Command.extend;\n\treturn child;\n};\n\t\n}).call(this);"
  },
  {
    "path": "public/assets/js/source/util--wp-api.js",
    "content": "(function( window, undefined ) {\n\n\t'use strict';\n\n\tfunction WP_API() {\n\t\tthis.models = {};\n\t\tthis.collections = {};\n\t\tthis.views = {};\n\t}\n\n\twindow.wp = window.wp || {};\n\twp.api = wp.api || new WP_API();\n\n})( window );\n\n(function( Backbone, _, window, undefined ) {\n\n\t//'use strict';\n\n\t// ECMAScript 5 shim, from MDN\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString\n\tif ( ! Date.prototype.toISOString ) {\n\t\tvar pad = function( number ) {\n\t\t\tvar r = String( number );\n\t\t\tif ( r.length === 1 ) {\n\t\t\t\tr = '0' + r;\n\t\t\t}\n\t\t\treturn r;\n\t\t};\n\n\t\tDate.prototype.toISOString = function() {\n\t\t\treturn this.getUTCFullYear() +\n\t\t\t\t'-' + pad( this.getUTCMonth() + 1 ) +\n\t\t\t\t'-' + pad( this.getUTCDate() ) +\n\t\t\t\t'T' + pad( this.getUTCHours() ) +\n\t\t\t\t':' + pad( this.getUTCMinutes() ) +\n\t\t\t\t':' + pad( this.getUTCSeconds() ) +\n\t\t\t\t'.' + String( ( this.getUTCMilliseconds()/1000 ).toFixed( 3 ) ).slice( 2, 5 ) +\n\t\t\t\t'Z';\n\t\t};\n\t}\n\n\tfunction WP_API_Utils() {\n\t\tvar origParse = Date.parse,\n\t\t\tnumericKeys = [ 1, 4, 5, 6, 7, 10, 11 ];\n\n\n\t\tthis.parseISO8601 = function( date ) {\n\t\t\tvar timestamp, struct, i, k,\n\t\t\t\tminutesOffset = 0;\n\n\t\t\t// ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string\n\t\t\t// before falling back to any implementation-specific date parsing, so that’s what we do, even if native\n\t\t\t// implementations could be faster\n\t\t\t//              1 YYYY                2 MM       3 DD           4 HH    5 mm       6 ss        7 msec        8 Z 9 ±    10 tzHH    11 tzmm\n\t\t\tif ((struct = /^(\\d{4}|[+\\-]\\d{6})(?:-(\\d{2})(?:-(\\d{2}))?)?(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{3}))?)?(?:(Z)|([+\\-])(\\d{2})(?::(\\d{2}))?)?)?$/.exec(date))) {\n\t\t\t\t// avoid NaN timestamps caused by “undefined” values being passed to Date.UTC\n\t\t\t\tfor ( i = 0; ( k = numericKeys[i] ); ++i) {\n\t\t\t\t\tstruct[k] = +struct[k] || 0;\n\t\t\t\t}\n\n\t\t\t\t// allow undefined days and months\n\t\t\t\tstruct[2] = ( +struct[2] || 1 ) - 1;\n\t\t\t\tstruct[3] = +struct[3] || 1;\n\n\t\t\t\tif ( struct[8] !== 'Z' && struct[9] !== undefined ) {\n\t\t\t\t\tminutesOffset = struct[10] * 60 + struct[11];\n\n\t\t\t\t\tif ( struct[9] === '+' ) {\n\t\t\t\t\t\tminutesOffset = 0 - minutesOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttimestamp = Date.UTC( struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7] );\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttimestamp = origParse ? origParse( date ) : NaN;\n\t\t\t}\n\n\t\t\treturn timestamp;\n\t\t};\n\t}\n\n\twindow.wp = window.wp || {};\n\twp.api = wp.api || {};\n\twp.api.utils = wp.api.utils || new WP_API_Utils();\n\n})( Backbone, _, window );\n\n/* global WP_API_Settings:false */\n// Suppress warning about parse function's unused \"options\" argument:\n/* jshint unused:false */\n(function( wp, WP_API_Settings, Backbone, _, window, undefined ) {\n\n\t'use strict';\n\n\t/**\n\t * Array of parseable dates\n\t *\n\t * @type {string[]}\n\t */\n\tvar parseable_dates = [ 'date', 'modified', 'date_gmt', 'modified_gmt' ];\n\n\t/**\n\t * Mixin for all content that is time stamped\n\t *\n\t * @type {{toJSON: toJSON, parse: parse}}\n\t */\n\tvar TimeStampedMixin = {\n\t\t/**\n\t\t * Serialize the entity pre-sync\n\t\t *\n\t\t * @returns {*}\n\t\t */\n\t\ttoJSON: function() {\n\t\t\tvar attributes = _.clone( this.attributes );\n\n\t\t\t// Serialize Date objects back into 8601 strings\n\t\t\t_.each( parseable_dates, function ( key ) {\n\t\t\t\tif ( key in attributes ) {\n\t\t\t\t\tattributes[key] = attributes[key].toISOString();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn attributes;\n\t\t},\n\n\t\t/**\n\t\t * Unserialize the fetched response\n\t\t *\n\t\t * @param {*} response\n\t\t * @returns {*}\n\t\t */\n\t\tparse: function( response ) {\n\t\t\t// Parse dates into native Date objects\n\t\t\t_.each( parseable_dates, function ( key ) {\n\t\t\t\tif ( ! ( key in response ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar timestamp = wp.api.utils.parseISO8601( response[key] );\n\t\t\t\tresponse[key] = new Date( timestamp );\n\t\t\t});\n\n\t\t\t// Parse the author into a User object\n\t\t\tif ( response.author !== 'undefined' ) {\n\t\t\t\tresponse.author = new wp.api.models.User( response.author );\n\t\t\t}\n\n\t\t\treturn response;\n\t\t}\n\t};\n\n\t/**\n\t * Mixin for all hierarchical content types such as posts\n\t *\n\t * @type {{parent: parent}}\n\t */\n\tvar HierarchicalMixin = {\n\t\t/**\n\t\t * Get parent object\n\t\t *\n\t\t * @returns {Backbone.Model}\n\t\t */\n\t\tparent: function() {\n\n\t\t\tvar object, parent = this.get( 'parent' );\n\n\t\t\t// Return null if we don't have a parent\n\t\t\tif ( parent === 0 ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tvar parentModel = this;\n\n\t\t\tif ( typeof this.parentModel !== 'undefined' ) {\n\t\t\t\t/**\n\t\t\t\t * Probably a better way to do this. Perhaps grab a cached version of the\n\t\t\t\t * instantiated model?\n\t\t\t\t */\n\t\t\t\tparentModel = new this.parentModel();\n\t\t\t}\n\n\t\t\t// Can we get this from its collection?\n\t\t\tif ( parentModel.collection ) {\n\t\t\t\treturn parentModel.collection.get( parent );\n\t\t\t} else {\n\t\t\t\t// Otherwise, get the object directly\n\t\t\t\tobject = new parentModel.constructor( {\n\t\t\t\t\tID: parent\n\t\t\t\t});\n\n\t\t\t\t// Note that this acts asynchronously\n\t\t\t\tobject.fetch();\n\t\t\t\treturn object;\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Private Backbone base model for all models\n\t */\n\tvar BaseModel = Backbone.Model.extend(\n\t\t/** @lends BaseModel.prototype  */\n\t\t{\n\t\t\t/**\n\t\t\t * Set nonce header before every Backbone sync\n\t\t\t *\n\t\t\t * @param {string} method\n\t\t\t * @param {Backbone.Model} model\n\t\t\t * @param {{beforeSend}, *} options\n\t\t\t * @returns {*}\n\t\t\t */\n\t\t\tsync: function( method, model, options ) {\n\t\t\t\toptions = options || {};\n\n\t\t\t\tif ( typeof WP_API_Settings.nonce !== 'undefined' ) {\n\t\t\t\t\tvar beforeSend = options.beforeSend;\n\n\t\t\t\t\toptions.beforeSend = function( xhr ) {\n\t\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', WP_API_Settings.nonce );\n\n\t\t\t\t\t\tif ( beforeSend ) {\n\t\t\t\t\t\t\treturn beforeSend.apply( this, arguments );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn Backbone.sync( method, model, options );\n\t\t\t}\n\t\t}\n\t);\n\n\t/**\n\t * Backbone model for single users\n\t */\n\twp.api.models.User = BaseModel.extend(\n\t\t/** @lends User.prototype  */\n\t\t{\n\t\t\tidAttribute: 'ID',\n\n\t\t\turlRoot: WP_API_Settings.root + '/users',\n\n\t\t\tdefaults: {\n\t\t\t\tID: null,\n\t\t\t\tusername: '',\n\t\t\t\temail: '',\n\t\t\t\tpassword: '',\n\t\t\t\tname: '',\n\t\t\t\tfirst_name: '',\n\t\t\t\tlast_name: '',\n\t\t\t\tnickname: '',\n\t\t\t\tslug: '',\n\t\t\t\tURL: '',\n\t\t\t\tavatar: '',\n\t\t\t\tmeta: {\n\t\t\t\t\tlinks: {}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Return avatar URL\n\t\t\t *\n\t\t\t * @param {number} size\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\tavatar: function( size ) {\n\t\t\t\treturn this.get( 'avatar' ) + '&s=' + size;\n\t\t\t}\n\t\t}\n\t);\n\n\t/**\n\t * Model for Taxonomy\n\t */\n\twp.api.models.Taxonomy = BaseModel.extend(\n\t\t/** @lends Taxonomy.prototype  */\n\t\t{\n\t\t\tidAttribute: 'slug',\n\n\t\t\turlRoot: WP_API_Settings.root + '/taxonomies',\n\n\t\t\tdefaults: {\n\t\t\t\tname: '',\n\t\t\t\tslug: null,\n\t\t\t\tlabels: {},\n\t\t\t\ttypes: {},\n\t\t\t\tshow_cloud: false,\n\t\t\t\thierarchical: false,\n\t\t\t\tmeta: {\n\t\t\t\t\tlinks: {}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t);\n\n\t/**\n\t * Backbone model for term\n\t */\n\twp.api.models.Term = BaseModel.extend( _.extend(\n\t\t/** @lends Term.prototype */\n\t\t{\n\t\t\tidAttribute: 'ID',\n\n\t\t\ttaxonomy: 'category',\n\n\t\t\t/**\n\t\t\t * @class Represent a term\n\t\t\t * @augments Backbone.Model\n\t\t\t * @constructs\n\t\t\t */\n\t\t\tinitialize: function( attributes, options ) {\n\t\t\t\tif ( typeof options !== 'undefined' ) {\n\t\t\t\t\tif ( options.taxonomy ) {\n\t\t\t\t\t\tthis.taxonomy = options.taxonomy;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Return URL for the model\n\t\t\t *\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\turl: function() {\n\t\t\t\tvar id = this.get( 'ID' );\n\t\t\t\tid = id || '';\n\n\t\t\t\treturn WP_API_Settings.root + '/taxonomies/' + this.taxonomy + '/terms/' + id;\n\t\t\t},\n\n\t\t\tdefaults: {\n\t\t\t\tID: null,\n\t\t\t\tname: '',\n\t\t\t\tslug: '',\n\t\t\t\tdescription: '',\n\t\t\t\tparent: null,\n\t\t\t\tcount: 0,\n\t\t\t\tlink: '',\n\t\t\t\tmeta: {\n\t\t\t\t\tlinks: {}\n\t\t\t\t}\n\t\t\t}\n\n\t\t}, TimeStampedMixin, HierarchicalMixin )\n\t);\n\n\t/**\n\t * Backbone model for single posts\n\t */\n\twp.api.models.Post = BaseModel.extend( _.extend(\n\t\t/** @lends Post.prototype  */\n\t\t{\n\t\t\tidAttribute: 'ID',\n\n\t\t\turlRoot: WP_API_Settings.root + '/posts',\n\n\t\t\tdefaults: {\n\t\t\t\tID: null,\n\t\t\t\ttitle: '',\n\t\t\t\tstatus: 'draft',\n\t\t\t\ttype: 'post',\n\t\t\t\tauthor: new wp.api.models.User(),\n\t\t\t\tcontent: '',\n\t\t\t\tlink: '',\n\t\t\t\t'parent': 0,\n\t\t\t\tdate: new Date(),\n\t\t\t\tdate_gmt: new Date(),\n\t\t\t\tmodified: new Date(),\n\t\t\t\tmodified_gmt: new Date(),\n\t\t\t\tformat: 'standard',\n\t\t\t\tslug: '',\n\t\t\t\tguid: '',\n\t\t\t\texcerpt: '',\n\t\t\t\tmenu_order: 0,\n\t\t\t\tcomment_status: 'open',\n\t\t\t\tping_status: 'open',\n\t\t\t\tsticky: false,\n\t\t\t\tdate_tz: 'Etc/UTC',\n\t\t\t\tmodified_tz: 'Etc/UTC',\n\t\t\t\tfeatured_image: null,\n\t\t\t\tterms: {},\n\t\t\t\tpost_meta: {},\n\t\t\t\tmeta: {\n\t\t\t\t\tlinks: {}\n\t\t\t\t}\n\t\t\t}\n\t\t}, TimeStampedMixin, HierarchicalMixin )\n\t);\n\n\t/**\n\t * Backbone model for pages\n\t */\n\twp.api.models.Page = BaseModel.extend( _.extend(\n\t\t/** @lends Page.prototype  */\n\t\t{\n\t\t\tidAttribute: 'ID',\n\n\t\t\turlRoot: WP_API_Settings.root + '/pages',\n\n\t\t\tdefaults: {\n\t\t\t\tID: null,\n\t\t\t\ttitle: '',\n\t\t\t\tstatus: 'draft',\n\t\t\t\ttype: 'page',\n\t\t\t\tauthor: new wp.api.models.User(),\n\t\t\t\tcontent: '',\n\t\t\t\tparent: 0,\n\t\t\t\tlink: '',\n\t\t\t\tdate: new Date(),\n\t\t\t\tmodified: new Date(),\n\t\t\t\tdate_gmt: new Date(),\n\t\t\t\tmodified_gmt: new Date(),\n\t\t\t\tdate_tz: 'Etc/UTC',\n\t\t\t\tmodified_tz: 'Etc/UTC',\n\t\t\t\tformat: 'standard',\n\t\t\t\tslug: '',\n\t\t\t\tguid: '',\n\t\t\t\texcerpt: '',\n\t\t\t\tmenu_order: 0,\n\t\t\t\tcomment_status: 'closed',\n\t\t\t\tping_status: 'open',\n\t\t\t\tsticky: false,\n\t\t\t\tpassword: '',\n\t\t\t\tmeta: {\n\t\t\t\t\tlinks: {}\n\t\t\t\t},\n\t\t\t\tfeatured_image: null,\n\t\t\t\tterms: []\n\t\t\t}\n\t\t}, TimeStampedMixin, HierarchicalMixin )\n\t);\n\n\t/**\n\t * Backbone model for revisions\n\t */\n\twp.api.models.Revision = wp.api.models.Post.extend(\n\t\t/** @lends Revision.prototype */\n\t\t{\n\t\t\t/**\n\t\t\t * Return URL for model\n\t\t\t *\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\turl: function() {\n\t\t\t\tvar parent_id = this.get( 'parent' );\n\t\t\t\tparent_id = parent_id || '';\n\n\t\t\t\tvar id = this.get( 'ID' );\n\t\t\t\tid = id || '';\n\n\t\t\t\treturn WP_API_Settings.root + '/posts/' + parent_id + '/revisions/' + id;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @class Represent a revision\n\t\t\t * @augments Backbone.Model\n\t\t\t * @constructs\n\t\t\t */\n\t\t\tinitialize: function() {\n\t\t\t\t// Todo: what of the parent model is a page?\n\t\t\t\tthis.parentModel = wp.api.models.Post;\n\t\t\t}\n\t\t}\n\t);\n\n\t/**\n\t * Backbone model for media items\n\t */\n\twp.api.models.Media = BaseModel.extend( _.extend(\n\t\t/** @lends Media.prototype */\n\t\t{\n\t\t\tidAttribute: 'ID',\n\n\t\t\turlRoot: WP_API_Settings.root + '/media',\n\n\t\t\tdefaults: {\n\t\t\t\tID: null,\n\t\t\t\ttitle: '',\n\t\t\t\tstatus: 'inherit',\n\t\t\t\ttype: 'attachment',\n\t\t\t\tauthor: new wp.api.models.User(),\n\t\t\t\tcontent: '',\n\t\t\t\tparent: 0,\n\t\t\t\tlink: '',\n\t\t\t\tdate: new Date(),\n\t\t\t\tmodified: new Date(),\n\t\t\t\tformat: 'standard',\n\t\t\t\tslug: '',\n\t\t\t\tguid: '',\n\t\t\t\texcerpt: '',\n\t\t\t\tmenu_order: 0,\n\t\t\t\tcomment_status: 'open',\n\t\t\t\tping_status: 'open',\n\t\t\t\tsticky: false,\n\t\t\t\tdate_tz: 'Etc/UTC',\n\t\t\t\tmodified_tz: 'Etc/UTC',\n\t\t\t\tdate_gmt: new Date(),\n\t\t\t\tmodified_gmt: new Date(),\n\t\t\t\tmeta: {\n\t\t\t\t\tlinks: {}\n\t\t\t\t},\n\t\t\t\tterms: [],\n\t\t\t\tsource: '',\n\t\t\t\tis_image: true,\n\t\t\t\tattachment_meta: {},\n\t\t\t\timage_meta: {}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @class Represent a media item\n\t\t\t * @augments Backbone.Model\n\t\t\t * @constructs\n\t\t\t */\n\t\t\tinitialize: function() {\n\t\t\t\t// Todo: what of the parent model is a page?\n\t\t\t\tthis.parentModel = wp.api.models.Post;\n\t\t\t}\n\t\t}, TimeStampedMixin, HierarchicalMixin )\n\t);\n\n\t/**\n\t * Backbone model for comments\n\t */\n\twp.api.models.Comment = BaseModel.extend( _.extend(\n\t\t/** @lends Comment.prototype */\n\t\t{\n\t\t\tidAttribute: 'ID',\n\n\t\t\tdefaults: {\n\t\t\t\tID: null,\n\t\t\t\tpost: null,\n\t\t\t\tcontent: '',\n\t\t\t\tstatus: 'hold',\n\t\t\t\ttype: '',\n\t\t\t\tparent: 0,\n\t\t\t\tauthor: new wp.api.models.User(),\n\t\t\t\tdate: new Date(),\n\t\t\t\tdate_gmt: new Date(),\n\t\t\t\tdate_tz: 'Etc/UTC',\n\t\t\t\tmeta: {\n\t\t\t\t\tlinks: {}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Return URL for model\n\t\t\t *\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\turl: function() {\n\t\t\t\tvar post_id = this.get( 'post' );\n\t\t\t\tpost_id = post_id || '';\n\n\t\t\t\tvar id = this.get( 'ID' );\n\t\t\t\tid = id || '';\n\n\t\t\t\treturn WP_API_Settings.root + '/posts/' + post_id + '/comments/' + id;\n\t\t\t}\n\t\t}, TimeStampedMixin, HierarchicalMixin )\n\t);\n\n\t/**\n\t * Backbone model for single post types\n\t */\n\twp.api.models.PostType = BaseModel.extend(\n\t\t/** @lends PostType.prototype */\n\t\t{\n\t\t\tidAttribute: 'slug',\n\n\t\t\turlRoot: WP_API_Settings.root + '/posts/types',\n\n\t\t\tdefaults: {\n\t\t\t\tslug: null,\n\t\t\t\tname: '',\n\t\t\t\tdescription: '',\n\t\t\t\tlabels: {},\n\t\t\t\tqueryable: false,\n\t\t\t\tsearchable: false,\n\t\t\t\thierarchical: false,\n\t\t\t\tmeta: {\n\t\t\t\t\tlinks: {}\n\t\t\t\t},\n\t\t\t\ttaxonomies: []\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Prevent model from being saved\n\t\t\t *\n\t\t\t * @returns {boolean}\n\t\t\t */\n\t\t\tsave: function () {\n\t\t\t\treturn false;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Prevent model from being deleted\n\t\t\t *\n\t\t\t * @returns {boolean}\n\t\t\t */\n\t\t\t'delete': function () {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t);\n\n\t/**\n\t * Backbone model for a post status\n\t */\n\twp.api.models.PostStatus = BaseModel.extend(\n\t\t/** @lends PostStatus.prototype */\n\t\t{\n\t\t\tidAttribute: 'slug',\n\n\t\t\turlRoot: WP_API_Settings.root + '/posts/statuses',\n\n\t\t\tdefaults: {\n\t\t\t\tslug: null,\n\t\t\t\tname: '',\n\t\t\t\t'public': true,\n\t\t\t\t'protected': false,\n\t\t\t\t'private': false,\n\t\t\t\tqueryable: true,\n\t\t\t\tshow_in_list: true,\n\t\t\t\tmeta: {\n\t\t\t\t\tlinks: {}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Prevent model from being saved\n\t\t\t *\n\t\t\t * @returns {boolean}\n\t\t\t */\n\t\t\tsave: function() {\n\t\t\t\treturn false;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Prevent model from being deleted\n\t\t\t *\n\t\t\t * @returns {boolean}\n\t\t\t */\n\t\t\t'delete': function() {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t);\n\n})( wp, WP_API_Settings, Backbone, _, window );\n\n/* global WP_API_Settings:false */\n(function( wp, WP_API_Settings, Backbone, _, window, undefined ) {\n\n\t'use strict';\n\n\tvar BaseCollection = Backbone.Collection.extend(\n\t\t/** @lends BaseCollection.prototype  */\n\t\t{\n\n\t\t\t/**\n\t\t\t * Setup default state\n\t\t\t */\n\t\t\tinitialize: function() {\n\t\t\t\tthis.state = {\n\t\t\t\t\tdata: {},\n\t\t\t\t\tcurrentPage: null,\n\t\t\t\t\ttotalPages: null,\n\t\t\t\t\ttotalObjects: null\n\t\t\t\t};\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Overwrite Backbone.Collection.sync to pagination state based on response headers.\n\t\t\t *\n\t\t\t * Set nonce header before every Backbone sync.\n\t\t\t *\n\t\t\t * @param {string} method\n\t\t\t * @param {Backbone.Model} model\n\t\t\t * @param {{success}, *} options\n\t\t\t * @returns {*}\n\t\t\t */\n\t\t\tsync: function( method, model, options ) {\n\t\t\t\toptions = options || {};\n\t\t\t\tvar beforeSend = options.beforeSend;\n\n\t\t\t\tif ( typeof WP_API_Settings.nonce !== 'undefined' ) {\n\t\t\t\t\toptions.beforeSend = function( xhr ) {\n\t\t\t\t\t\txhr.setRequestHeader( 'X-WP-Nonce', WP_API_Settings.nonce );\n\n\t\t\t\t\t\tif ( beforeSend ) {\n\t\t\t\t\t\t\treturn beforeSend.apply( this, arguments );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif ( 'read' === method ) {\n\t\t\t\t\tvar SELF = this;\n\n\t\t\t\t\tif ( options.data ) {\n\t\t\t\t\t\tSELF.state.data = _.clone( options.data );\n\n\t\t\t\t\t\tdelete SELF.state.data.page;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tSELF.state.data = options.data = {};\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( typeof options.data.page === 'undefined' ) {\n\t\t\t\t\t\tSELF.state.currentPage = null;\n\t\t\t\t\t\tSELF.state.totalPages = null;\n\t\t\t\t\t\tSELF.state.totalObjects = null;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tSELF.state.currentPage = options.data.page - 1;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar success = options.success;\n\t\t\t\t\toptions.success = function( data, textStatus, request ) {\n\t\t\t\t\t\tSELF.state.totalPages = parseInt( request.getResponseHeader( 'X-WP-TotalPages' ), 10 );\n\t\t\t\t\t\tSELF.state.totalObjects = parseInt( request.getResponseHeader( 'X-WP-Total' ), 10 );\n\n\t\t\t\t\t\tif ( SELF.state.currentPage === null ) {\n\t\t\t\t\t\t\tSELF.state.currentPage = 1;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tSELF.state.currentPage++;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( success ) {\n\t\t\t\t\t\t\treturn success.apply( this, arguments );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn Backbone.sync( method, model, options );\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Fetches the next page of objects if a new page exists\n\t\t\t *\n\t\t\t * @param {data: {page}} options\n\t\t\t * @returns {*}\n\t\t\t */\n\t\t\tmore: function( options ) {\n\t\t\t\toptions = options || {};\n\t\t\t\toptions.data = options.data || {};\n\n\t\t\t\t_.extend( options.data, this.state.data );\n\n\t\t\t\tif ( typeof options.data.page === 'undefined' ) {\n\t\t\t\t\tif ( ! this.hasMore() ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.state.currentPage === null || this.state.currentPage <= 1 ) {\n\t\t\t\t\t\toptions.data.page = 2;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.data.page = this.state.currentPage + 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn this.fetch( options );\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Returns true if there are more pages of objects available\n\t\t\t *\n\t\t\t * @returns null|boolean\n\t\t\t */\n\t\t\thasMore: function() {\n\t\t\t\tif ( this.state.totalPages === null ||\n\t\t\t\t\t this.state.totalObjects === null ||\n\t\t\t\t\t this.state.currentPage === null ) {\n\t\t\t\t\treturn null;\n\t\t\t\t} else {\n\t\t\t\t\treturn ( this.state.currentPage < this.state.totalPages );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t);\n\n\t/**\n\t * Backbone collection for posts\n\t */\n\twp.api.collections.Posts = BaseCollection.extend(\n\t\t/** @lends Posts.prototype */\n\t\t{\n\t\t\turl: WP_API_Settings.root + '/posts',\n\n\t\t\tmodel: wp.api.models.Post\n\t\t}\n\t);\n\n\t/**\n\t * Backbone collection for pages\n\t */\n\twp.api.collections.Pages = BaseCollection.extend(\n\t\t/** @lends Pages.prototype */\n\t\t{\n\t\t\turl: WP_API_Settings.root + '/pages',\n\n\t\t\tmodel: wp.api.models.Page\n\t\t}\n\t);\n\n\t/**\n\t * Backbone users collection\n\t */\n\twp.api.collections.Users = BaseCollection.extend(\n\t\t/** @lends Users.prototype */\n\t\t{\n\t\t\turl: WP_API_Settings.root + '/users',\n\n\t\t\tmodel: wp.api.models.User\n\t\t}\n\t);\n\n\t/**\n\t * Backbone post statuses collection\n\t */\n\twp.api.collections.PostStatuses = BaseCollection.extend(\n\t\t/** @lends PostStatuses.prototype */\n\t\t{\n\t\t\turl: WP_API_Settings.root + '/posts/statuses',\n\n\t\t\tmodel: wp.api.models.PostStatus\n\n\t\t}\n\t);\n\n\t/**\n\t * Backbone media library collection\n\t */\n\twp.api.collections.MediaLibrary = BaseCollection.extend(\n\t\t/** @lends MediaLibrary.prototype */\n\t\t{\n\t\t\turl: WP_API_Settings.root + '/media',\n\n\t\t\tmodel: wp.api.models.Media\n\t\t}\n\t);\n\n\t/**\n\t * Backbone taxonomy collection\n\t */\n\twp.api.collections.Taxonomies = BaseCollection.extend(\n\t\t/** @lends Taxonomies.prototype */\n\t\t{\n\t\t\tmodel: wp.api.models.Taxonomy,\n\n\t\t\turl: WP_API_Settings.root + '/taxonomies'\n\t\t}\n\t);\n\n\t/**\n\t * Backbone comment collection\n\t */\n\twp.api.collections.Comments = BaseCollection.extend(\n\t\t/** @lends Comments.prototype */\n\t\t{\n\t\t\tmodel: wp.api.models.Comment,\n\n\t\t\tpost: null,\n\n\t\t\t/**\n\t\t\t * @class Represent an array of comments\n\t\t\t * @augments Backbone.Collection\n\t\t\t * @constructs\n\t\t\t */\n\t\t\tinitialize: function( models, options ) {\n\t\t\t\tthis.constructor.__super__.initialize.apply( this, arguments );\n\n\t\t\t\tif ( options && options.post ) {\n\t\t\t\t\tthis.post = options.post;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Return URL for collection\n\t\t\t *\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\turl: function() {\n\t\t\t\treturn WP_API_Settings.root + '/posts/' + this.post + '/comments';\n\t\t\t}\n\t\t}\n\t);\n\n\t/**\n\t * Backbone post type collection\n\t */\n\twp.api.collections.PostTypes = BaseCollection.extend(\n\t\t/** @lends PostTypes.prototype */\n\t\t{\n\t\t\tmodel: wp.api.models.PostType,\n\n\t\t\turl: WP_API_Settings.root + '/posts/types'\n\t\t}\n\t);\n\n\t/**\n\t * Backbone terms collection\n\t */\n\twp.api.collections.Terms = BaseCollection.extend(\n\t\t/** @lends Terms.prototype */\n\t\t{\n\t\t\tmodel: wp.api.models.Term,\n\n\t\t\ttype: 'post',\n\n\t\t\ttaxonomy: 'category',\n\n\t\t\t/**\n\t\t\t * @class Represent an array of terms\n\t\t\t * @augments Backbone.Collection\n\t\t\t * @constructs\n\t\t\t */\n\t\t\tinitialize: function( models, options ) {\n\t\t\t\tthis.constructor.__super__.initialize.apply( this, arguments );\n\n\t\t\t\tif ( typeof options !== 'undefined' ) {\n\t\t\t\t\tif ( options.type ) {\n\t\t\t\t\t\tthis.type = options.type;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( options.taxonomy ) {\n\t\t\t\t\t\tthis.taxonomy = options.taxonomy;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.on( 'add', _.bind( this.addModel, this ) );\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * We need to set the type and taxonomy for each model\n\t\t\t *\n\t\t\t * @param {Backbone.model} model\n\t\t\t */\n\t\t\taddModel: function( model ) {\n\t\t\t\tmodel.type = this.type;\n\t\t\t\tmodel.taxonomy = this.taxonomy;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Return URL for collection\n\t\t\t *\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\turl: function() {\n\t\t\t\treturn WP_API_Settings.root + '/posts/types/' + this.type + '/taxonomies/' + this.taxonomy + '/terms/';\n\t\t\t}\n\t\t}\n\t);\n\n\t/**\n\t * Backbone revisions collection\n\t */\n\twp.api.collections.Revisions = BaseCollection.extend(\n\t\t/** @lends Revisions.prototype */\n\t\t{\n\t\t\tmodel: wp.api.models.Revision,\n\n\t\t\tparent: null,\n\n\t\t\t/**\n\t\t\t * @class Represent an array of revisions\n\t\t\t * @augments Backbone.Collection\n\t\t\t * @constructs\n\t\t\t */\n\t\t\tinitialize: function( models, options ) {\n\t\t\t\tthis.constructor.__super__.initialize.apply( this, arguments );\n\n\t\t\t\tif ( options && options.parent ) {\n\t\t\t\t\tthis.parent = options.parent;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * return URL for collection\n\t\t\t *\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\turl: function() {\n\t\t\t\treturn WP_API_Settings.root + '/posts/' + this.parent + '/revisions';\n\t\t\t}\n\t\t}\n\t);\n\n})( wp, WP_API_Settings, Backbone, _, window );"
  },
  {
    "path": "public/assets/js/tour.js",
    "content": "(function( $ ) {\n\t\t\t\t\t\tjQuery(document).ready(function($){\n\n\t\t\t\t\t\t\t$('body').addClass('lasso-modal-open');\n\n\t\t\t\t\t\t\t$('.lasso--loading').remove();\n\t\t\t\t\t\t\t$('#lasso--tour__slides').hide().fadeIn()\n\n\t\t\t\t\t\t\t$('#lasso--tour__slides').unslider({\n\t\t\t\t\t\t\t\tdots: true,\n\t\t\t\t\t\t\t\tdelay:7000\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t});\n\t\t\t\t\t})( jQuery );"
  },
  {
    "path": "public/assets/less/source/all-posts.less",
    "content": "// modal outer\n.lasso--modal{\n    top:10vh;\n\n    &.lasso--modal__full {\n\n        width:100%;\n        max-width:@modal--width__full;\n\n        .lasso--modal__inner {\n            display: block;\n            padding:@modal--padding * 2;\n            .clearfix();\n        }\n    }\n\n}\n\n#lasso--all-posts__modal {\n\n    #lasso--loading {\n        position: absolute;\n        height:90%;\n    }\n\n}\n\nul.lasso--post-object-list,\nul.lasso--post-list {\n    text-align: left;\n    list-style:none;\n    margin:0;\n    padding:0;\n\n    li {\n        display: block;\n        position: relative;\n        width:100%;\n        list-style-type: none;\n        margin-bottom:7px;\n        font-size:@modal--font__size;\n        font-family: @editor--font;\n        font-weight:bold;\n    }\n}\n\n// post object list\nul.lasso--post-object-list {\n    width:@list--sb__width;\n    float:left;\n    height:100%;\n\n    li {\n        line-height: @list--item__line-height / 2;\n        margin-bottom: 0;\n        font-family: @editor--font;\n        font-weight: normal;\n        .transition(opacity .15s ease);\n\n        &:not(.active) {\n            .opacity(0.45);\n        }\n\n        &:hover {\n            cursor: pointer;\n            .opacity(1);\n        }\n\n    }\n\n}\n\n// post filtering\n.lasso--post-filtering {\n    padding:0 @search--padding;\n    width: ~'calc( 100% - @{list--sb__width})';\n    height:@search--height;\n    float:right;\n    .clearfix();\n\n    .lasso--search__results,\n    .lasso--search {\n        float:left;\n    }\n\n    // search results div\n    .lasso--search__results {\n        opacity:0;\n        .transition(opacity .2s ease);\n        width:60%;\n        font-size:@input--font__size;\n\n        span {\n            font-weight:bold;\n            margin-right:4px;\n        }\n    }\n\n    // teh search input contianer\n    .lasso--search {\n        width:40%;\n        overflow: hidden;\n        position: relative;\n\n        #lasso--search__toggle,\n        input {\n            .transition(right .15s linear);\n        }\n\n        // icon\n        #lasso--search__toggle {\n            position: relative;\n            top: @search--icon__offset / 2;\n            right: -@search--input__size - @search--icon__offset;\n\n            &:before {\n                .opacity(0.5);\n                .transition(opacity .15s ease);\n            }\n\n            &:hover {\n                cursor: pointer;\n                &:before { .opacity(0.9); }\n            }\n        }\n\n        // the input\n        input {\n            float:right;\n            width:@search--input__size;\n            right:-@search--input__size;\n            .editor--input();\n            height:@input--height + 2;\n\n            &:focus {\n                box-shadow:none;\n            }\n        }\n\n        // when visible\n        &.lasso--search__visible {\n\n            #lasso--search__toggle {\n                right:-@search--icon__offset;\n\n                &:before { .opacity(0.9); }\n                &:hover:before { .opacity(0.5); }\n            }\n\n            input { right:0; }\n        }\n    }\n}\n\n// Character helper\n#lasso--helper {\n    position:absolute;\n    right:4px;\n    top:4px;\n    font-size:@modal--font__size - 2;\n    padding:2px 6px;\n    background:@modal--bg__accent;\n    color:white;\n    border-radius:2px;\n    font-family:Arial;\n}\n\n\n// Clear Search Icon\n#lasso--clear-search {\n    position:absolute;\n    right:7px;\n    top:7px;\n    color:@modal--color-dark;\n    z-index:1;\n\n    &:hover {\n        color:darken(@modal--color-dark,5);\n        cursor:pointer;\n    }\n}\n\n\n// empty state\n.lasso--empty-state {\n    max-width:200px;\n    text-align:center;\n    color:@gray;\n    margin: 0 auto;\n    top: 40%;\n    position: relative;\n\n    .lasso--empty-state-icon {\n        font-size:@icon--size__large;\n    }\n\n    p {\n        margin-bottom:0;\n        font-family:@editor--font;\n        font-size:90%;\n        font-weight:bold;\n\n        + a {\n            margin-top:@editor--padding;\n        }\n    }\n}\n\n\n// list of posts\nul.lasso--post-list {\n    float:left;\n    padding:0 @modal--padding;\n    width: ~'calc( 100% - @{list--sb__width})';\n    overflow:hidden;\n    position: relative;\n    height:520px;\n    border-left:1px solid @base--dark;\n    .box-shadow(inset 1px 0 1px -1px rgba(255,255,255,0.15));\n\n    li {\n        overflow: hidden;\n        line-height: @list--item__line-height;\n    }\n\n    .lasso--post-list__item {\n        color:@modal--color-dark;\n        display: block;\n        padding:@list--item__padding;\n        background: fadeout(@list--item__bg,25);\n        text-decoration: none;\n        border-radius: @editor--radius;\n        .transition(all .15s ease);\n        font-family: @editor--font;\n        font-weight: normal;\n        width:100%;\n        overflow: hidden;\n        white-space: nowrap;\n        text-overflow: ellipsis;\n\n        // post status\n        &:before {\n            content:'';\n            height:@status--h;\n            width:@status--w;\n            border-radius: 100%;\n            margin-right: @status--h;\n            display: inline-block;\n        }\n\n        &.draft:before { background:@status--draft; }\n        &.publish:before { background:@status--publish; }\n        &.pending:before { background:@status--pending; }\n\n        &:hover{\n            background: @list--item__bg;\n            text-decoration: none;\n            width:~'calc( 100% - @{list--control__width})';\n\n            .lasso--post-list__controls {\n                right:0;\n            }\n        }\n\n        &:active {\n            outline: none;\n            background: @list--item__bg;\n            text-decoration: none;\n            .box-shadow(inset 1px 1px 2px rgba(0,0,0,0.5));\n        }\n\n        &:focus {\n            outline: none;\n        }\n\n        &.no-delete:hover {\n            @new-width: @list--control__width / 2;\n\n            width:~'calc( 100% - @{new-width})';\n\n        }\n\n    }\n\n}\n\n// post controls within a list\n.lasso--post-list__controls {\n    position: absolute;\n    right:0;\n    top:0;\n    width:@list--control__width;\n    text-align: right;\n    right:-@list--control__width;\n    height:@list--item__line-height;\n    .transition(right .15s ease);\n\n    span {\n        color:darken(@modal--color,50);\n        display: inline-block;\n        width:@list--item__line-height;\n        height:@list--item__line-height;\n        background: @list--item__bg;\n        border-radius: @editor--radius;\n        position: relative;\n\n        &:after {\n            .editor-icon-font();\n            text-align: center;\n            font-size:18px;\n            position: absolute;\n            z-index: 2;\n            top:16px;\n            left:16px;\n        }\n\n        &:hover {\n            color:darken(@modal--color,50);\n            background: fadeout(@modal--bg__accent,50);\n        }\n        &:active {\n            background: @list--item__bg;\n            text-decoration: none;\n            .box-shadow(inset 1px 1px 2px rgba(0,0,0,0.5));\n        }\n    }\n\n    #lasso--post__edit{\n        margin-right:3px;\n        &:hover {\n            color:@modal--color;\n            background: @editor--color__update;\n        }\n        &:after {\n            content:'\\e908';\n        }\n    }\n\n    #lasso--post__delete{\n        &:hover {\n            color:@modal--color;\n            background: @editor--color__error;\n        }\n        &:after {\n            content:'\\e9ad';\n        }\n    }\n}\n\n// load more\n#lasso--load-more, #lasso--close-modal-posts {\n    .editor-btn-secondary();\n    font-size:@input--font__size;\n    text-transform: uppercase;\n    line-height:2;\n    margin-top:@editor--padding;\n    .opacity(0.66);\n}\n\n\n.editus-firstp:empty:before{\n  content:attr(placeholder);\n  color:grey;\n  font-style:italic;\n}"
  },
  {
    "path": "public/assets/less/source/animations.less",
    "content": ".lasso-editing {\n\n    .aesop-content-comp-wrap,\n    .aesop-video-container,\n    .aesop-image-component-image {\n        .transition(all .25s linear);\n    }\n}\n.lassoShowAnimate {\n    -webkit-animation: lassoShowAnimate 0.2s;\n    -moz-animation: lassoShowAnimate 0.2s;\n    animation: lassoShowAnimate 0.2s;\n}\n.lassoHideAnimate {\n    -webkit-animation: lassoHideAnimate 0.2s;\n    -moz-animation: lassoHideAnimate 0.2s;\n    animation: lassoHideAnimate 0.2s;\n}\n@-webkit-keyframes lassoShowAnimate {\n  0% {\n    transform: scale(0.7);\n    -webkit-transform: scale(0.7); }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1); } \n}\n@-moz-keyframes lassoShowAnimate {\n  0% {\n    transform: scale(0.7);\n    -webkit-transform: scale(0.7); }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1); } \n}\n@keyframes lassoShowAnimate {\n  0% {\n    transform: scale(0.7);\n    -webkit-transform: scale(0.7); }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1); } \n}\n@-webkit-keyframes lassoHideAnimate {\n  0% {\n    transform: scale(1);\n    -webkit-transform: scale(1); }\n  100% {\n    transform: scale(0.5);\n    -webkit-transform: scale(0.5); } }\n@-moz-keyframes lassoHideAnimate {\n  0% {\n    transform: scale(1);\n    -webkit-transform: scale(1); }\n  100% {\n    transform: scale(0.5);\n    -webkit-transform: scale(0.5); } }\n@keyframes lassoHideAnimate {\n  0% {\n    transform: scale(1);\n    -webkit-transform: scale(1); }\n  100% {\n    transform: scale(0.5);\n    -webkit-transform: scale(0.5); } }\n"
  },
  {
    "path": "public/assets/less/source/component-controls.less",
    "content": "// draggable handle\nul.lasso-component--controls {\n    * { .box-sizing(border-box); }\n    .editor--tool__bg();\n    position: absolute;\n    margin:0;\n    padding:0;\n    line-height:1;\n    height:@component-controls--height;\n    width:@component-controls--width;\n    top:4px;\n    //right:0;\n    //left:-10000px;\n    text-align: center;\n    margin: 0 auto;\n    border-radius:@editor--radius - 2;\n    .clearfix();\n    .opacity(0);\n    .transition(opacity .4s ease);\n    z-index: 105;\n    padding-left:0;\n    \n    &.editus-center {\n       left:0;\n       right:0;\n    }\n    &.editus-right {\n       right:0;\n    }\n\n    li {\n        float:left;\n        list-style-type: none;\n        line-height: 1;\n\t\tmargin: 0;\n        width:@component-controls--width / 4.1;\n        height:@component-controls--height - 2;\n        border-right:1px solid lighten(@toolbar--border,5);\n        text-align: center;\n        text-shadow:0 1px 1px rgba(0,0,0,0.4);\n\n        &:before {\n            .editor-icon-font();\n            position: relative;\n            top:1px;\n            font-size:@component-controls--font__size;\n        }\n\n        &:first-child:hover {\n            border-bottom-left-radius: @component-controls--radius;\n            border-top-left-radius: @component-controls--radius;\n        }\n\n        &:hover {\n            cursor: pointer;\n            background:@toolbar--hover;\n        }\n\n        &:active {\n            .box-shadow(inset 0 0 6px -2px rgba(0,0,0,0.66));\n        }\n\n        &:last-child {\n            border-right:none;\n\n            &:hover {\n                border-top-right-radius: @component-controls--radius;\n                border-bottom-right-radius: @component-controls--radius;\n            }\n        }\n\n        &.lasso-drag{\n            cursor:move ;\n            &:hover {\n                cursor:move;\n            }\n            &:before {\n                content:'\\e600';\n            }\n        }\n\n        &.lasso-settings:before {\n            content:'\\e994';\n        }\n\n        &.lasso-clone:before {\n            content:'\\e92c';\n        }\n        &.lasso-delete:before {\n            content:'\\e9ad';\n        }\n    }\n\n}\n\n\n.lasso-editing .aesop-component:hover, .lasso-editing .wp-block-cover:hover {\n .lasso-component--controls{\n    left:4px;\n    .opacity(1);\n }\n}\n\n// misc\n.aesop-timeline-stop .lasso-component--controls li {\n    line-height:16px;\n}\n.aesop-image-component[data-align=\"right\"]:hover .lasso-component--controls,\n.aesop-image-component[data-align=\"left\"]:hover .lasso-component--controls {\n    margin:13px 0 0 4px;\n}\n.aesop-image-component[data-align=\"right\"]:hover .lasso-component--controls {\n    left:auto;\n}\n.lasso-component {\n  position:relative;\n}\n\n.editus_shortcode_p {\n  position: relative;\n}\n\n.editus_shortcode {\n  .editor--tool__bg();\n  .transition(opacity .4s ease);\n  margin: auto;\n  text-align: center;\n  width: 200px;\n  z-index: 105;\n  position: absolute;\n  left: 0;\n  right: 0;\n  top:0;\n  opacity:0.5;\n  border-radius:4px;\n}\n\n.editus_shortcode_p:hover .editus_shortcode {\n  opacity:1;\n}\n\n@media ( max-width:768 ) { \n\t.editus_shortcode_p .editus_shortcode {\n\t  opacity:1;\n\t}\n}"
  },
  {
    "path": "public/assets/less/source/component-settings--gallery.less",
    "content": "\n// gallery thumb images container\n#lasso--gallery__images {\n    min-height: 65px;\n    position: relative;\n\n    .lasso-icon-spinner6 {\n        position: relative;\n        left: 135px;\n        top: 18px;\n        -webkit-animation: spin 2s infinite linear;\n        animation: spin 2s infinite linear;\n        font-size: 16px;\n    }\n}\n\n.editor-btn-secondary {\n    .editor-btn-secondary();\n}\n// gallery images ul\n#ase-gallery-images {\n    margin:0 -7px;\n    border-radius: @editor--radius;\n    padding:2px;\n    .clearfix();\n    .transition(background .15s ease);\n    .ui-state-highlight { height: 1.5em; line-height: 1.2em; }\n}\n\n// single gallery image\n.ase-gallery-image {\n    position:relative;\n    float:left;\n    margin:4px;\n    .transition(transform .1s ease);\n    list-style:none;\n    i {\n        top:3px;\n        position: absolute;\n        z-index:1;\n        color:white;\n        font-size:16px;\n        text-shadow:0 1px 1px rgba(0,0,0,0.5);\n        .opacity(0.6);\n        .transition(all .2s ease);\n\n        &:hover {\n            cursor: pointer;\n            .opacity(1.0);\n            .scale(1.1);\n        }\n\n        &:active {\n            .scale(1);\n            box-shadow:none;\n        }\n    }\n\n    .dashicons-edit {\n        left:3px;\n    }\n    .dashicons-no-alt {\n        right:2px;\n    }\n\n    img{\n        max-width:54px;\n        border-radius:2px;\n        .transition(opacity .15s ease);\n    }\n\n    // being dragged\n    &.ui-sortable-helper {\n        -ms-transform: rotate(7deg); /* IE 9 */\n        -webkit-transform: rotate(7deg); /* Chrome, Safari, Opera */\n        transform: rotate(7deg);\n    }\n\n    &:hover {\n        cursor: move;\n\n        img {\n            .opacity(0.66);\n        }\n    }\n}\n.ase-gallery-opts--edit-gallery:hover {\n    // gallery images ul\n    #ase-gallery-images {\n        background:@toolbar--bg__dark;\n        .box-shadow(inset 0 -1px 1px rgba(255,255,255,0.1));\n    }\n}\n\n// add image\n.lasso-editor-tiny-btn {\n    .tiny-circle-btn( @toolbar--bg__dark, fadeout(@toolbar--color,20) );\n}\n#lasso--gallery__create {\n    //position: absolute;\n    //right:12px;\n}\n#ase-gallery-add-image {\n    position: absolute;\n    right:12px;\n    font-size: 9px;\n}\n\n// dropzone\n.ase-gallery-drop-zone {\n    border: 1px solid @toolbar--bg;\n    background: @toolbar--bg__accent;\n    color: #363636;\n    width:54px;\n    height:54px;\n    float:left;\n    margin:4px;\n    border-radius:2px;\n}\n\n// specificity\n#lasso--component__settings .ase-gallery-layout-label {\n    font-size:12px;\n}\n\n// gallery layout picker\n.ase-gallery-opts--type{\n\n    position: relative;\n\n    h3 {\n        margin:0;\n    }\n\n    input[type=\"radio\"] {\n        position: absolute;\n        opacity: 0;\n        z-index: -1;\n    }\n\n    .ase-gallery-layout-label {\n        position: relative;\n        float:left;\n        height:68px;\n        width:78px;\n        overflow: hidden;\n        text-align: center;\n        background:@toolbar--bg__accent;\n        padding:5px;\n        box-sizing:border-box;\n        border:1px solid @toolbar--bg__dark;\n        .transition(opacity .15s ease);\n        .opacity(0.3);\n        margin-right:2px;\n        font-weight:normal;\n\n        &:last-of-type {\n            margin-right: 0 !important;\n        }\n\n        &:after {\n            content:'';\n            background-image:url('../img/layout-sprite.png');\n            background-size:84%;\n            position: absolute;\n            height:42px;\n            display: block;\n            left:0;\n            right:0;\n            bottom:0;\n        }\n\n        &:hover {\n            .opacity(1);\n            cursor: pointer;\n        }\n\n        &:active {\n            background:darken(@toolbar--bg__accent,4);\n            .box-shadow(inset 0 0 6px -1px rgba(0,0,0,0.5));\n        }\n    }\n\n    .selected {\n        .box-shadow(inset 0 0 12px -2px rgba(0,0,0,0.5));\n        .opacity(1);\n\n    }\n\n    label:first-of-type:after {\n        background-position: 5px -9px;\n    }\n    label:nth-of-type(2):after {\n        background-position: 5px -52px;\n    }\n    label:nth-of-type(3):after {\n        background-position: 5px -99px;\n    }\n    label:nth-of-type(4):after {\n        background-position: 5px -145px;\n    }\n\tlabel:nth-of-type(5):after {\n        background-position: 5px -191px;\n    }\n    label:last-of-type:after {\n        background-position: 5px -235px;\n    }\n}\n.ase-gallery-opts {\n    .transition(opacity .25s ease);\n}\n\n// empty gallery placholder\n.lasso--empty-component {\n    height:0;\n    .opacity(0);\n    text-align: center;\n    color:@input--color;\n    font-family: @editor--font;\n    font-size:@toolbar--font__size;\n    .transition(all .2s linear);\n\n    span {\n        position: relative;\n        top:2px;\n    }\n}\n.lasso-editing {\n\n    .lasso--empty-component + .aesop-map-component,\n    .aesop-gallery-component.empty-gallery {\n        .lasso-component--controls {\n            .opacity(1);\n            left:0;\n        }\n    }\n    .lasso--empty-component {\n        height:150px;\n        padding-top:75px;\n        .opacity(1);\n    }\n}\n#lasso--component__settings.gallery-no-images {\n    .ase-gallery-opts:not(.ase-gallery-opts--create-gallery) {\n        display: none;\n    }\n}\n// no galleries\n#lasso--component-settings-form{\n    &.creating-gallery {\n        .lasso-option.lasso-gallery-id {\n            display: none;\n        }\n    }\n    &.has-galleries {\n        .ase-gallery-opts--create-gallery {\n            display: none;\n        }\n    }\n    &.hide-all-fields .ase-gallery-opts {\n        .opacity(0);\n    }\n}\n\n\n"
  },
  {
    "path": "public/assets/less/source/component-settings--map.less",
    "content": "#lasso--map-form {\n    position: relative;\n\n    .lasso--map-form__submit {\n        position: absolute;\n        top:10px;\n        right:10px;\n        z-index: 1000;\n        background: @editor--color__update;\n        border:1px solid darken(@editor--color__update,2);\n        padding:8px 12px;\n        font-size: 14px;\n        line-height: 1.2;\n        font-family: @editor--font;\n        text-shadow:1px 1px rgba(0,0,0,0.1);\n        .box-shadow(0 0 5px -1px rgba(0,0,0,0.4));\n\n        &:active,\n        &:focus {\n            outline:none;\n        }\n\n        &:hover {\n            background:darken(@editor--color__update,10);\n            border:1px solid darken(@editor--color__update,12);\n        }\n\n        &:active {\n            box-shadow: none;\n        }\n    }\n}\n\n#lasso--map-form {\n\n    margin-top: 10px;\n\n    // marker wrap\n    .leaflet-popup-content-wrapper, \n    .leaflet-popup-tip {\n        border-radius:4px;\n\n        input {\n            font-size: 14px;\n            border-radius: 0;\n            padding:3px 5px;\n            width:200px;\n            display: inline-block;\n            line-height: 1;\n        }\n    }\n\n    // inner marker content\n    .leaflet-popup-content {\n        margin:10px;\n    }\n\n    // hide the close button because teh update button closes\n    .leaflet-popup-close-button {\n        position: absolute;\n        left:-10000px;\n        height:0;\n    }\n\n    //marker buttons\n    .marker-update-button,\n    .marker-delete-button {\n        border-radius:0;\n        color:white;\n        box-shadow:none;\n        border:none;\n        border-radius:3px;\n        display: inline-block;\n        height:25px;\n        width:25px;\n        vertical-align: top;\n        .box-sizing(border-box);\n        text-align: center;\n\n        &:hover {\n            cursor: pointer;\n        }\n\n        &:active {\n            outline:none;\n            focus:none;\n            box-shadow: none;\n        }\n\n        &:before {\n            position: relative;\n            text-align: center;\n        }\n    }\n    .marker-update-button {\n        background:@editor--color__update;\n\n        &:hover {\n            background:darken(@editor--color__update,6);\n        }\n        &:active {\n            background:darken(@editor--color__update,10);\n        }\n\n        &:before {\n            top:1px;\n            left:-1px;\n            font-size:24px;\n        }\n    }\n    .marker-delete-button {\n        background:@editor--color__error;\n\n        &:hover {\n            background:darken(@editor--color__error,6);\n        }\n        &:active {\n            background:darken(@editor--color__error,10);\n        }\n\n        &:before {\n            font-size:17px;\n            top:1px;\n            left:1px;\n        }\n    }\n}\n\n// hide the clone setting on the map\n.aesop-map-component .lasso-component--controls {\n    width:91px;\n    z-index: 9999;\n    .lasso-clone {\n        display: none;\n    }\n}\n\n// account for sticky maps\n.aesop-sticky-map {\n    #lasso--map-form .lasso-component--controls {\n        position: fixed;\n        z-index: 9999;\n        width:61px;\n\n        .lasso-drag {\n            display: none;\n        }\n    }\n    &.aesop-sticky-map-left #lasso--map-form .lasso-component--controls{\n        left: 183px;\n        right: auto;\n    }\n    &.aesop-sticky-map-right #lasso--map-form .lasso-component--controls{\n        right: 183px;\n        left: auto;\n    }\n}\n"
  },
  {
    "path": "public/assets/less/source/component-settings.less",
    "content": "#lasso--component__settings {\n\n    form {\n        margin:0;\n        position: relative;\n        padding-bottom:@insert--height; // height of insert\n    }\n\n    label,\n     .lasso-option-desc {\n        display: block;\n        line-height: 1.3;\n    }\n\n    // option label\n    h3,\n    label {\n        font-weight:bold;\n        margin-bottom: 3px;\n        font-size: @sidebar--font__size;\n    }\n\n    .lasso-option-desc {\n        margin-bottom: 5px;\n        font-size: @sidebar--font__size - 2.75;\n    }\n\n\n    // general textarea and input styles\n    input[type=\"text\"],\n    input[type=\"text_small\"],\n    input[type=\"media_upload\"],\n    textarea,\n    select {\n        background:@input--bg;\n        width:100%;\n        height:@input--height;\n        border:1px solid @input--border;\n        border-radius:@editor--radius;\n        line-height:1.8;\n        padding:0 6px;\n        color:@input--color;\n        .box-shadow(inset 1px 1px 1px rgba(0,0,0,.4));\n        font-size: @sidebar--font__size;\n        &:focus {\n            box-shadow: none;\n            outline:none;\n            border:1px solid @editor--color__update;\n        }\n    }\n\n    // color picker\n    input[type=\"color\"] {\n        border-radius: @editor--radius - 1;\n        border:1px solid @input--border;\n        padding:0 2px;\n        height:@input--height;\n        display: block;\n        &:active,\n        &:focus {\n            box-shadow: none;\n            outline:none;\n            border:1px solid @editor--color__update;\n        }\n    }\n\n    select {\n        height:@input--height;\n        box-shadow: none;\n    }\n\n    textarea {\n        overflow: auto;\n        margin:0;\n        line-height:1.15;\n        padding:6px;\n        height:auto;\n    }\n\n    // media upload treatment\n    input[type=\"media_upload\"] {\n        height:@input--height;\n    }\n\n    input[type=\"submit\"],\n    .lasso-generator-cancel {\n        .editor-btn-primary();\n        font-size:15px;\n    }\n\n    // option button/media upload\n    .lasso-option-button {\n        position: absolute;\n        bottom:21px;\n        right:21px;\n        background-color: @sidebar--button__bg;\n        border-color: @sidebar--button__border;\n        .transition(background .15s ease);\n        .box-shadow(0 1px 1px rgba(0,0,0,0.25));\n\n        &:hover {\n            text-decoration: none;\n            background:darken(@sidebar--button__bg,6);\n        }\n\n        &:active,\n        &:focus {\n            outline:none;\n            text-decoration: none;\n            border-color:darken(@sidebar--button__border,5);\n            background:darken(@sidebar--button__bg,10);\n            transition:none;\n            .box-shadow(inset 1px 1px rgba(0,0,0,0.4));\n        }\n    }\n\n    #lasso-upload-img {\n        height:28px;\n        padding:8px;\n        border-top-right-radius: @editor--radius - 1;\n        border-bottom-right-radius: @editor--radius - 1;\n        .editor-icon-font();\n\n        &:before {\n            content:'\\e9c6';\n            position: relative;\n            color:@input--bg;\n        }\n\n    }\n\n    .lasso-generator-cancel {\n        background:none;\n        color:@editor--color__error;\n        position: relative;\n        top: -1px;\n\n        &:hover {\n            color:lighten(@editor--color__error,2);\n            background:transparent;\n            text-decoration: none;\n        }\n\n        &:active {\n            color:darken(@editor--color__error,2);\n            box-shadow:none;\n        }\n    }\n}\n\n\n// single option\n.lasso-option {\n    position: relative;\n    border-bottom:1px solid @input--border;\n    margin:0;\n    padding:15px @sidebar--padding @sidebar--padding;\n    .clearfix();\n    .box-shadow(0 1px 1px rgba(255,255,255,0.05));\n    .transition(background .15s ease);\n\n    &:hover {\n        background: fadeout(@sidebar--bg__accent,50);\n    }\n}\n\n// update setting button\n.lasso-buttoninsert-wrap {\n    display: none;\n    margin:0 auto;\n    position: fixed;\n    text-align: right;\n    padding:@editor--padding__lg;\n    bottom:0;\n    width:@sidebar--width - 4;\n    height:@insert--height;\n    background:@sidebar--bg__accent;\n    right:-@sidebar--width - 4;\n    z-index: 1; //clears scroll\n    .clearfix();\n    .box-sizing(border-box);\n    .transition(right .25s ease);\n    .box-shadow(0 -10px 10px -10px rgba(0,0,0,1));\n}\n#lasso-generator-insert { // save\n    text-align: center;\n    float: right;\n    display:block;\n    margin:0 15px;\n    padding:6px 10px;\n    border-radius:@editor--radius - 2;\n    background:@sidebar--buttonInsert__bg;\n    border:1px solid @sidebar--buttonInsert__border;\n    color:@sidebar--buttonInsert__color;\n\n    &:hover {\n        text-decoration: none;\n        background:darken(@sidebar--buttonInsert__bg,10);\n    }\n\n    &:active,\n    &:focus {\n        text-decoration: none;\n        outline:none;\n    }\n\n    &:active {\n        background:darken(@sidebar--buttonInsert__bg,15);\n        .box-shadow(inset 1px 1px rgba(0,0,0,0.4));\n    }\n\n    &.saved {\n        background: @editor--color__success;\n    }\n}\n\n// hide the content text option in the content comonent settings\n.lasso-c-comp-text {\n    position: absolute;\n    right:-10000px;\n    .opacity(0);\n    height:0;\n}"
  },
  {
    "path": "public/assets/less/source/editor-controls.less",
    "content": "// do not print\n@media print {\n\t#lasso--controls {\n        display: none;\n\t}\n}\n\n\n#lasso--controls{\n   .lasso--controls__center {\n    display:block;\n   }\n}\n\n\n// center controls containing the editor editor, settings, and add new post button\n.lasso--controls__center {\n\n    .center();\n\n    li {\n        list-style-type: none;\n        line-height: 0;\n    }\n\n}\n\n// save and publish controls\n.lasso--controls__right {\n    position: fixed;\n    right: -10000px;\n    bottom: @toolbar--pos__bottom;\n    z-index:9999;\n    .opacity(0);\n    .transition(opacity .3s ease);\n    text-align: right;\n\n    a {\n        display:inline-block;\n        vertical-align: bottom;\n        color:@control--color;\n        font-family:@editor--font;\n        font-style:normal;\n        font-size: @control--font__size;\n        padding:@control--padding;\n        border-radius: @editor--radius - 1;\n        height:@toolbar--height;\n        width:@toolbar--height + 4;\n        line-height: @toolbar--height - 1;\n        text-align: center;\n        .transition(opacity .15s ease);\n\n        &:hover,\n        &:active,\n        &:focus,\n        &:focus:before,\n        &:active:before{\n            color:@control--color;\n            text-decoration: none;\n        }\n\n        &:before {\n            color:white;\n            .editor-icon-font();\n        }\n\n        &:focus {\n            outline:none;\n        }\n\n    }\n}\n\n\n#lasso--edit{\n    //background: @toolbar--bg__accent;\n    border-top-left-radius: @editor--radius - 1;\n    border-bottom-left-radius: @editor--radius - 1;\n    &:before {\n        content:'\\e908';\n    }\n\n    //&:hover {\n    //    background: darken(@toolbar--bg__accent,3);\n    //}\n}\n#lasso--post-settings:before {\n    content:'\\f031';\n}\n#lasso--post-new:before {\n    content:'\\e603';\n\n}\n#lasso--post-revisions:before {\n    content:'\\e94d';\n\n}\n#lasso--post-all:before {\n    content:'\\e9ba';\n    font-size:15px;\n    top:11px;\n}\n\n//settings button\n#lasso--post-settings2, #lasso--post-delete {\n    background:@editor--color__update;\n    font-size: @control--font__size + 2;\n\n    &:before {\n        position: relative;\n        top:3px;\n        left:0;\n        //height:auto;\n\t\twidth:28px;\n\t\theight:28px;\n\t\t//content: url('wrench.svg');\n    }\n\n    &:hover {\n        background:darken(@editor--color__update,10);\n    }\n\n    &:active {\n        .box-shadow(inset 1px 1px 2px rgba(0,0,0,0.4));\n    }\n}\n\n#lasso--post-settings2 {\n\t&:before {\n        content:'\\f031';\n    }\n}\n\n#lasso--post-delete {\n\t&:before {\n        content:'\\E9AD';\n    }\n}\n\n\n// SAVE BUTTON\n#lasso--save {\n    background:@editor--color__update;\n    font-size: @control--font__size + 2;\n\n    &:before {\n        position: relative;\n        top:5px;\n        left:0;\n        //height:auto;\n\t\twidth:28px;\n\t\theight:28px;\n        content:'\\e601';\n\t\t//content: url('floppy.svg');\n    }\n\n    &:hover {\n        background:darken(@editor--color__update,10);\n    }\n\n    &:active {\n        .box-shadow(inset 1px 1px 2px rgba(0,0,0,0.4));\n    }\n\n    // post is being saved\n    &.being-saved:before {\n        content:'\\e97f';\n\t\ttop:4px;\n\t\twidth:22px;\n\t\theight:22px;\n        -webkit-animation: spin 2s infinite linear;\n        animation: spin 2s infinite linear;\n    }\n\n    // post has been saved\n    &.lasso--saved {\n\n        background:@editor--color__success;\n\n        &:before {\n            top:2px;\n            content:'\\ea10';\n        }\n\n    }\n    // post has an error saving\n    &.lasso--error {\n\n        background: @editor--color__error;\n\n        &:before {\n            content:'\\ea05';\n        }\n    }\n\n}\n\n// EXIT BUTTON\n#lasso--exit {\n    background: @editor--color__warning;\n    float: left;\n\n    &:before {\n        position: relative;\n        top:3px;\n        content:'\\ea0f';\n    }\n\n}\n\n\n// PUBLISH BUTTON (if post is in draft)\n#lasso--publish {\n    background: @editor--color__success;\n\n    &:before {\n        content:'\\e909';\n        position:relative;\n        top:2px;\n    }\n}\n\n\n\n// body class lasso is editing\n.lasso-editing {\n\n    #lasso--controls .lasso-editor-controls,\n    #lasso--post-settings,\n    #lasso--edit {\n        .opacity(0);\n        position: absolute;\n        left:-10000px\n    }\n\n    .lasso--controls__right {\n        .opacity(1);\n        right: @toolbar--pos__bottom;\n        left: @toolbar--pos__bottom;\n    }\n\n    .wp-audio-shortcode {\n        visibility: visible !important;\n    }\n\n}\n\n@-webkit-keyframes spin {\n    0% {\n         -webkit-transform: rotate(0deg);\n        transform: rotate(0deg);\n    }\n    100% {\n        -webkit-transform: rotate(359deg);\n        transform: rotate(359deg);\n    }\n}\n@keyframes spin {\n    0% {\n        -webkit-transform: rotate(0deg);\n        transform: rotate(0deg);\n    }\n    100% {\n        -webkit-transform: rotate(359deg);\n        transform: rotate(359deg);\n    }\n}"
  },
  {
    "path": "public/assets/less/source/editor.less",
    "content": ".aesop-component {\n    position: relative;\n}\n\n// missing wp media modal styles\n.screen-reader-text, .screen-reader-text span, .ui-helper-hidden-accessible {\n    position: absolute;\n    margin: -1px;\n    padding: 0;\n    height: 1px;\n    width: 1px;\n    overflow: hidden;\n    clip: rect(0 0 0 0);\n    border: 0;\n}\n\n// editable title\n*[contenteditable=\"true\"]:focus {\n    outline:none;\n}\n\n// title been edited\n.lasso-title-saved {\n    .transition(all .2s ease);\n    background:fadeout(white,90);\n}\n\n// drop zone\n.lasso-drop-zone {\n    .box-sizing(border-box);\n    height:@editor--dropzone__height;\n    background: @editor--dropzone__bg;\n    border:1px dashed @editor--dropzone__border;\n    list-style-type: none;\n    width:700px;\n    margin:0 auto 25px;\n    border-radius:@editor--radius - 1;\n\n    &:hover {\n        background: darken(@editor--dropzone__bg,15);\n    }\n}\n\n// component being dragged around on the page\n.lasso-drag-holder {\n    height:@editor--dropzone__height !important;\n    background:#d7d7d7;\n    text-align: center;\n    width:60px;\n\n    // each component has a data-component-type data attribute\n    // with the compents slug. That's used to add a class on drag\n    // which we use here to place icons as :before elements\n    //\n    // Custom modules must have this data-component-type so that\n    // you can style the draggable placeholder\n    .editor-icon-font();\n    .editor--icon__list();\n\n    &:before {\n        position: relative;\n        top:25px;\n        font-size:22px;\n    }\n}\n\n.lasso-editor{\n    //position: relative;\n    //min-height: 10px;\n\n    &:focus {\n        outline: none;\n        border: none;\n        box-shadow: none;\n    }\n\n    p:empty {\n        display: block;\n        //height: 1em;\n    }\n    // component item being dragged from toolbar to editor\n    .ui-draggable-dragging {\n        list-style-type: none;\n        height:50px;\n        padding:10px;\n        width:60px !important;\n        background:fadeout(@toolbar--bg,50);\n        text-align: center;\n        font-size:22px;\n        border-radius: @editor--radius;\n        .editor-icon-font();\n        .editor--icon__list();\n        .box-sizing(border-box);\n\n        &:before {\n            color:white;\n            position: relative;\n            top:4px;\n        }\n    }\n\n}\n.lasso-editor-clear{\n    background: transparent !important;\n    background-color: transparent !important;\n    border-color: transparent !important;\n}\n\n.lasso-editor-paste-hook{\n    position: absolute;\n    opacity:0;\n}\n.lasso-editor-placeholder{\n\tposition: absolute;\n}\n.lasso-editor-placeholder div{\n\t.opacity(0.5);\n\tposition: absolute;\n}\n.lasso-editor-placeholder-rich div{\n\tfont-style: italic;\n}\n.lasso-editor-inline,\n.lasso-editor-placeholder-inline div,\n.lasso-editor-inlineRich,\n.lasso-editor-placeholder-inlineRich div{\n\toverflow: hidden;\n\twhite-space: nowrap;\n}\n.lasso-editor-drag {\n\tposition: absolute;\n\tcursor: move;\n\tmargin-left: -5px;\n\tmargin-top: -20px;\n}\n.lasso-editor-toolbar-hide {\n\toverflow: hidden;\n\tmax-height: 0;\n\tpadding-top: 0;\n\tpadding-bottom: 0;\n\tmargin-top: 0;\n\tmargin-bottom: 0;\n\ttransition-property: opacity;\n\t-moz-transition-duration: 0.3s;\n\t-webkit-transition-duration: 0.3s;\n\t-o-transition-duration: 0.3s;\n\ttransition-duration: 0.3s;\n\t-moz-transition-timing-function: cubic-bezier(0, 1, 0.5, 1);\n\t-webkit-transition-timing-function: cubic-bezier(0, 1, 0.5, 1);\n\t-o-transition-timing-function: cubic-bezier(0, 1, 0.5, 1);\n\ttransition-timing-function: cubic-bezier(0, 1, 0.5, 1);\n\topacity: 0;\n}\n\n.lasso-editor-toolbar-show {\n\ttransition-property: opacity;\n\t-moz-transition-duration: 0.3s;\n\t-webkit-transition-duration: 0.3s;\n\t-o-transition-duration: 0.3s;\n\ttransition-duration: 0.3s;\n\t-moz-transition-timing-function: ease-in;\n\t-webkit-transition-timing-function: ease-in;\n\t-o-transition-timing-function: ease-in;\n\ttransition-timing-function: ease-in;\n\tmax-height: 1000px;\n\topacity: 1;\n\twidth: auto !important;\n}\n\n.lasso-editor-toolbar-fixed {\n\tposition: fixed;\n}\n.lasso-editor-focused {\n\ttransition: all 500ms ease-in-out 0s;\n\t-moz-box-shadow: 0px 0px 3px 4px rgba(0, 0, 0, 0.2);\n\t-webkit-box-shadow: 0px 0px 3px 4px rgba(0, 0, 0, 0.2);\n\tbox-shadow: 0px 0px 3px 4px rgba(0, 0, 0, 0.2);\n}\n\n#lasso--pagerefresh {\n    padding:15px;\n    background:@editor--color__success;\n    color:white;\n    font-size:@modal--font__size;\n    line-height: @modal--font__size * 1.3;\n    .transition(opacity .15s ease);\n}\n\n#aesop-generator-settings .aesop-chapter-title {\n    left:0px;\n}\n\n"
  },
  {
    "path": "public/assets/less/source/featimg-controls.less",
    "content": "#lasso--featImgControls {\n    position: relative;\n    z-index: 1;\n    left:0;\n    right:0;\n    text-align: center;\n    top:5px;\n    width:@featimg-controls--width;\n    height:@featimg-controls--height;\n    padding:0;\n    margin:0 auto;\n    font-size: @component-controls--font__size;\n    border-radius: @editor--radius - 2;\n    line-height: 0;\n    #gradient > .vertical( @toolbar--bg__accent, @toolbar--bg );\n    .box-shadow(inset 0 1px 0 rgba(255,255,255,0.1));\n    .transition(opacity .15s ease);\n\n    &.lasso--featImg--has-thumb {\n        width:@featimg-controls--width * 2;\n\t\tpadding:0;\n\n        #lasso--featImgDelete {\n            .opacity(1);\n        }\n    }\n\n    li {\n        float:left;\n        list-style-type: none;\n        line-height: 0;\n\t\tmargin-left: 0;\n        width:@featimg-controls--width;\n        height:@featimg-controls--height;\n        text-align: center;\n        text-shadow:0 1px 1px rgba(0,0,0,0.4);\n\n        i {\n            font-style: normal;\n            position: relative;\n            top:5px;\n        }\n\n        &:before {\n            position: relative;\n            top:3px;\n            font-size:@component-controls--font__size;\n        }\n        &:hover{\n            cursor: pointer;\n            background: @toolbar--hover;\n        }\n        &:active {\n            .box-shadow(inset 0 1px 1px rgba(0,0,0,0.4));\n        }\n    }\n\n    .lasso--featImg--controlHidden {\n        position: absolute;\n        left:-1000px;\n        height:0;\n        .opacity(0);\n    }\n\n    #lasso--featImgSave {\n        .lasso--featImg--controlHidden;\n    }\n\n    #lasso--featImgDelete {\n        .opacity(0);\n    }\n\n    a {\n        color:@component-controls--color;\n        display:block;\n\n        &:hover{\n            text-decoration: none;\n        }\n    }\n}"
  },
  {
    "path": "public/assets/less/source/fonts.css",
    "content": "@font-face{font-family:icomoon;src:url(../../../public/assets/fonts/icomoon.eot?ua4grz);src:url(../../../public/assets/fonts/icomoon.eot?#iefixua4grz) format('embedded-opentype'),url(../../../public/assets/fonts/icomoon.woff?ua4grz) format('woff'),url(../../../public/assets/fonts/icomoon.ttf?ua4grz) format('truetype'),url(../../../public/assets/fonts/icomoon.svg?ua4grz#icomoon) format('svg');font-weight:400;font-style:normal}[class*=\" lasso-icon-\"],[class^=lasso-icon-]{font-family:icomoon;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso-icon-move:before{content:\"\\e600\"}.lasso-icon-pen:before{content:\"\\e908\"}.lasso-icon-image:before{content:\"\\e90d\"}.lasso-icon-images:before{content:\"\\e90e\"}.lasso-icon-camera:before{content:\"\\e90f\"}.lasso-icon-headphones:before{content:\"\\e910\"}.lasso-icon-film:before{content:\"\\e913\"}.lasso-icon-book:before{content:\"\\e91f\"}.lasso-icon-books:before{content:\"\\e920\"}.lasso-icon-file-text2:before{content:\"\\e926\"}.lasso-icon-location:before{content:\"\\e947\"}.lasso-icon-clock:before{content:\"\\e94e\"}.lasso-icon-user:before{content:\"\\e971\"}.lasso-icon-quotes-left:before{content:\"\\e977\"}.lasso-icon-plus:before{content:\"\\ea0a\"}.lasso-icon-bold:before{content:\"\\ea62\"}.lasso-icon-underline:before{content:\"\\ea63\"}.lasso-icon-italic:before{content:\"\\ea64\"}.lasso-icon-strikethrough:before{content:\"\\ea65\"}.lasso-icon-pagebreak:before{content:\"\\ea6e\"}.lasso-icon-paragraph-center:before{content:\"\\ea78\"}.lasso-icon-spinner6:before{content:\"\\e97f\"}.lasso-icon-upload2:before{content:\"\\e9c6\"}.lasso-icon-cross:before{content:\"\\ea0f\"}.lasso-icon-bin2:before{content:\"\\e9ad\"}.lasso-icon-copy:before{content:\"\\e92c\"}.lasso-icon-disk:before{content:\"\\e601\"}.lasso-icon-embed:before{content:\"\\ea7f\"}.lasso-icon-blog:before{content:\"\\e909\"}.lasso-icon-pencil:before{content:\"\\e905\"}.lasso-icon-gear:before{content:'\\e994'}.lasso-icon-link:before{content:'\\e9cb'}.lasso-icon-help:before{content:\"\\e602\"}.lasso-icon-tools:before{content:\"\\f031\"}.lasso-icon-layout:before{content:\"\\e603\"}.lasso-icon-list:before{content:\"\\e9ba\"}.lasso-icon-file-add:before{content:\"\\e603\"}.lasso-icon-check:before{content:'\\ea10'}.lasso-icon-history:before{content:\"\\e94d\"}"
  },
  {
    "path": "public/assets/less/source/fonts.less",
    "content": "@font-path:        \"../../../public/assets/fonts\";\n\n@font-face {\n\tfont-family: 'icomoon-editus';\n\tsrc:url('@{font-path}/icomoon.eot?ua4grz');\n\tsrc:url('@{font-path}/icomoon.eot?#iefixua4grz') format('embedded-opentype'),\n\t\turl('@{font-path}/icomoon.woff?ua4grz') format('woff'),\n\t\turl('@{font-path}/icomoon.ttf?ua4grz') format('truetype'),\n\t\turl('@{font-path}/icomoon.svg?ua4grz#icomoon') format('svg');\n\tfont-weight: normal;\n\tfont-style: normal;\n}\n\n[class^=\"lasso-icon-\"], [class*=\" lasso-icon-\"] {\n\tfont-family: 'icomoon-editus';\n\tspeak: none;\n\tfont-style: normal;\n\tfont-weight: normal;\n\tfont-variant: normal;\n\ttext-transform: none;\n\tline-height: 1;\n\n\t/* Better Font Rendering =========== */\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n}\n\n.lasso-icon-move:before {\n\tcontent: \"\\e600\";\n}\n.lasso-icon-pen:before {\n\tcontent: \"\\e908\";\n}\n.lasso-icon-image:before {\n    content: \"\\e90d\";\n}\n.lasso-icon-images:before {\n\tcontent: \"\\e90e\";\n}\n.lasso-icon-camera:before {\n\tcontent: \"\\e90f\";\n}\n.lasso-icon-headphones:before {\n\tcontent: \"\\e910\";\n}\n.lasso-icon-film:before {\n\tcontent: \"\\e913\";\n}\n.lasso-icon-book:before {\n\tcontent: \"\\e91f\";\n}\n.lasso-icon-books:before {\n\tcontent: \"\\e920\";\n}\n.lasso-icon-file-text2:before {\n\tcontent: \"\\e926\";\n}\n.lasso-icon-location:before {\n\tcontent: \"\\e947\";\n}\n.lasso-icon-clock:before {\n\tcontent: \"\\e94e\";\n}\n.lasso-icon-user:before {\n\tcontent: \"\\e971\";\n}\n.lasso-icon-quotes-left:before {\n\tcontent: \"\\e977\";\n}\n.lasso-icon-plus:before {\n\tcontent: \"\\ea0a\";\n}\n.lasso-icon-bold:before {\n\tcontent: \"\\ea62\";\n}\n.lasso-icon-underline:before {\n\tcontent: \"\\ea63\";\n}\n.lasso-icon-italic:before {\n\tcontent: \"\\ea64\";\n}\n.lasso-icon-strikethrough:before {\n\tcontent: \"\\ea65\";\n}\n.lasso-icon-pagebreak:before {\n\tcontent: \"\\ea6e\";\n}\n.lasso-icon-paragraph-center:before {\n\tcontent: \"\\ea78\";\n}\n.lasso-icon-spinner6:before {\n    content: \"\\e97f\";\n}\n.lasso-icon-upload2:before {\n    content: \"\\e9c6\";\n}\n.lasso-icon-cross:before {\n    content: \"\\ea0f\";\n}\n.lasso-icon-bin2:before {\n    content: \"\\e9ad\";\n}\n.lasso-icon-copy:before {\n    content: \"\\e92c\";\n}\n.lasso-icon-disk:before {\n    content: \"\\e601\";\n}\n.lasso-icon-embed:before {\n    content: \"\\ea7f\";\n}\n.lasso-icon-blog:before {\n    content: \"\\e909\";\n}\n.lasso-icon-pencil:before {\n    content: \"\\e905\";\n}\n.lasso-icon-gear:before {\n    content:'\\e994';\n}\n.lasso-icon-link:before {\n    content:'\\e9cb';\n}\n.lasso-icon-help:before {\n    content: \"\\e602\";\n}\n.lasso-icon-tools:before {\n    content: \"\\f031\";\n}\n.lasso-icon-layout:before {\n    content: \"\\e603\";\n}\n.lasso-icon-list:before {\n    content: \"\\e9ba\";\n}\n.lasso-icon-file-add:before {\n    content: \"\\e603\";\n}\n.lasso-icon-check:before {\n    content:'\\ea10';\n}\n.lasso-icon-history:before {\n    content: \"\\e94d\";\n}"
  },
  {
    "path": "public/assets/less/source/form-controls.less",
    "content": ".lasso--btn-primary {\n    .editor-btn-primary();\n}\n.lasso--btn-secondary {\n    .editor-btn-secondary();\n}\n\n.lasso--post-form {\n\n    label {\n        font-size: @modal--font__size;\n        line-height: 1;\n        margin-bottom: 8px;\n        display: block;\n        font-family: @editor--font;\n\n        .lasso-icon-help {\n            margin-left: 5px;\n            position: relative;\n            top:2px;\n        }\n    }\n\n    // general input\n    input[type=\"text\"] {\n        .editor--input();\n    }\n\n    .checkbox_label {\n        display: inline-block;\n    }\n\n    .checkbox-control {\n        position: relative;\n        display: inline-block;\n        padding-left: 28px;\n        cursor: pointer;\n        //color:#444;\n        top:2px;\n\n        input {\n            position: absolute;\n            opacity: 0;\n            z-index: -1; /* Put the input behind the label so it doesn't overlay text */\n        }\n\n        input:checked ~ .control-indicator {\n          color: @input--bg;\n          background-color: @editor--color__update;\n        }\n\n        input:active ~ .control-indicator {\n          color:@input--bg;\n          background-color: @editor--color__update;\n        }\n    }\n\n    .control-indicator {\n        position: absolute;\n        top: -1px;\n        left: 0;\n        display: block;\n        width:  18px;\n        height: 18px;\n        line-height: 1rem;\n        font-size: 65%;\n        color: @input--bg;\n        text-align: center;\n        background-color: @input--bg;\n        background-size: 50% 50%;\n        background-position: center center;\n        background-repeat: no-repeat;\n        -webkit-user-select: none;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        user-select: none;\n    }\n\n    /* Checkbox modifiers */\n    .checkbox .control-indicator {\n      border-radius: .25rem;\n    }\n    .checkbox input:checked ~ .control-indicator {\n      background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTYuNCwxTDUuNywxLjdMMi45LDQuNUwyLjEsMy43TDEuNCwzTDAsNC40bDAuNywwLjdsMS41LDEuNWwwLjcsMC43bDAuNy0wLjdsMy41LTMuNWwwLjctMC43TDYuNCwxTDYuNCwxeiINCgkvPg0KPC9zdmc+DQo=);\n    }\n\n    /* Radio modifiers */\n    .radio .control-indicator {\n      border-radius: 50%;\n    }\n    .radio input:checked ~ .control-indicator {\n      background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQsMUMyLjMsMSwxLDIuMywxLDRzMS4zLDMsMywzczMtMS4zLDMtM1M1LjcsMSw0LDF6Ii8+DQo8L3N2Zz4NCg==);\n    }\n\n    /* Alternately, use another character */\n    .control-x input:checked ~ .control-indicator {\n      background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0xLjQsMEwwLDEuNGwwLjcsMC43bDEuOCwxLjhMMC43LDUuN0wwLDYuNGwxLjQsMS40bDAuNy0wLjdsMS44LTEuOGwxLjgsMS44bDAuNywwLjdsMS40LTEuNEw3LjEsNS43DQoJTDUuMywzLjlsMS44LTEuOGwwLjctMC43TDYuNCwwTDUuNywwLjdMMy45LDIuNUwyLjEsMC43QzIuMSwwLjcsMS40LDAsMS40LDB6Ii8+DQo8L3N2Zz4NCg==);\n    }\n    .control-dash input:checked ~ .control-indicator {\n      background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0wLDN2Mmg4VjNIMHoiLz4NCjwvc3ZnPg0K)\n    }\n\n    // cancel button and set date to now button\n\t#lasso--postsettings-setnow,\n    .lasso--postsettings-cancel {\n        background: 0 0;\n        color: @editor--color__error;\n        position: relative;\n        top: 3px;\n\n        &:hover {\n            color:darken(@editor--color__error,5);\n            text-decoration: none;\n        }\n    }\n\t#lasso--postsettings-setnow {\n\t    font-size:16px;\n\t}\n\n    // save button\n    input[type=\"submit\"] {\n        .editor-btn-primary();\n        float:right;\n    }\n}\n\n// button group\n.lasso--btn-group {\n    text-align: center;\n\n    a {\n        margin:0;\n        display: inline-block;\n    }\n\n    &.lasso--btn-group-small {\n        a{\n            font-size:14px;\n        }\n    }\n}\n\n// Notice\n.lasso--notice {\n    text-align: center;\n    max-width:@notice--width;\n    padding:@editor--padding;\n    color:white;\n    font-family: @editor--font;\n    font-size:@editor--font__size;\n    margin:@editor--padding auto;\n\n    &.lasso--notice-warning {\n        background:@editor--color__warning;\n    }\n    &.lasso--notice-info {\n        background:@editor--color__update;\n    }\n    &.lasso--notice-error {\n        background:@editor--color__error;\n    }\n    &.lasso--notice-success {\n        background:@editor--color__success;\n    }\n}\n\n\n// post status slider\n#lasso--slider {\n    position: relative;\n    text-align: left;\n    background: @rail--track__color;\n    top:5px;\n    height:@rail__height;\n    border-radius:4px;\n    .box-shadow(inset 1px 1px 1px rgba(0,0,0,0.2));\n\n    // slider handle\n    .ui-slider-handle {\n        position: absolute;\n        z-index: 2;\n        width: @rail--handle__w;\n        height: @rail--handle__h;\n        cursor: default;\n        -ms-touch-action: none;\n        touch-action: none;\n        background:@rail--handle__color;\n        top:-6px;\n        margin-left:-@rail--handle__w / 2;\n        border-radius: 100%;\n        .box-shadow(0 0 7px -1px rgba(0,0,0,0.75));\n\n        &:focus,\n        &:active {\n            outline:none;\n        }\n\n        &:hover,\n        &:active {\n            .box-shadow(inset 0 0 6px rgba(0,0,0,0.5));\n        }\n\n        &:hover { border:4px solid @rail--handle__color; }\n\n        &:active { border:4px solid darken(@rail--handle__color,3); }\n\n        &:hover, &:focus, &:active { cursor: move; }\n    }\n\n}\n\n// select cuistomizer\n.lasso--select-wrap {\n    position: relative;\n    display: inline-block;\n    color: @input--color;\n\n    // the select item\n    select {\n        display: inline-block;\n        width: 100%;\n        margin: 0;\n        line-height: @input--height;\n        color: @toolbar--color;\n        background-color: @modal--bg__accent;\n        border: 0;\n        padding:2px 25px 2px 12px;\n        border-radius: @editor--radius;\n        cursor: pointer;\n        outline: 0;\n        font-size:@input--font__size;\n        -webkit-appearance: none;\n         -moz-appearance: none;\n              appearance: none;\n    }\n\n    // Undo the Firefox inner focus ring\n    select:focus:-moz-focusring {\n      color: transparent;\n      text-shadow: 0 0 0 #000;\n    }\n\n    // Dropdown arrow\n    &:after {\n        position: absolute;\n        top: 50%;\n        right: 12px;\n        display: inline-block;\n        content: \"\";\n        width: 0;\n        height: 0;\n        margin-top: -.15rem;\n        pointer-events: none;\n        border-top: 4px solid @toolbar--color;\n        border-right: 4px solid transparent;\n        border-bottom: 4px solid transparent;\n        border-left: 4px solid transparent;\n    }\n\n    /* Hover state */\n    /* Uncomment if you need it, but be aware of the sticky iOS states.\n    .select select:hover {\n      background-color: #ddd;\n    }\n    */\n\n    // open\n    select:active {\n        color: @input--color;\n        background-color: @modal--bg__accent;\n    }\n\n    // Hide the arrow in IE10 and up\n    select::-ms-expand {\n        display: none;\n    }\n\n    // Media query to target Firefox only\n    @-moz-document url-prefix() {\n        /* Firefox hack to hide the arrow */\n        select {\n            text-indent: 0.01px;\n            text-overflow: '';\n            padding-right: 1rem;\n        }\n\n        /* <option> elements inherit styles from <select>, so reset them. */\n        option {\n            background-color: white;\n        } \n    }\n\n\n}"
  },
  {
    "path": "public/assets/less/source/mixins.css",
    "content": ".lasso--animate__spin{-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.not-visible{opacity:0;filter:alpha(opacity=0);display:none;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease}"
  },
  {
    "path": "public/assets/less/source/mixins.less",
    "content": ".editor--input(){\n    background: @input--bg;\n\tbackground-color: @input--bg !important;\n    border:1px solid @input--border;\n    color:@input--color;\n    font-size: @sidebar--font__size;\n    z-index: 0;\n    position: relative;\n    padding-left: 6px;\n    padding: @input--padding;\n    height:@input--height__lg;\n    border-radius: @editor--radius @editor--radius;\n    .box-shadow(inset 1px 1px 1px rgba(0,0,0,.4));\n\n    &:focus {\n        outline:none;\n        border:1px solid @editor--color__update;\n        border-radius:@editor--radius - 2;\n    }\n}\n\n.lasso--animate__spin {\n    -webkit-animation: spin 2s infinite linear;\n    animation: spin 2s infinite linear;\n}\n.not-visible {\n    .not-visible();\n}\n.not-visible(){\n    .opacity(0);\n    display:none;\n    .transition(opacity .2s ease);\n}\n\n\n.center(){\n    width:auto;\n    left:50%;\n    .translate(-50%, 0);\n}\n.editor-icon-font(){\n    font-family: 'icomoon-editus';\n    display:inline-block;\n    speak: none;\n    font-style: normal;\n    font-weight: normal;\n    font-variant: normal;\n    text-transform: none;\n    line-height: 1;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n}\n\n.editor--input(){\n    background: @input--bg;\n    border:1px solid @input--border;\n    color:@input--color;\n    font-size: @sidebar--font__size;\n    z-index: 0;\n    position: relative;\n    padding-left: 6px;\n    height:@input--height__lg;\n    border-radius: @editor--radius @editor--radius;\n    .box-shadow(inset 1px 1px 1px rgba(0,0,0,.4));\n}\n\n.editor--tool__bg() {\n    color:@toolbar--color;\n     border:1px solid @toolbar--border;\n    #gradient > .vertical( @toolbar--bg__accent, @toolbar--bg );\n    .box-shadow(inset 0 1px 0 rgba(255,255,255,0.1));\n}\n\n.editor--icon__list(){\n    // image\n\n    &.lasso-toolbar--component__wpimg:before,\n    &.lasso-toolbar--component__image:before { content: \"\\e90f\"; }\n    // character\n    &.lasso-toolbar--component__character:before { content: \"\\e971\"; }\n    // qupte\n    &.lasso-toolbar--component__wpquote:before,\n    &.lasso-toolbar--component__quote:before { content: \"\\e977\"; }\n    // content\n    &.lasso-toolbar--component__content:before { content: \"\\ea78\"; }\n    // chapter head\n    &.lasso-toolbar--component__chapter:before { content: \"\\e91f\"; }\n    // parallax\n    &.lasso-toolbar--component__parallax:before { content: \"\\ea6e\"; }\n    // audio\n    &.lasso-toolbar--component__audio:before { content: \"\\e910\"; }\n    // video\n\t&.lasso-toolbar--component__wpvideo:before,\n    &.lasso-toolbar--component__video:before { content: \"\\e913\"; }\n    // map\n    &.lasso-toolbar--component__map:before { content: \"\\e947\"; }\n    // video\n    &.lasso-toolbar--component__timeline:before { content: \"\\e94e\"; }\n    // document\n    &.lasso-toolbar--component__document:before { content: \"\\e926\"; }\n    // collection\n    &.lasso-toolbar--component__collection:before { content: \"\\e920\"; }\n    // gallery\n    &.lasso-toolbar--component__gallery:before { content: \"\\e90e\"; }\n\t// gallery pop\n    &.lasso-toolbar--component__gallerypop:before { content: \"\\f211\"; font-family: Dashicons; }\n\t// event\n    &.lasso-toolbar--component__event:before { content: \"\\f145\"; font-family: Dashicons; }\n}\n\n.tiny-circle-btn( @bg: @editor--color__update, @color: white ) {\n    font-size: 10px;\n    background: @bg;\n    color: @color;\n    border-radius: 100%;\n    font-weight: normal;\n    height: 18px;\n    width: 18px;\n    line-height: 20px;\n    text-align: center;\n    text-shadow: 1px 1px rgba(0,0,0,0.1);\n\n    &:focus,\n    &:active,\n    &:hover {\n        outline: none;\n        color:@color;\n        text-decoration: none;\n    }\n\n    &:hover {\n        color:@color;\n        background: fadeout(@editor--color__update,20);\n    }\n    &:active {\n        color:@color;\n        background:@editor--color__update;\n    }\n}\n\n.editor-btn-primary(){\n    text-align: center;\n    margin: 0 0 0 15px;\n    border-radius: 2px;\n    background:@editor--color__update;\n    border: none;\n    display:inline-block;\n    font-family:@editor--font;\n    color: #fff;\n    font-size: 17px;\n    line-height: @input--lineheight;\n    padding: 2px 12px 1px;\n    -webkit-appearance: none;\n\n    &:active,\n    &:focus {\n        outline:none;\n    }\n\n    &:hover {\n        text-decoration: none;\n        color:white;\n        background:darken(@editor--color__update,10);\n    }\n\n    &:active {\n        .box-shadow(inset 1px 1px 2px rgba(0,0,0,0.4));\n    }\n}\n\n.editor-btn-secondary() {\n    background: @base--light;\n    border:1px solid @toolbar--bg__dark;\n    color:@toolbar--color;\n    font-size: 17px;\n    line-height: @input--lineheight;\n    padding: 2px 12px 1px;\n    text-decoration: none;\n    display: inline-block;\n    border-radius: @editor--radius - 2;\n    .transition(opacity .15s ease);\n\n    &:active,&:visited {\n        color:@toolbar--color\n    }\n\n    &:hover {\n        .opacity(1.0);\n        color:@toolbar--color;\n        text-decoration: none;\n    }\n\n    &:active {\n        .box-shadow(inset 1px 1px 2px rgba(0,0,0,0.4));\n    }\n\n    &.lasso--btn-loading {\n\n        &:before {\n            .editor-icon-font();\n            content:'\\e97f';\n            margin-right:@editor--padding;\n            -webkit-animation: spin 2s infinite linear;\n            animation: spin 2s infinite linear;\n        }\n    }\n}\n\n/////////\n.clearfix() {\n  &:before,\n  &:after {\n    content: \" \"; // 1\n    display: table; // 2\n  }\n  &:after {\n    clear: both;\n  }\n}\n// Drop shadows\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n// Transitions\n.transition(@transition) {\n  -webkit-transition: @transition;\n  -moz-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n// Transformations\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9+\n          transform: rotate(@degrees);\n}\n.scale(@ratio) {\n  -webkit-transform: scale(@ratio);\n      -ms-transform: scale(@ratio); // IE9+\n          transform: scale(@ratio);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9+\n          transform: translate(@x, @y);\n}\n.skew(@x; @y) {\n  -webkit-transform: skew(@x, @y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n          transform: skew(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9+\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9+\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n          transform-origin: @origin;\n}\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n          animation: @animation;\n}\n\n// Opacity\n.opacity(@opacity) {\n  opacity: @opacity;\n  // IE8 filter\n  @opacity-ie: (@opacity * 100);\n  filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n    background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Opera 12\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}"
  },
  {
    "path": "public/assets/less/source/mobile.less",
    "content": "// iOS\n.os-ios {\n    .lasso-component--controls {\n        .opacity(1);\n        left:0;\n    }\n}\n\n// small screens\n@media(max-width:600px) {\n\n    // editor controls\n    .lasso-editing {\n        .lasso--toolbar_wrap.ase-not-active,\n        .lasso--toolbar_wrap.toolbar-extended,\n        .lasso--toolbar_wrap.ase-not-active.toolbar-extended,\n        .lasso--toolbar_wrap {\n            border-radius: 0;\n            //top:0;\n            width:100%;\n            left:0;\n            right:0;\n            .translate(0, 0); // This combined with left:0 removes centering. Without it, the toolbar has a negative margin.\n            height:auto; // Allow toolbar natural height and icon wrapping for extra small screens\n            bottom:auto; // Allow toolbar natural height and icon wrapping for extra small screens\n        }\n        .lasso--controls__right {\n            z-index: 1000; // clears toolbar wrap\n            top:auto; // keep on bottom so as to not overlap controls, which are now on the top. Change if toolbar is given enough left and right margin\n            right:0;\n\n            a {\n                background:none;\n            }\n\n            #lasso--save{\n               // background: none;\n                &:before {\n               //     color:@editor--color__update;\n                    top:3px;\n                }\n            }\n        }\n\n        #lasso-toolbar--link.link--drop-down,\n        #lasso-toolbar--html.html--drop-down {\n            position: static;\n\n            #lasso-toolbar--link__wrap,\n            #lasso-toolbar--html__wrap {\n                left:0;\n                right:0;\n                //top:44px;\n                //bottom:auto;\n\t\t\t\ttop:auto;\n                bottom:50px;\n                width:90%;\n\n                &:after {\n                    margin:0;\n                    top:-6px;\n                    border-top: none;\n                    border-bottom: 6px solid @toolbar--hover;\n                }\n            }\n        }\n        #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after { left:142px; }\n        #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after { left:175px; }\n\n        #lasso-toolbar--components.toolbar--drop-down {\n\n            position: static;\n\n            ul {\n                top:44px;\n                left:0;\n                right:0;\n                width:100%;\n\n                &:after {\n                    left:206px;\n                    margin:0;\n                    top:-6px;\n                    border-top: none;\n                    border-bottom: 6px solid @toolbar--hover;\n                }\n            }\n        }\n\n        .toolbar-extended {\n            #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after { left:222px; }\n            #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after { left:255px; }\n            #lasso-toolbar--components.toolbar--drop-down ul:after { left:288px; }\n        }\n\n    }\n\n    // all posts modal @since 0.9.4\n    #lasso--all-posts__modal {\n\n        ul.lasso--post-list,\n        ul.lasso--post-object-list {\n            float:none;\n            width:100%;\n            display:block;\n        }\n\n        ul.lasso--post-object-list {\n            margin-bottom:@editor--padding * 2;\n            padding-bottom:@editor--padding;\n            border-bottom:1px solid @base--dark;\n            .box-shadow(0 1px 1px -1px rgba(255,255,255,0.15));\n\n            li {\n                display:inline-block;\n                width:auto;\n                margin-right:@editor--padding * 2;\n                font-size:90%;\n            }\n        }\n\n        ul.lasso--post-list {\n            padding-left:0;\n            border:none;\n            box-shadow:none;\n        }\n    }\n\n    // global modal\n    .lasso--modal {\n        //display: block;\n\n        .lasso--modal__inner,\n        &.lasso--modal__full .lasso--modal__inner {\n            border-radius:0;\n            padding:@editor--padding;\n        }\n    }\n\n}\n\n.lasso-mobile {\n\t#lasso--exit {\n\t   float:none;\n\t}\n}\n\n\n// for tablet\n@media (min-width: 601px) {\n\t.lasso-mobile{\n\t\t\t// drop up menu\n\t\t\t.toolbar--drop-up{\n\t\t\t\tul {\n\t\t\t\t\t&:after {\n\t\t\t\t\t\tmargin:0;\n\t\t\t\t\t\ttop:-9px;\n\t\t\t\t\t\tborder-top: none;\n\t\t\t\t\t\tborder-bottom: 6px solid @toolbar--hover;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t#lasso-toolbar--html__wrap,\n\t\t\t#lasso-toolbar--link__wrap{\n\t\t\t    &:after {\n\t\t\t\t\t margin:0;\n                    top:-9px;\n                    border-top: none;\n                    border-bottom: 6px solid @toolbar--hover;\n\t\t\t\t}\n\t\t\t}\n\t}\n\t.lasso-mobile.lasso--toolbar_wrap {\n\t\t    width:100%;\n\t}\n}"
  },
  {
    "path": "public/assets/less/source/post-settings.less",
    "content": ".lasso-modal-open {\n    overflow: hidden;\n}\n\n// modal overlay\n#lasso--modal__overlay {\n    z-index: 9999;\n    position: fixed;\n    left:0;\n    top:0;\n    right:0;\n    bottom:0;\n    background:@modal--overlay__bg;\n}\n\n// modal outer\n.lasso--modal{\n    z-index: 100001;\n    position:fixed;\n    display: table;\n    top:33vh;\n    left:0;\n    right:0;\n    bottom:0;\n    width:100%;\n    max-width:@modal--width;\n    margin:0 auto;\n    font-family:@editor--font;\n    * {\n        .box-sizing(border-box);\n    }\n\n}\n\n// modal inner\n.lasso--modal__inner {\n    display:table-cell;\n    vertical-align: middle;\n    background:@modal--bg;\n    border-radius:@editor--radius;\n    border:1px solid @modal--border;\n    padding:@modal--padding;\n    .box-shadow(0 0 10px 1px rgba(0,0,0,0.5) );\n    color:@modal--color;\n    .clearfix();\n    position: relative; // @since 0.9.4\n\tlabel{\n\t    color:#fff;\n\t}\n}\n\n// modal close\n#lasso--modal__close {\n    position:absolute;\n    right:20px;\n    top:10px;\n\n    &:hover {\n        cursor: pointer;\n    }\n}\n\n// post status slider wrap\n.lasso--slider_wrap {\n    padding:0 10px;\n    height:18px;\n}\n\n// GLOBAL INPUT SETTINGS\n.lasso--postsettings__option {\n    padding-bottom:20px;\n    margin-bottom:20px;\n    position: relative;\n    line-height: 1;\n    border-bottom:1px solid @modal--border;\n    .box-shadow(0 1px 1px rgba(255,255,255,0.05));\n\n\n    &.lasso--last-option {\n        border-bottom:none;\n        margin-bottom: 0;\n        padding-bottom: 0;\n    }\n\n    // story status label\n    .story-status {\n        margin:12px 0 8px;\n        padding:0 10px;\n        line-height: 1;\n\t\tdisplay:table;\n\t\twidth:100%;\n        .clearfix();\n\n        li {\n            font-size: @modal--font__size;\n            //float: left;\n            list-style-type: none;\n\t\t\tdisplay: table-cell;\n        }\n\n        &.story-status-publish {\n            #lasso--status-draft {\n                .opacity(0.3);\n            }\n        }\n\n        &.story-status-draft {\n            #lasso--status-publish {\n                 .opacity(0.3);\n            }\n        }\n\n        #lasso--status-pending {\n\t\t\ttext-align:center;\n        }\n\n        // published\n        #lasso--status-publish {\n            float: right;\n\t\t\ttext-align:right;\n        }\n    }\n\n    // post slug option\n    &.story-slug-option {\n\n        .lasso--select-wrap {\n            position: absolute;\n            top:24px;\n            left:1px;\n\n            select {\n                font-size:@modal--font__size - 1;\n                border-radius:1px 0 0 1px;\n            }\n        }\n        + .lasso--postsettings__footer {\n            margin-top:inherit;\n            padding-top:inherit;\n            padding-to:20px;\n            margin-top:20px;\n        }\n    }\n\n    &.checkbox-option {\n\n    }\n\n    + .lasso--postsettings__footer {\n        border-top:none;\n        box-shadow: none;\n        margin-top:0;\n        padding-top:0;\n    }\n}\n\n// post settings form footer\n.lasso--postsettings__footer {\n    text-align: right;\n    font-size: @modal--font__size + 2;\n    padding-top:20px;\n    margin-top:22px;\n    border-top:1px solid @modal--border;\n    .box-shadow(0 -1px 1px rgba(255,255,255,0.05));\n\n    a,input {\n        display: inline-block;\n    }\n\n}\n\n#lasso--postnew__form {\n    // post slug option\n    .story-slug-option {\n        margin-bottom: 0;\n        //input[type=\"text\"] {\n        //    padding-left:92px;\n        //}\n\t\t#lasso--select-type {\n\t\t    height:35px;\n\t\t}\n    }\n\t.lasso--modal__trigger-footer {\n\t   left:90px;\n\t   width:260px;\n\t}\n\n}\n\n\n// Modal Addon - 0.9.4\n.lasso--modal__tabs {\n    position:absolute;\n    right:0;\n    top:-@modal--tab__height;\n    padding:0;\n    margin:0;\n    height:@modal--tab__height;\n    list-style:none;\n\n    li {\n        display:inline-block;\n        background:@modal--bg__accent;\n        font-size:@input--font__size;\n        border-top-left-radius: @editor--radius;\n        border-top-right-radius: @editor--radius;\n        padding:0 @editor--padding;\n        margin:0 1px 0;\n        height:@modal--tab__height;\n        line-height:@modal--tab__height;\n        .transition(background .15s ease);\n\n        &.active-tab,\n        &:hover {\n            cursor:pointer;\n            background:@modal--bg;\n        }\n\n        &:last-child {\n            margin-right:-1px;\n        }\n    }\n}\n// ACF\n.lasso--modal__content {\n    #poststuff {\n        min-width:1px;\n    }\n}\n// wide form to fit new feature image - 0.9.4\n#lasso--post-settings__modal {\n    max-width:@modal--width__med;\n}\n// settings columns\n.lasso--postsettings__1col {\n\n}\n.lasso--postsettings__2col {\n    .clearfix();\n\n    .lasso--postsettings__left,\n    .lasso--postsettings__right {\n        float:left;\n    }\n\n    .lasso--postsettings__left {\n        width:35%;\n\n        label {\n            font-size:14px;\n            line-height:1;\n            display:block;\n            margin-bottom: 15px;\n        }\n\n        .lasso-util--help {\n            left:6px;\n            top:2px;\n        }\n    }\n    .lasso--postsettings__right {\n        width:62%;\n        margin-left:3%;\n    }\n}\n\n.story-tags-option,\n.story-slug-option {\n    border-bottom:none;\n    box-shadow:none;\n    padding-bottom:0;\n}\n.lasso--postsettings__middle {\n    clear:left;\n    padding-top:@editor--padding__lg;\n    border-top:1px solid @modal--border;\n    .box-shadow(inset 0 1px 1px rgba(255,255,255,0.05));\n}\n\n// post thumb\n.lasso--post-thumb {\n    position: relative;\n\n    .lasso--post-thumb__controls {\n        position: absolute;\n        top:@editor--padding;\n        left:@editor--padding;\n        right:@editor--padding;\n        z-index: 1;\n\n        i {\n            text-shadow:0 1px 1px rgba(0,0,0,0.5);\n            .opacity(0.6);\n            .transition(all .2s ease);\n\n            &:hover {\n                cursor: pointer;\n                .opacity(1.0);\n                .scale(1.1);\n            }\n\n            &:active {\n                .scale(1);\n                box-shadow:none;\n            }\n        }\n\n\n        #lasso--post-thumb__add {\n            font-size:@input--font__size + 1;\n            top:2px;\n            margin-right:-4px;\n            position:relative;\n        }\n\n        #lasso--save-status {\n            float: right;\n            font-size:@input--font__size + 1;\n            position: relative;\n            top: 3px;\n            right: 3px;\n            color:@editor--color__success;\n        }\n\n    }\n\n    // image\n    img{\n        border:5px solid fadeout(@modal--bg__accent,25);\n        border-radius: @editor--radius;\n\t\twidth:196px;\n        height:136px;\n    }\n}\n\n#lasso--postsettings__form.no-thumbnail {\n    #lasso--post-thumb__delete {\n        .not-visible();\n    }\n}\n\n// custom form #\n.lasso--modal__checkbox,\n#lasso--post-settings__modal {\n\n}\n\n#lasso--custom-taxo-select {\n    padding-top: 1px;\n    padding-bottom: 1px;\n    font-size: 15px;\n}\n"
  },
  {
    "path": "public/assets/less/source/revisions.less",
    "content": "#lasso--revision__modal {\n\n    .lasso--slider_wrap {\n        padding:0 16px;\n        margin-top:@editor--padding + 8;\n    }\n    .transition(opacity .15s ease);\n\n    .lasso--btn-group {\n        .lasso--btn-secondary {\n            .opacity(0.7);\n            .transition(opacity .15s ease);\n\n            &:hover {\n                .opacity(1);\n            }\n        }\n    }\n\n    .lasso-icon-move {\n        position: absolute;\n        top:@editor--padding + 5;\n        right:@editor--padding + 5;\n        color:darken(@modal--color-dark, 33);\n        font-size:@modal--font__size;\n\n        &:hover {\n            cursor:move;\n        }\n    }\n\n}\n\n// revision list\n#lasso--revision-list {\n    margin:0;\n    padding:0;\n    list-style:none;\n    text-align: center;\n    margin-bottom: @editor--padding;\n    width:110%;\n    left:-5%;\n    position: relative;\n    top:-3px;\n    .clearfix();\n\n    li {\n        padding:12px 0 0 0;\n        display:inline-block;\n        font-family:@editor--font;\n        font-size:@modal--font__size - 3;\n        color:@modal--color-dark;\n        position: relative;\n        text-transform: uppercase;\n        line-height:13px;\n        margin:0 auto;\n        position: relative;\n\n        span {color:@modal--color-dark;}\n\n        &:first-child {\n            margin-left:0;\n        }\n\n        &:last-child {\n            margin-right: 0;\n        }\n\n        &:before {\n            content:'';\n            height:5px;\n            border-right:1px solid darken(@modal--color-dark,33);\n            width:1px;\n            position: absolute;\n            top:0;\n            left:0;\n            right:0;\n            text-align: center;\n            margin:0 auto;\n        }\n    }\n}\n\n#lasso--revision-list[data-count=\"6\"]{\n    li { width:16.666666%; }\n    li[data-revision=\"0\"] { left:2px; }\n    li[data-revision=\"1\"] { left:2px; }\n    li[data-revision=\"2\"] {  }\n    li[data-revision=\"3\"] {  }\n    li[data-revision=\"4\"] {  }\n    li[data-revision=\"5\"] { right:-1px; }\n    li[data-revision=\"6\"] { right:6px; }\n}\n\n// 5 revisions\n#lasso--revision-list[data-count=\"5\"] {\n\n    li { width:20%; }\n\n    li[data-revision=\"0\"] { left:-4px; }\n    li[data-revision=\"1\"] { left:-2px; }\n    li[data-revision=\"2\"] { left:0; }\n    li[data-revision=\"3\"] { right:-2px; }\n    li[data-revision=\"4\"] { right:-4px; }\n}\n\n// 4 revisions\n#lasso--revision-list[data-count=\"4\"] {\n\n    li { width:25%; }\n\n    li[data-revision=\"0\"] { left:-15px; }\n    li[data-revision=\"1\"] { left:-4px; }\n    li[data-revision=\"2\"] { right:-4px; }\n    li[data-revision=\"3\"] { right:-15px; }\n}\n\n// 3 revisions\n#lasso--revision-list[data-count=\"3\"] {\n\n    li { width:33.333%; }\n\n    li[data-revision=\"0\"] { left:-29px; }\n    li[data-revision=\"1\"] { left:0; }\n    li[data-revision=\"2\"] { right:-29px; }\n}\n// 2 revisions\n#lasso--revision-list[data-count=\"2\"] {\n\n    li { width:50%; }\n\n    li[data-revision=\"0\"] { left:-60px; }\n    li[data-revision=\"1\"] { right:-60px; }\n}\n\n// no revisions\n.lasso--revision-count-1 {\n\n}\n\n\n\n\n\n"
  },
  {
    "path": "public/assets/less/source/scrollbar.less",
    "content": ".ps-container.ps-active-x>.ps-scrollbar-x-rail,\n.ps-container.ps-active-y>.ps-scrollbar-y-rail {\n    display: block;\n}\n\n.ps-container>.ps-scrollbar-x-rail {\n    display: none;\n    position: absolute;\n    opacity: 0;\n    -ms-filter: \"alpha(Opacity=0)\";\n    filter: alpha(opacity=0);\n    -webkit-transition: background-color .2s linear,opacity .2s linear;\n    -moz-transition: background-color .2s linear,opacity .2s linear;\n    -o-transition: background-color .2s linear,opacity .2s linear;\n    transition: background-color .2s linear,opacity .2s linear;\n    bottom: 3px;\n    height: 8px;\n}\n\n.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x {\n    position: absolute;\n    background-color: @scrollbar--handle;\n    -webkit-transition: background-color .2s linear;\n    -moz-transition: background-color .2s linear;\n    -o-transition: background-color .2s linear;\n    transition: background-color .2s linear;\n    bottom: 0;\n    height: 8px;\n}\n\n.ps-container>.ps-scrollbar-x-rail.in-scrolling {\n    background-color: @scrollbar--rail;\n    opacity: .9;\n    -ms-filter: \"alpha(Opacity=90)\";\n    filter: alpha(opacity=90);\n}\n\n.ps-container>.ps-scrollbar-y-rail {\n    display: none;\n    position: absolute;\n    opacity: 0;\n    -ms-filter: \"alpha(Opacity=0)\";\n    filter: alpha(opacity=0);\n    -webkit-transition: background-color .2s linear,opacity .2s linear;\n    -moz-transition: background-color .2s linear,opacity .2s linear;\n    -o-transition: background-color .2s linear,opacity .2s linear;\n    transition: background-color .2s linear,opacity .2s linear;\n    right: 3px;\n    width: 8px;\n}\n\n.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y {\n    position: absolute;\n    background-color: @scrollbar--handle;\n    -webkit-transition: background-color .2s linear;\n    -moz-transition: background-color .2s linear;\n    -o-transition: background-color .2s linear;\n    transition: background-color .2s linear;\n    right: 0;\n    width: 8px;\n}\n\n.ps-container>.ps-scrollbar-y-rail.in-scrolling {\n    background-color: @scrollbar--rail;\n    .opacity(0.9);\n}\n\n.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail {\n   .opacity(0.6);\n}\n\n.ps-container:hover>.ps-scrollbar-x-rail.in-scrolling,.ps-container:hover>.ps-scrollbar-y-rail.in-scrolling {\n    background-color: @scrollbar--rail;\n    .opacity(0.9);\n}\n\n.ps-container:hover>.ps-scrollbar-x-rail:hover {\n    background-color: @scrollbar--rail;\n    .opacity(0.9);\n}\n\n.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x {\n    background-color: #999;\n}\n\n.ps-container:hover>.ps-scrollbar-y-rail:hover {\n    background-color: @scrollbar--rail;\n   .opacity(0.9);\n}\n\n.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y {\n    background-color: #999;\n}\n"
  },
  {
    "path": "public/assets/less/source/sidebar.less",
    "content": ".lasso-sidebar-open {\n    overflow: hidden;\n    .lasso-buttoninsert-wrap,\n    #lasso--sidebar {\n        right:0;\n\n    }\n\n}\n\n// modal outer\n#lasso--sidebar {\n    z-index: 9999;\n    position:fixed;\n    right:-@sidebar--width;\n    top:0;\n    bottom:0;\n    width:@sidebar--width;\n    .transition(right .25s ease);\n\n    * {\n        .box-sizing(border-box);\n    }\n\t\n\tlabel, p  {\n\t  color: @toolbar--color;\n\t  background: @sidebar--bg;\n\t}\n\t\n\tcode {\n\t  color: @toolbar--color;\n\t  background: @sidebar--bg;\n\t}\n\n}\n// account for admin bar\n.admin-bar {\n\n    #lasso--sidebar {\n        top:@admin-bar--height;\n    }\n    #lasso--component__settings {\n\n        form {\n            padding-bottom:@insert--height + @admin-bar--height; // height of insert\n        }\n    }\n}\n\n// sidebar inner\n\n.lasso--sidebar__inner {\n    height:100%;\n    font-family:@editor--font;\n    font-size: @sidebar--font__size;\n    background: @sidebar--bg;\n    border-left:4px solid @sidebar--bg__accent;\n    color:@sidebar--color;\n    text-shadow:0 1px 1px rgba(0,0,0,0.4);\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n    //overflow: scroll;\n    .box-shadow(inset 9px 0 9px -9px rgba(0,0,0,1));\n\n\n    // modal close // specificity\n    #lasso--sidebar__close {\n        color:@sidebar--close__color;\n    }\n\n    #lasso--component__settings {\n        overflow: hidden;\n        position: relative;\n    }\n}\n\n#lasso--sidebar__drag {\n    height:100px;\n    width:50px;\n    background:red;\n    top:50%;\n    bottom:0;\n    position:absolute;\n}"
  },
  {
    "path": "public/assets/less/source/sweet-alert.less",
    "content": ".sweet-overlay {\n    background-color: rgba(0, 0, 0, 0.4);\n    position: fixed;\n    left: 0;\n    right: 0;\n    top: 0;\n    bottom: 0;\n    display: none;\n    z-index: 1000;\n}\n\n.sweet-alert {\n    background-color: darken(@base,2);\n    font-family: @editor--font;\n    width: 478px;\n    padding: 17px;\n    border-radius: 5px;\n    text-align: center;\n    position: fixed;\n    left: 50%;\n    top: 50%;\n    margin-left: -256px;\n    margin-top: -200px;\n    overflow: hidden;\n    display: none;\n    z-index: 100002;\n    .box-shadow(0 0 10px 1px rgba(0,0,0,0.5) );\n\n    @media all and (max-width: 540px) {\n\n            width: auto;\n            margin-left: 0;\n            margin-right: 0;\n            left: 15px;\n            right: 15px;\n\n    }\n    h2 {\n        color: @toolbar--color;\n        font-size: 30px;\n        text-align: center;\n        font-weight: 600;\n        text-transform: none;\n        position: relative;\n        margin: 25px 0;\n        padding: 0;\n        line-height: 40px;\n        display: block;\n        font-family: inherit;\n\n    }\n    p {\n        color: @modal--color;\n        font-size: 16px;\n        text-align: center;\n        font-weight: 300;\n        position: relative;\n        text-align: inherit;\n        float: none;\n        margin: 0;\n        padding: 0;\n        line-height: normal;\n\n        ~ button {\n            margin-bottom:20px;\n        }\n    }\n    // button\n    button {\n        background-color: @editor--color__update;\n        color: white;\n        border: none;\n        box-shadow: none;\n        font-size: 17px;\n        font-family:@editor--font;\n        font-weight: 500;\n        border-radius: 5px;\n        padding: 10px 32px;\n        margin: 26px 5px 0 5px;\n        cursor: pointer;\n\n        &:focus {\n            outline: none;\n            box-shadow: 0 0 2px rgba(128, 179, 235, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.05);\n        }\n        &:hover {\n            background-color: #a1d9f2;\n        }\n        &:active {\n            background-color: #81ccee;\n        }\n        &.cancel {\n            background:none;\n            color:@editor--color__error;\n        }\n        &.cancel:hover {\n            background:none;\n        }\n        &.cancel:active {\n            background:none;\n         }\n        &.cancel:focus {\n            box-shadow: rgba(197, 205, 211, 0.8) 0px 0px 2px, rgba(0, 0, 0, 0.0470588) 0px 0px 0px 1px inset !important;\n        }\n    }\n    button::-moz-focus-inner {\n        border: 0;\n    }\n\n    // icon\n    .icon {\n        width: 80px;\n        height: 80px;\n        border: 4px solid gray;\n        border-radius: 50%;\n        margin: 20px auto;\n        padding: 0;\n        position: relative;\n        box-sizing: content-box;\n\n        &.error {\n            border-color: @editor--color__error;\n        }\n        &.error .x-mark {\n            position: relative;\n            display: block;\n        }\n        &.error .line {\n            position: absolute;\n            height: 5px;\n            width: 47px;\n            background-color: @editor--color__error;\n            display: block;\n            top: 37px;\n            border-radius: 2px;\n        }\n        &.error .line.left {\n              -webkit-transform: rotate(45deg);\n              transform: rotate(45deg);\n              left: 17px;\n        }\n        &.error .line.right {\n              -webkit-transform: rotate(-45deg);\n              transform: rotate(-45deg);\n              right: 16px;\n        }\n        &.warning {\n            border-color: @editor--color__error;\n        }\n        &.warning .body {\n            position: absolute;\n            width: 5px;\n            height: 47px;\n            left: 50%;\n            top: 10px;\n            border-radius: 2px;\n            margin-left: -2px;\n            background-color: @editor--color__error;\n        }\n        &.warning .dot {\n            position: absolute;\n            width: 7px;\n            height: 7px;\n            border-radius: 50%;\n            margin-left: -3px;\n            left: 50%;\n            bottom: 10px;\n            background-color: @editor--color__error;\n        }\n        &.info {\n            border-color: @editor--color__update;\n        }\n        &.info::before {\n            content: \"\";\n            position: absolute;\n            width: 5px;\n            height: 29px;\n            left: 50%;\n            bottom: 17px;\n            border-radius: 2px;\n            margin-left: -2px;\n            background-color: @editor--color__update;\n        }\n        &.info::after {\n            content: \"\";\n            position: absolute;\n            width: 7px;\n            height: 7px;\n            border-radius: 50%;\n            margin-left: -3px;\n            top: 19px;\n            background-color: @editor--color__update;\n        }\n        &.success {\n            border-color: #A5DC86;\n        }\n        &.success::before,\n        &.success::after {\n            content: '';\n            border-radius: 50%;\n            position: absolute;\n            width: 60px;\n            height: 120px;\n            background: white;\n            -webkit-transform: rotate(45deg);\n            transform: rotate(45deg); \n        }\n        &.success::before {\n            border-radius: 120px 0 0 120px;\n            top: -7px;\n            left: -33px;\n            -webkit-transform: rotate(-45deg);\n            transform: rotate(-45deg);\n            -webkit-transform-origin: 60px 60px;\n            transform-origin: 60px 60px;\n        }\n\n        &.success::after {\n            border-radius: 0 120px 120px 0;\n            top: -11px;\n            left: 30px;\n            -webkit-transform: rotate(-45deg);\n            transform: rotate(-45deg);\n            -webkit-transform-origin: 0px 60px;\n            transform-origin: 0px 60px;\n        }\n        &.success .placeholder {\n            width: 80px;\n            height: 80px;\n            border: 4px solid rgba(165, 220, 134, 0.2);\n            border-radius: 50%;\n            box-sizing: content-box;\n            position: absolute;\n            left: -4px;\n            top: -4px;\n            z-index: 2;\n        }\n        &.success .fix {\n            width: 5px;\n            height: 90px;\n            background-color: white;\n            position: absolute;\n            left: 28px;\n            top: 8px;\n            z-index: 1;\n            -webkit-transform: rotate(-45deg);\n            transform: rotate(-45deg);\n        }\n        &.success .line {\n            height: 5px;\n            background-color: #A5DC86;\n            display: block;\n            border-radius: 2px;\n            position: absolute;\n            z-index: 2;\n        }\n        &.success .line.tip {\n              width: 25px;\n              left: 14px;\n              top: 46px;\n              -webkit-transform: rotate(45deg);\n              transform: rotate(45deg);\n          }\n        &.success .line.long {\n              width: 47px;\n              right: 8px;\n              top: 38px;\n              -webkit-transform: rotate(-45deg);\n              transform: rotate(-45deg);\n          }\n        &.custom {\n            background-size: contain;\n            border-radius: 0;\n            border: none;\n            background-position: center center;\n            background-repeat: no-repeat;\n        }\n    }\n\t\n\t#shortcode_edit { \n\t    width:100%;\n\t    height: 200px; \n\t\tcolor:black; \n\t\tfont-size: small; \n\t\tfont-family: \"Lucida Console\", \n\t\t\"Courier New\", monospace;\n\t}\n}\n\n\n.sweet-alert[data-has-cancel-button=false] button {\n    box-shadow: none !important;\n}\n\n/*\n * Animations\n */\n@-webkit-keyframes showSweetAlert {\n  0% {\n    transform: scale(0.7);\n    -webkit-transform: scale(0.7); }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1); } }\n@-moz-keyframes showSweetAlert {\n  0% {\n    transform: scale(0.7);\n    -webkit-transform: scale(0.7); }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1); } }\n@keyframes showSweetAlert {\n  0% {\n    transform: scale(0.7);\n    -webkit-transform: scale(0.7); }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1); } }\n@-webkit-keyframes hideSweetAlert {\n  0% {\n    transform: scale(1);\n    -webkit-transform: scale(1); }\n  100% {\n    transform: scale(0.5);\n    -webkit-transform: scale(0.5); } }\n@-moz-keyframes hideSweetAlert {\n  0% {\n    transform: scale(1);\n    -webkit-transform: scale(1); }\n  100% {\n    transform: scale(0.5);\n    -webkit-transform: scale(0.5); } }\n@keyframes hideSweetAlert {\n  0% {\n    transform: scale(1);\n    -webkit-transform: scale(1); }\n  100% {\n    transform: scale(0.5);\n    -webkit-transform: scale(0.5); } }\n.showSweetAlert {\n  -webkit-animation: showSweetAlert 0.2s;\n  -moz-animation: showSweetAlert 0.2s;\n  animation: showSweetAlert 0.2s; }\n\n.hideSweetAlert {\n  -webkit-animation: hideSweetAlert 0.2s;\n  -moz-animation: hideSweetAlert 0.2s;\n  animation: hideSweetAlert 0.2s; }\n\n\n.animateSuccessTip {\n  -webkit-animation: animateSuccessTip 0.75s;\n  -moz-animation: animateSuccessTip 0.75s;\n  animation: animateSuccessTip 0.75s; }\n\n.animateSuccessLong {\n  -webkit-animation: animateSuccessLong 0.75s;\n  -moz-animation: animateSuccessLong 0.75s;\n  animation: animateSuccessLong 0.75s; }\n\n.icon.success.animate::after {\n  -webkit-animation: rotatePlaceholder 4.25s ease-in;\n  -moz-animation: rotatePlaceholder 4.25s ease-in;\n  animation: rotatePlaceholder 4.25s ease-in; }\n"
  },
  {
    "path": "public/assets/less/source/toolbar.less",
    "content": "// main toolbar layout\n.lasso--toolbar_wrap {\n\n    width: auto;\n    left: 50%;\n    .translate(-50%, 0);\n\n    &.toolbar-extended {\n\n    }\n\n}\n\n// global styles wrapper for editor and toolbar controls\n.lasso-editor-controls--wrap {\n\n    * { .box-sizing(border-box); }\n\n    .editor--tool__bg();\n    height:@toolbar--height;\n    font-size:16px;\n    border-radius:@editor--radius;\n    position:fixed;\n    text-align: center;\n    bottom:@toolbar--pos__bottom;\n    z-index: @z-index--toolbar;\n}\n\n\n// global styles  ul for the editor and toolbar controls\nul.lasso-editor-controls{\n    margin:0;\n    padding:0;\n    letter-spacing: 0;\n    list-style: none;\n    height:@toolbar--height;\n    line-height:1;\n    .clearfix();\n\n    li {\n        height:@toolbar--height - 2;\n        position:relative;\n        float:left;\n        padding:@toolbar--item__padding;\n        border-right:1px solid lighten(@toolbar--border,5);\n        text-align: center;\n        text-shadow:0 1px 1px @text-shadow;\n        line-height:1;\n\t\tmargin:0;\n\n        &:before {\n            .editor-icon-font();\n            .transition(all .2s ease);\n            position: relative;\n            top:10px;\n        }\n\n        &:first-child:hover {\n            border-top-left-radius: @editor--radius;\n            border-bottom-left-radius: @editor--radius;\n        }\n\n        &:last-child {\n            border-right:0;\n\n            &:hover {\n                border-top-right-radius: @editor--radius;\n                border-bottom-right-radius: @editor--radius;\n            }\n        }\n\n        &:hover {\n            cursor: pointer;\n            background: @toolbar--hover;\n        }\n\n        &:active {\n            .box-shadow(inset 0 1px 1px rgba(0,0,0,0.4));\n        }\n    }\n}\n\n// toolbar buttons\n#lasso-toolbar--bold:before {\n    content:'\\ea62';\n}\n#lasso-toolbar--italic:before {\n    content:'\\ea64';\n}\n#lasso-toolbar--underline:before {\n   content:'\\ea63';\n}\n#lasso-toolbar--strike:before {\n    content:'\\ea65';\n}\n#lasso-toolbar--link:before {\n    content:'\\e9cb';\n}\n#lasso-toolbar--ol:before {\n    //content:'OL';\n\tcontent: \"\\e9b9\";\n    top:9px;\n\tfont-size:18px;\n    //font-weight:bold;\n    letter-spacing: 0.05em;\n}\n#lasso-toolbar--ul:before {\n    //content:'UL';\n\tcontent: \"\\e9bc\";\n    top:9px;\n\tfont-size:18px;\n    //font-weight:bold;\n    letter-spacing: 0.05em;\n}\n\n#lasso-toolbar--h2:before {\n    content:'H2';\n    top:9px;\n    font-size:18px;\n    font-weight:bold;\n    letter-spacing: 0.05em;\n}\n#lasso-toolbar--h3:before {\n    content:'H3';\n    top:9px;\n    font-size:18px;\n    font-weight:bold;\n    letter-spacing: 0.05em;\n}\n#lasso-toolbar--h4:before {\n    content:'H4';\n    top:9px;\n    //font-size:17px;\n    font-weight:bold;\n    letter-spacing: 0.05em;\n}\n#lasso-toolbar--h5:before {\n    content:'H5';\n    top:9px;\n    //font-size:17px;\n    font-weight:bold;\n    letter-spacing: 0.05em;\n}\n#lasso-toolbar--h6:before {\n    content:'H6';\n    top:9px;\n    //font-size:17px;\n    font-weight:bold;\n    letter-spacing: 0.05em;\n}\n#lasso-toolbar--html:before {\n    content:'\\ea7f';\n}\n#lasso-toolbar--components:before {\n    content:'\\ea0a';\n}\n\n#lasso-toolbar--color-set:before {\n    content:'A';\n\t//top:5px;\n    //font-size:21px;\n    font-weight:bold;\n    letter-spacing: 0.05em;\n\t//color: #ff0;\n\t//font-family:Dashicons;\n}\n\n#lasso-toolbar--color-pick:before {\n    //content:'\\f309';\n\tcontent:'\\f100';\n\t//color: #ff0;\n\tfont-family:Dashicons;\n}\n\n#lasso-toolbar--left-align:before {\n    content:'\\f206';\n\tfont-family:Dashicons;\n}\n\n#lasso-toolbar--center-align:before {\n    content:'\\f207';\n\tfont-family:Dashicons;\n}\n\n#lasso-toolbar--right-align:before {\n    content:'\\f208';\n\tfont-family:Dashicons;\n}\n\n\n// html drop up\n#lasso-toolbar--html {\n\n    #lasso-toolbar--html__wrap{\n        position: absolute;\n        left:-10000px;\n        .opacity(0);\n    }\n\n    &.html--drop-down,\n    &.html--drop-up {\n\n        * {\n            .box-sizing(border-box);\n            -webkit-font-smoothing: antialiased;\n             -moz-osx-font-smoothing: grayscale;\n        }\n        box-shadow:none;\n        background:@toolbar--hover;\n\n       #lasso-toolbar--html__wrap{\n            margin:0;\n            padding:4px;\n            .opacity(1);\n            list-style-type: none;\n            width:@toolbar--htmldrop__width;\n            height:@toolbar--htmldrop__height;\n            bottom:45px;\n            border-radius:@editor--radius;\n            left:-@toolbar--htmldrop__width / 2 + 16;\n            background:@toolbar--bg__accent;\n\n            &:after {\n                content:'';\n                position:absolute;\n                width: 0;\n                height: 0;\n                border-left: 6px solid transparent;\n                border-right: 6px solid transparent;\n                border-top: 6px solid @toolbar--hover;\n                left:0;\n                right:0;\n                bottom:-6px;\n                text-align: center;\n                margin:0 auto;\n            }\n\n            &:hover {\n                cursor: default;\n            }\n        }\n\n        #lasso-toolbar--html__inner {\n            background: @toolbar--htmldrop__bg;\n            color:@toolbar--htmldrop__color;\n            height:@toolbar--htmldrop__theight;\n            overflow: scroll;\n            text-align: left;\n            line-height: 1.25;\n            padding:@toolbar--htmldrop__padding;\n            border-radius: @editor--radius - 2;\n            font-family: monospace;  /* monospace font */\n            white-space: pre;        /* behave like <pre> */\n            font-size: @toolbar--htmldrop__font-size;\n            .box-shadow(inset 0 0 4px 1px rgba(0,0,0,0.25));\n\n            &:empty:before {\n                content: attr(placeholder);\n                color:fadeout(@toolbar--htmldrop__color,50);\n            }\n\n            &:hover {\n                cursor: text;\n            }\n            &:focus {\n                outline: none;\n            }\n        }\n\n        #lasso-toolbar--html__footer {\n            text-align: right;\n            font-family: @editor--font;\n            padding:7px 2px 2px;\n            height:@toolbar--htmldrop__fheight;\n\n            a {\n                font-size:@toolbar--htmldrop__font-size;\n                font-weight:bold;\n                padding:5px 7px 4px;\n                line-height: 1;\n                border-radius:@editor--radius - 2;\n                display: inline-block;\n                text-decoration: none;\n                color:white;\n                text-shadow:0 1px 1px @text-shadow;\n            }\n\n            // inset html\n            #lasso-toolbar--html__insert {\n                background:@editor--color__update;\n\n                &:hover {\n                    background: darken(@editor--color__update,7);\n                }\n                &:active {\n                    background: darken(@editor--color__update,14);\n                    .box-shadow(inset 1px 1px 2px rgba(0,0,0,0.4));\n                }\n            }\n\n            // cancel\n            .lasso-toolbar--html__cancel {\n                color:@editor--color__error;\n            }\n\t\t\t\n\t\t\t#lasso-toolbar--html__footer_desc {\n\t\t\t    text-align:left;\n\t\t\t\tcolor:white;\n\t\t\t\tfont-size:14px;\n\t\t\t}\n        }\n    }\n}\n\n// html insert icons\n#lasso-toolbar--html__footer ul.lasso-toolbar--html-snips {\n    font-size:@toolbar--htmldrop__font-size - 2;\n    line-height: 0;\n    float:left;\n    margin:0;\n    padding-left:0;\n    list-style:none;\n    .clearfix();\n\n    li {\n        line-height: 0;\n        height:25px;\n        margin-right:4px;\n        border:none;\n        //background:@toolbar--htmldrop__bg;\n        border:1px solid darken(@toolbar--htmldrop__bg,2);\n        border-radius:@editor--radius;\n        .box-shadow(inset 1px 1px 0 rgba(255,255,255,0.05));\n\n        &:before {\n            top:5px;\n        }\n\n        &:last-child {\n            border-right:1px solid darken(@toolbar--htmldrop__bg,2);\n        }\n    }\n\n    #lasso-html--h2:before {\n        content:'H2';\n    }\n    #lasso-html--h3:before {\n        content:'H3';\n    }\n    #lasso-html--ul:before {\n        content:'UL';\n    }\n    #lasso-html--ol:before {\n        content:'OL';\n    }\n\t#lasso-html--table:before {\n        //content: \"\\f509\";\n\t\t//content: \"Table\";\n    }\n}\n\n// components drop up\n#lasso-side-comp-button,\n#lasso-toolbar--components{\n\n    ul {\n        position: absolute;\n        left:-10000px;\n        .opacity(0);\n    }\n\n    // drop up menu\n    &.toolbar--drop-down,\n    &.toolbar--drop-up,\n\t&.toolbar--side\t{\n\n        * { .box-sizing(border-box); }\n        box-shadow:none;\n        //background:@toolbar--hover;\n\n        ul {\n            margin:0;\n            padding:4px;\n            .opacity(1);\n            list-style-type: none;\n            width:@toolbar--drop__width;\n            height:auto;//@toolbar--drop__height;\n            top:-@toolbar--drop__height - 6;\n            border-radius:@editor--radius;\n            left:-@toolbar--drop__width / 2 + 16;\n            //background:@toolbar--bg__accent;\n            line-height: 0;\n            column-gap:0;\n\n            &:after {\n                content:'';\n                position:absolute;\n                width: 0;\n                height: 0;\n                border-left: 6px solid transparent;\n                border-right: 6px solid transparent;\n                border-top: 6px solid @toolbar--hover;\n                left:0;\n                right:0;\n                bottom:-6px;\n                text-align: center;\n                margin:0 auto;\n            }\n\n            li {\n                line-height:0;\n                text-align: center;\n                position:relative;\n                font-size:20px;\n                text-shadow:0 1px 1px @text-shadow;\n                border-right:none;\n                margin:1px;\n                padding:2px;\n                height:36px;\n                width:40px;\n                //background:lighten(@toolbar--bg,3);\n                background:none;\n                border-left:1px solid rgba(255,255,255,0.1);\n                border-top:1px solid rgba(255,255,255,0.1);\n                .box-shadow(1px 1px 0 rgba(0,0,0,0.3));\n\n                &:before {\n                    top:6px;\n                }\n\n\n                &:hover {\n                    cursor: move;\n                    background:@toolbar--bg;\n                    border-radius: 0;\n                }\n\n                &.active,\n                &:active {\n                    .box-shadow(inset 0 1px 1px rgba(0,0,0,0.4));\n                    background:darken(@toolbar--bg,4);\n                }\n\n                // icons on draggable items\n                .editor--icon__list();\n\n            }\n        }\n\n    }\n}\n\n// link drop up\n#lasso-toolbar--link {\n\n    * { .box-sizing(border-box); }\n\n    // drop up\n    #lasso-toolbar--link__wrap {\n        position: absolute;\n        left:-10000px;\n        .opacity(0);\n    }\n\n    &.link--drop-down,\n    &.link--drop-up {\n        box-shadow:none;\n        background:@toolbar--hover;\n\n        #lasso-toolbar--link__wrap {\n            margin:0;\n            padding:4px;\n            .opacity(1);\n            list-style-type: none;\n            width:@toolbar--linkdrop__width;\n            height:@toolbar--linkdrop__height;\n            bottom:45px;\n            border-radius:@editor--radius;\n            left:-@toolbar--linkdrop__width / 2 + 16;\n            background:@toolbar--bg__accent;\n\n            &:after {\n                content:'';\n                position:absolute;\n                width: 0;\n                height: 0;\n                border-left: 6px solid transparent;\n                border-right: 6px solid transparent;\n                border-top: 6px solid @toolbar--hover;\n                left:0;\n                right:0;\n                bottom:-6px;\n                text-align: center;\n                margin:0 auto;\n            }\n\n            &:hover {\n                cursor: default;\n            }\n        }\n        #lasso-toolbar--link__inner {\n            background: @toolbar--htmldrop__bg;\n            color:@toolbar--htmldrop__color;\n            height:@toolbar--linkdrop__height - 38;\n            white-space: nowrap;\n            overflow: hidden;\n            text-align: left;\n            line-height: 1.25;\n            padding:@toolbar--htmldrop__padding;\n            border-radius: @editor--radius - 2;\n            font-family: monospace;  /* monospace font */\n            font-size: @toolbar--htmldrop__font-size;\n            .box-shadow(inset 0 0 4px 1px rgba(0,0,0,0.25));\n\n            &:empty:before {\n                content: attr(placeholder);\n                color:fadeout(@toolbar--htmldrop__color,50);\n            }\n\n            &:after {\n                content:'';\n                height:20px;\n                width:20px;\n                position:absolute;\n                background: @toolbar--htmldrop__bg;\n                border-top-right-radius: 2px;\n                border-bottom-right-radius: 2px;\n                right: 4px;\n                top: 4px;\n                height: 32px;\n                width: 36px;\n            }\n\n            &:hover {\n                cursor: text;\n            }\n            &:focus {\n                outline: none;\n            }\n        }\n    }\n\n    // save link\n    .lasso-toolbar--link__control {\n        position: absolute;\n        top:9px;\n        right:5px;\n        width:25px;\n        font-family: @editor--font;\n        font-size:@toolbar--htmldrop__font-size - 2;\n        font-weight:bold;\n        padding:5px 7px 4px;\n        line-height: 1;\n        border-radius:@editor--radius - 2;\n        display: inline-block;\n        text-decoration: none;\n        color:white;\n        text-shadow:0 1px 1px @text-shadow;\n        background: @editor--color__update;\n\n        &:before {\n            .editor-icon-font();\n            content:'\\ea10';\n        }\n    }\n\t\n\t.styled-checkbox {\n\t    position: absolute;\n        top:45px;\n        left:8px;\n\t}\n\tlabel {\n\t    position: absolute;\n        top:45px;\n        left:41px;\n\t\tfont-family: @editor--font;\n\t\tcolor: white;\n\t\tfont-size:@toolbar--htmldrop__font-size - 2;\n\t}\n}\n\n// aesop not active\n.ase-not-active {\n    @width:94px;\n    #lasso-toolbar--components {\n        #lasso-toolbar--components__list {\n            width:@width;\n            left: ~'calc(50% - @{width} / 2)';\n            height:48px;\n            top:-55px !important;\n        }\n    }\n}\n\n#lasso-toolbar--components__list,#lasso-toolbar--link__wrap, #lasso-toolbar--html__wrap, .iris-picker{\n    z-index: @z-index--toolbar+1;\n}\n\n//side component button\n#lasso-side-comp-button.toolbar--side {\n\tbackground:none;\n}\n#lasso-side-comp-button:before {\n\t content: \"\\f502\";\n\t font-family: dashicons;\n    display: inline-block;\n    font-weight: 400;\n\tfont-size:30px;\n}\n\n#lasso-side-comp-button li {\n    float: left;\n}\n\n#lasso-side-comp-button ul:after {\n    content:none !important;\n}\n\n\n#lasso-side-comp-button li:before \n{\n    font-family: icomoon-editus;\n    display: inline-block;\n    font-style: normal;\n    font-weight: 400;\n    font-variant: normal;\n    text-transform: none;\n    line-height: 1;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n    -webkit-transition: all .2s ease;\n    -moz-transition: all .2s ease;\n    transition: all .2s ease;\n    position: relative;\n    top: 10px;\n}\n\n\n"
  },
  {
    "path": "public/assets/less/source/tour.less",
    "content": ".lasso--tour__modal {\n\n    .lasso--postsettings__footer {\n        .clearfix();\n    }\n\n    .lasso--modal__inner {\n        position: relative;\n    }\n\n    .lasso--postsettings__option {\n        border-bottom: none;\n        box-shadow:none;\n        padding-bottom:0;\n        margin-bottom: 0;\n        float: left;\n        top:4px;\n        position: relative;\n        .opacity(0.85);\n\n        label {\n            padding-left:23px;\n            font-size:@modal--font__size;\n            font-weight: normal;\n\t\t\tcolor:#fff;\n        }\n\n        .control-indicator {\n            width:14px;\n            height:14px;\n            top:0;\n        }\n    }\n    #lasso--tour__slides {\n        position: relative;\n        overflow: auto;\n        display: none;\n    }\n\n    ul {\n        margin:0;\n        padding:0;\n        list-style: none;\n        .clearfix();\n\n        li {\n            float: left;\n        }\n    }\n\n    li {\n        img{\n            background: @modal--border;\n            padding:6px;\n            border-radius:3px;\n            .box-shadow(0 1px 1px rgba(255,255,255,0.1));\n        }\n        p {\n            font-family: @editor--font;\n            font-size:@modal--font__size + 2;\n            line-height: 1.25;\n            margin:15px auto 28px;\n            padding-right:4px;\n            padding-left:4px;\n        }\n    }\n    .dots {\n        position: absolute;\n        left: 0;\n        right:0;\n        right: 0;\n        bottom: -10px;\n        text-align: center;\n        width: 100%;\n        margin:0;\n\t\theight:30px;\n\n        li {\n            display: inline-block;\n            width: 14px;\n            height: 14px;\n            line-height: 16px;\n            margin: 0 3px;\n            text-indent: -999em;\n            border: 1px solid @modal--border;\n             background: fadeout(@editor--color__update,25);\n            border-radius: 100%;\n            cursor: pointer;\n            .opacity(.4);\n            -webkit-transition: background .5s, opacity .5s;\n            -moz-transition: background .5s, opacity .5s;\n            transition: background .5s, opacity .5s;\n            .box-shadow(0 1px 1px rgba(255,255,255,0.1));\n\n            &.active {\n                background: white;\n                opacity: 1;\n            }\n        }\n\n    }\n\t\n\tinput[type=\"submit\"] {\n        .editor-btn-primary();\n    }\n}\n\n.lasso--loading {\n    height:auto;\n    //position: absolute;\n    left:0;\n    top:0;\n    right:0;\n    width:100%;\n}\n\n\n.lasso--loader {\n    height:40px;\n    width:40px;\n    margin:10px auto;\n    top:48%;\n    position:relative;\n    -webkit-animation: rotation .6s infinite linear;\n    -moz-animation: rotation .6s infinite linear;\n    -o-animation: rotation .6s infinite linear;\n    animation: rotation .6s infinite linear;\n    border-left:3px solid fadeout(@loader--color,80);\n    border-right:3px solid fadeout(@loader--color,80);\n    border-bottom:3px solid fadeout(@loader--color,80);\n    border-top:3px solid @loader--color;\n    border-radius:100%;\n}\n\n@-webkit-keyframes rotation {\n    from {-webkit-transform: rotate(0deg);}\n    to {-webkit-transform: rotate(359deg);}\n}\n\n@-moz-keyframes rotation {\n    from {-moz-transform: rotate(0deg);}\n    to {-moz-transform: rotate(359deg);}\n}\n\n@-o-keyframes rotation {\n    from {-o-transform: rotate(0deg);}\n    to {-o-transform: rotate(359deg);}\n}\n\n@keyframes rotation {\n    from {transform: rotate(0deg);}\n    to {transform: rotate(359deg);}\n}"
  },
  {
    "path": "public/assets/less/source/util--tags.less",
    "content": ".story-tags-option,\n.story-categories-option,\n.story-custom-taxonomy-option {\n\n    // the tags\n    .tagit {\n        padding: 4px 0 0;\n        overflow: auto;\n        margin-left: inherit; /* usually we don't want the regular ul margins. */\n        margin-right: inherit;\n        border-radius:3px;\n        list-style:none;\n\n        li {\n            float:left;\n\n            &.tagit-choice {\n                position: relative;\n                margin: 2px;\n                display: inline;\n                padding: 4px 8px 4px 18px;\n                font-family: @editor--font;\n                font-size:@tag--font__size;\n                line-height: @tag--font__size + 4;\n                color: @tag--color;\n                text-align: center;\n                white-space: nowrap;\n                vertical-align: baseline;\n                border-radius: 2px;\n                background:fadeout(@tag--bg,25);\n            }\n\n            .tagit-close {\n                cursor: pointer;\n                position:absolute;\n                left:7px;\n                color:@tag--color;\n                top:5px;\n\n                &:hover {\n                    text-decoration: none;\n                    color:@tag--color;\n                }\n            }\n\n            &.tagit-new {\n                position: relative;\n                top:-6px;\n            }\n            input[type=\"text\"] {\n                box-shadow: none;\n                border: none;\n                border-radius:0;\n                margin: 0;\n                padding: 0 0 0 4px;\n                width: inherit;\n                background-color: #fff !important;\n\t\t\t\tcolor: #000 !important;\n                outline: none;\n                font-size:@tag--font__size;\n                line-height: @tag--font__size + 12;\n                display: inline-block;\n                margin: 2px 5px 2px 0;\n                color:fadeout(@tag--color,50);\n            }\n\n        }\n    }\n\n    input.tagit-hidden-field {\n        display: none;\n    }\n\n    ul.tagit li.tagit-choice a.tagit-label {\n        cursor: pointer;\n        text-decoration: none;\n    }\n\n}\n\n.story-categories-option {\n    border-bottom:none;\n    box-shadow:none;\n    margin-bottom: 0;\n}\n\n.story-tags-option {\n    // the tags\n    .tagit li.tagit-choice {\n        position: relative;\n        margin: 2px 2px 2px 15px;\n        padding: 4px 8px 4px 12px;\n        border-top-left-radius: 0;\n        border-bottom-left-radius: 0;\n\n        &:before {\n            content: '';\n            position: absolute;\n            width: 0;\n            height: 0;\n            border-top: 12px solid transparent;\n            border-bottom: 12px solid transparent;\n            border-right: 14px solid @tag--bg;\n            left: -14px;\n            top: 0;\n        }\n\n        .tagit-close {\n            left:0;\n        }\n    }\n\n\n}\n\n.lasso-modal-open {\n        // autocomplete dropdown\n    .ui-autocomplete {\n        position: absolute;\n        top: 100%;\n        left: 0;\n        z-index: 100002;\n        float: left;\n        display: none;\n        min-width: 160px;\n        padding: 4px;\n        margin: 2px 0 0 0;\n        list-style: none;\n        color:@tag--color;\n        background-color: @modal--bg__accent;\n        border-radius: 3px;\n        box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n        -webkit-background-clip: padding-box;\n        -moz-background-clip: padding;\n        background-clip: padding-box;\n\n        .ui-menu-item {\n            display: block;\n            padding: 1px 2px;\n            clear: both;\n            font-weight: normal;\n            line-height: 18px;\n\t\t\t\n            white-space: nowrap;\n            font-family: @editor--font;\n            font-size:@modal--font__size;\n\t\t\tbackground-color: @modal--bg;\n\t\t\ta {\n\t\t\t\tbackground-color: @modal--bg;\n\t\t\t\tcolor: white;//@tag--color;\n\t\t\t}\n\n            &:hover,\n            &.ui-state-active {\n                cursor: pointer;\n                //background:darken(@modal--bg__accent,7);\n            }\n        }\n    }\n\t\n\t.ui-autocomplete.tagit-autocomplete {\n\t\toverflow-y: scroll;\n\t\tmax-height: 310px;\n\t}\n\n}"
  },
  {
    "path": "public/assets/less/source/util--tooltips.less",
    "content": "// lasso tooltip\n.lasso-util--help {\n    position: relative;\n    cursor: pointer;\n    color: @tooltip--icon__color;\n    display: inline-block;\n    .transition(opacity .15s ease);\n    .opacity(0.75);\n\n    &:hover {\n        text-decoration: none;\n        .opacity(1);\n    }\n\n    // base styles\n    &:before,\n    &:after {\n        position: absolute;\n        visibility: hidden;\n        .opacity(0);\n        -webkit-transition:\n            opacity 0.2s ease-in-out,\n            visibility 0.2s ease-in-out,\n            -webkit-transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n        -moz-transition:\n            opacity 0.2s ease-in-out,\n            visibility 0.2s ease-in-out,\n            -moz-transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n        transition:\n            opacity 0.2s ease-in-out,\n            visibility 0.2s ease-in-out,\n            transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n        -webkit-transform: translate3d(0, 0, 0);\n        -moz-transform:    translate3d(0, 0, 0);\n        transform:         translate3d(0, 0, 0);\n        pointer-events: none;\n    }\n\n    // show on hover and focus\n    &:hover:before,\n    &:hover:after,\n    &:focus:before,\n    &:focus:after {\n        visibility: visible;\n        .opacity(1);\n    }\n\n\n    // base style caret\n    &:before {\n        z-index: 10001;\n        border: 6px solid transparent;\n        background: transparent;\n        content: \"\";\n    }\n\n    // base style for content area\n    &:after {\n        z-index: 1000;\n        padding: 8px;\n        width: 160px;\n        background-color: @tooltip--bg;\n        color: @tooltip--color;\n        font-family: @editor--font;\n        //text-shadow:1px 1px rgba(255,255,255,0.2);\n        content: attr(data-tooltip);\n        font-size: @tooltip--font__size;\n        line-height: 1.2;\n        border-radius:@editor--radius - 2;\n    }\n}\n\n/* Directions */\n\n/* Top (default) */\n.lasso-util--help:before,\n.lasso-util--help:after,\n.lasso-util--help-top:before,\n.lasso-util--help-top:after {\n  bottom: 100%;\n  left: 50%;\n}\n\n.lasso-util--help:before,\n.lasso-util--help-top:before {\n  margin-left: -6px;\n  margin-bottom: -12px;\n  border-top-color: @tooltip--bg;\n}\n\n/* Horizontally align top/bottom.lasso-util--helps */\n\n.lasso-util--help:after,\n.lasso-util--help-top:after {\n  margin-left: -80px;\n}\n\n\n.lasso-util--help:hover:before,\n.lasso-util--help:hover:after,\n.lasso-util--help:focus:before,\n.lasso-util--help:focus:after,\n.lasso-util--help-top:hover:before,\n.lasso-util--help-top:hover:after,\n.lasso-util--help-top:focus:before,\n.lasso-util--help-top:focus:after {\n  -webkit-transform: translateY(-12px);\n  -moz-transform:    translateY(-12px);\n  transform:         translateY(-12px); \n}\n\n/* Left */\n.lasso-util--help-left:before,\n.lasso-util--help-left:after {\n  right: 100%;\n  bottom: 50%;\n  left: auto;\n}\n\n.lasso-util--help-left:before {\n  margin-left: 0;\n  margin-right: -12px;\n  margin-bottom: 0;\n  border-top-color: transparent;\n  border-left-color: @tooltip--bg;\n}\n\n.lasso-util--help-left:hover:before,\n.lasso-util--help-left:hover:after,\n.lasso-util--help-left:focus:before,\n.lasso-util--help-left:focus:after {\n  -webkit-transform: translateX(-12px);\n  -moz-transform:    translateX(-12px);\n  transform:         translateX(-12px); \n}\n\n/* Bottom */\n.lasso-util--help-bottom:before,\n.lasso-util--help-bottom:after {\n  top: 100%;\n  bottom: auto;\n  left: 50%;\n}\n\n.lasso-util--help-bottom:before {\n  margin-top: -12px;\n  margin-bottom: 0;\n  border-top-color: transparent;\n  border-bottom-color: @tooltip--bg;\n}\n\n.lasso-util--help-bottom:hover:before,\n.lasso-util--help-bottom:hover:after,\n.lasso-util--help-bottom:focus:before,\n.lasso-util--help-bottom:focus:after {\n  -webkit-transform: translateY(12px);\n  -moz-transform:    translateY(12px);\n  transform:         translateY(12px); \n}\n\n/* Right */\n.lasso-util--help-right:before,\n.lasso-util--help-right:after {\n  bottom: 50%;\n  left: 100%;\n}\n\n.lasso-util--help-right:before {\n  margin-bottom: 0;\n  margin-left: -12px;\n  border-top-color: transparent;\n  border-right-color: @tooltip--bg;\n}\n\n.lasso-util--help-right:hover:before,\n.lasso-util--help-right:hover:after,\n.lasso-util--help-right:focus:before,\n.lasso-util--help-right:focus:after {\n  -webkit-transform: translateX(12px);\n  -moz-transform:    translateX(12px);\n  transform:         translateX(12px); \n}\n\n/* Move directional arrows down a bit for left/right.lasso-util--helps */\n.lasso-util--help-left:before,\n.lasso-util--help-right:before {\n  top: 3px;\n}\n\n/* Vertically center.lasso-util--help content for left/right.lasso-util--helps */\n.lasso-util--help-left:after,\n.lasso-util--help-right:after {\n  margin-left: 0;\n  margin-bottom: -16px;\n}"
  },
  {
    "path": "public/assets/less/source/variables.css",
    "content": ""
  },
  {
    "path": "public/assets/less/source/variables.less",
    "content": "// EDITOR GLOBALS\n@editor--font:                  'Arial';\n@editor--font__size:            14px;\n@editor--color__success:        #4DA34D;\n@editor--color__error:          #d9534f;\n@editor--color__update:         #007aab;\n@editor--color__warning:        #f0ad4e;\n@editor--radius:                4px;\n@editor--confirm__pos:          20px;\n@editor--dropzone__height:      75px;\n@editor--dropzone__color:       @editor--color__update;\n@editor--dropzone__bg:          fadeout(black,97);\n@editor--dropzone__border:      fadeout(black,80);\n@editor--padding:               10px;\n@editor--padding__lg:           @editor--padding * 2;\n\n// COLORS\n@base:                           #23282D;\n@base--light:                   #32373C;// lighten(@base,6);\n@base--dark:                    darken(@base,5);\n\n@gray:                          #737679;\n@text-shadow:                   rgba(0,0,0,0.4);\n\n// TOOLBAR\n@toolbar--bg:                   @base;\n@toolbar--bg__dark:             @base--dark;\n@toolbar--bg__accent:           lighten(@toolbar--bg,8);\n@toolbar--border:               @base--dark;\n@toolbar--hover:                lighten(@toolbar--bg__accent,2);\n@toolbar--color:                #E2E2E2;\n    @toolbar--color__dark:      @base; // light theme var\n\n@toolbar--width:                232px;\n@toolbar--height:               39px;\n@toolbar--item__padding:        0 8px;\n@toolbar--font__size:           20px;\n@toolbar--icon__height:         20px;\n@toolbar--icon__width:          @toolbar--icon__height;\n@toolbar--pos__bottom:          20px;\n@toolbar--drop__height:         86px;\n@toolbar--drop__width:          304px;\n\n@toolbar--htmldrop__width:      340px;\n@toolbar--htmldrop__theight:    130px;\n@toolbar--htmldrop__fheight:    90px;\n/* CALC-NO-EDIT */ @toolbar--htmldrop__height: @toolbar--htmldrop__theight + @toolbar--htmldrop__fheight + 8;\n@toolbar--htmldrop__padding:    8px;\n@toolbar--htmldrop__color:      @toolbar--color;\n@toolbar--htmldrop__font:       'Courier New';\n@toolbar--htmldrop__font-size:  14px;\n\n@toolbar--htmldrop__bg:         @base;\n\n@toolbar--linkdrop__height:    70px;\n@toolbar--linkdrop__width:     300px;\n\n// EDITOR CONTROLS\n@control--bg:                   @toolbar--bg;\n@control--color:                @toolbar--color;\n@control--padding:              @toolbar--item__padding;\n@control--font__size:           @toolbar--font__size;\n@control--width:                133px;\n\n// Z INDEX\n@z-index--toolbar:              9999;\n\n// COMPONENT CONTROLS\n@component-controls--bg:         @toolbar--bg__accent;\n@component-controls--height:     26px;\n@component-controls--width:      121px;\n@component-controls--color:       white;\n@component-controls--font__size: 15px;\n@component-controls--radius:     @editor--radius - 2;\n\n// FEAT IMG CONTROLS\n@featimg-controls--width:       30px;\n@featimg-controls--height:      @component-controls--height;\n\n// MODAL\n@modal--overlay__bg:            fadeout(white,15);\n@modal--width:                  381px;\n@modal--width__med:             600px;\n@modal--width__full:            800px;\n@modal--bg:                     @base;\n@modal--bg__accent:             @base--light;\n@modal--border:                 darken(@toolbar--border,5);\n@modal--color:                  @toolbar--color;\n@modal--color-dark:            darken(@modal--color,10);\n@modal--padding:                18px;\n@modal--font__size:             14px;\n@modal--tab__height:            @input--height__lg;\n\n// RAIL\n@rail__height:                  10px;\n@rail--track__color:            @modal--bg__accent;\n@rail--handle__color:           @editor--color__update;\n@rail--handle__w:               22px;\n@rail--handle__h:               22px;\n\n// STATUS\n@status--w:                     8px;\n@status--h:                     @status--w;\n@status--publish:               @editor--color__success;\n@status--draft:                 @editor--color__warning;\n@status--pending:               @editor--color__update;\n\n// SIDEBAR\n@sidebar--width:                285px;\n@sidebar--bg:                   @toolbar--bg;\n@sidebar--bg__accent:           @toolbar--bg__accent;\n@sidebar--color:                @toolbar--color;\n@sidebar--padding:              20px;\n@sidebar--font__size:           14px;\n@sidebar--button__bg:           lighten(@toolbar--bg,18);\n@sidebar--button__border:       darken(@sidebar--button__bg,14);\n\n@sidebar--close__color:         @editor--color__update;\n@sidebar--buttonInsert__color:  #FFF;\n@sidebar--buttonInsert__bg:     @editor--color__update;\n@sidebar--buttonInsert__border: darken(@sidebar--buttonInsert__bg,5);\n\n\n// ALL POSTS\n@list--sb__width:               100px;\n@list--item__bg:                @modal--bg__accent;\n@list--item__padding:           0 15px;\n@list--item__line-height:       50px;\n@list--control__width:          115px;\n\n// SEARCH\n@search--height:                42px;\n@search--padding:               @modal--padding;\n@search--input__size:           194px;\n@search--icon__offset:          15px;\n\n// iCONS\n@icon--size__large:             50px;\n\n@list--filter-height:           42px;\n\n\n// iCONS\n@icon--size__large:             50px;\n\n// COMPONENT SETTINGS\n@input--bg:                     #f8f8f8;\n@input--color:                  #444;\n@input--border:                 darken(@sidebar--bg,5);\n@input--font__family:           'Courier New';\n@input--font__size:             15px;\n@input--height:                 30px;\n@input--height__lg:             @input--height + 6;\n\n@input--button__color:          white;\n@input--button__padding:        2px 8px;\n@input--lineheight:             1.8;\n@input--padding:               @input--button__padding;\n\n// MISFITS\n@insert--height:                70px;\n@admin-bar--height:             32px;\n\n@scrollbar--handle:             @base--light;\n@scrollbar--rail:               transparent;\n\n// TAGS\n@tag--color:                    white;\n@tag--bg:                       @modal--bg__accent;\n@tag--font__size:               12px;\n\n// TOOLLTIPS\n@tooltip--icon__color:          @editor--color__update;\n@tooltip--color:                @toolbar--color;\n@tooltip--bg:                   fadeout(@editor--color__update,5);\n@tooltip--font__size:           12px;\n\n// LOADER\n@loader--color:                 lighten(@base--light,20);\n\n// NOTICe\n@notice--width:                 500px;\n\n"
  },
  {
    "path": "public/assets/less/source/wpimg-controls.less",
    "content": "// edit wp-image -wrap .\n.lasso--wpquote, \n.lasso--wpimg__wrap {\n    position: relative;\n}\n\n.lasso--wpquote:hover{\n    .opacity(1);\n    left:0;\n}\n.lasso--wpimg__wrap:hover,\n.lasso-component:hover,.wp-block-image:hover {\n    .lasso-component--controls {\n        .opacity(1);\n        //left:0;\n    }\n}\n\n.wp-block-image:hover {\n    .lasso-component--controls {\n        position:relative;\n    }\n}\n\n.lasso--wpquote {\n    .lasso-component--controls {\n        //width:91px;\n        #lasso-component--settings__trigger {\n            position: absolute;\n            left:-10000px;\n            height:0;\n            .opacity(0);\n            display:none;\n        }\n    }\n}"
  },
  {
    "path": "public/assets/less/style.less",
    "content": "@import 'source/mixins.less';\n@import 'source/variables.less';\n@import 'source/fonts.less';\n@import 'source/animations.less';\n@import 'source/editor.less';\n@import 'source/toolbar.less';\n@import 'source/editor-controls.less';\n@import 'source/form-controls.less';\n@import 'source/post-settings.less';\n@import 'source/scrollbar.less';\n@import 'source/sidebar.less';\n@import 'source/component-controls.less';\n@import 'source/component-settings.less';\n@import 'source/component-settings--gallery.less';\n@import 'source/component-settings--map.less';\n@import 'source/featimg-controls.less';\n@import 'source/wpimg-controls.less';\n@import 'source/sweet-alert.less';\n@import 'source/util--tooltips.less';\n@import 'source/util--tags.less';\n@import 'source/tour.less';\n@import 'source/animations.less';\n@import 'source/all-posts.less';\n@import 'source/revisions.less';\n@import 'source/mobile.less';"
  },
  {
    "path": "public/includes/assets.php",
    "content": "<?php\n/**\n*\tLoad the assets used for Editus\n*\n*\t@since 1.0\n*/\nnamespace lasso_public_facing;\n\nuse lasso\\process\\gallery;\n\nclass assets {\n\n\tpublic function __construct(){\n\n\t\tadd_action('wp_enqueue_scripts', array($this,'scripts'));\n\t}\n    \n    function is_multipage()\n    {\n        global $post;\n        $pos = strpos($post->post_content, \"<!--nextpage-->\");\n        if (!$pos) return -1;\n        \n        global $wp;\n        $url =  home_url( $wp->request );\n        $index = intval(basename($url)) == 0 ? 0 : intval(basename($url))-1;\n        return $index;        \n    }\n\n\tpublic function scripts(){\n\n\t\n\t\tglobal $post;\n\t\tif ( lasso_user_can('edit_posts') \n\t\t     /* uncomment this line to disable Editus on Gutenberg posts*/\n             /* && !( function_exists( 'has_blocks' ) && has_blocks( $post->post_content)  && !is_home()) */              \n             ) {\n\t\t\t\n\t\t\t/**    Returns the time offset from UTC\n\t\t\t*/\n\t\t\tfunction get_UTC_offset() {\n\t\t\t\t$timezone_string = get_option( 'timezone_string' );\n\t\t\t\tif (empty( $timezone_string ) ) {\n\t\t\t\t\treturn get_option('gmt_offset')*3600;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t$origin_dtz = new \\DateTimeZone($timezone_string);\t\t\t\t\n\t\t\t\t$origin_dt = new \\DateTime(\"now\", $origin_dtz);\n\t\t\t\t$offset = $origin_dtz->getOffset($origin_dt);\n\t\t\t\treturn $offset;\n\t\t\t}\n\n\t\t\twp_enqueue_style('lasso-style', LASSO_URL.'/public/assets/css/lasso.css', LASSO_VERSION, true);\n\n            //don't load autocomplete if it's a stockholm theme\n\t\t\t$themename  \t= wp_get_theme()->get('Name');\n\t\t\tif ($themename !='Stockholm' ) {\n\t\t\t\twp_enqueue_script('jquery-ui-autocomplete');\n\t\t\t}\n\t\t\twp_enqueue_script('jquery-ui-draggable');\n\t\t\twp_enqueue_script('jquery-ui-sortable');\n\t\t\twp_enqueue_script('jquery-ui-slider');\n\t\t\t\n\t\t\t// media uploader\n\t\t\twp_enqueue_media();\n\n\t\t\t// url for json api\n\t\t\t$home_url = function_exists('json_get_url_prefix') ? json_get_url_prefix() : false;\n\n\t\t\t$article_object \t= lasso_editor_get_option('article_class','lasso_editor');\n\n\t\t\t$article_object \t= empty( $article_object ) && lasso_get_supported_theme_class() ? lasso_get_supported_theme_class() : $article_object;\n\n\t\t\t$featImgClass \t\t= lasso_editor_get_option('featimg_class','lasso_editor');\n\t\t\tif (empty( $featImgClass )) {\n\t\t\t\t$featImgClass = lasso_get_supported_theme_featured_image_class();\n\t\t\t}\n\t\t\t$titleClass \t\t= lasso_editor_get_option('title_class','lasso_editor');\n\t\t\tif (empty( $titleClass )) {\n\t\t\t\t$titleClass = lasso_get_supported_theme_title_class();\n\t\t\t}\n\t\t\t$toolbar_headings  \t= lasso_editor_get_option('toolbar_headings', 'lasso_editor');\n\t\t\t$toolbar_headings_h4  \t= lasso_editor_get_option('toolbar_headings_h4', 'lasso_editor');\n\t\t\t$objectsNoSave  \t= lasso_editor_get_option('dont_save', 'lasso_editor');\n\t\t\t$objectsNonEditable  \t= lasso_editor_get_option('non_editable', 'lasso_editor');\n\t\t\t$disableRESTSave = lasso_editor_get_option('save_using_rest_disabled', 'lasso_editor');\n\t\t\t$save_to_post_disabled  = lasso_editor_get_option( 'post_save_disabled', 'lasso_editor' );\n\t\t\t$edit_post_disabled  = lasso_editor_get_option( 'post_edit_disabled', 'lasso_editor' );\n\t\t\t\n\t\t\t$bold_tag = lasso_editor_get_option('bold_tag', 'lasso_editor','b');\n\t\t\t$i_tag = lasso_editor_get_option('i_tag', 'lasso_editor','i');\n            \n            $use_old_wpimg = lasso_editor_get_option('use_old_wpimg', 'lasso_editor','off');\n            \n            $use_wpimgblock = false;\n            \n            $text_select_popup = lasso_editor_get_option('text_select_popup', 'lasso_editor', false);\n            \n            $link_prefix_http = lasso_editor_get_option('link_prefix_http', 'lasso_editor', 'off');\n\t\t\t$inherit_categories = lasso_editor_get_option('inherit_categories', 'lasso_editor', 'off');\n\n\t\t\t\n\t\t\t//text alignement\n\t\t\t$show_align = lasso_editor_get_option('toolbar_show_alignment', 'lasso_editor');\n\t\t\t\n\t\t\t//make links editable under the editing mode\n\t\t\t$links_editable = lasso_editor_get_option('links_editable', 'lasso_editor');\n\t\t\t\n\t\t\t//color \n\t\t\t$show_color = lasso_editor_get_option('toolbar_show_color', 'lasso_editor');\n\t\t\t\n\t\t\t// allow change date for post\n\t\t\t$allow_change_date = lasso_editor_get_option('allow_change_date', 'lasso_editor');\n\t\t\t\n\t\t\t//disable shortcode editing\n\t\t\t$disable_shortcode_editing = lasso_editor_get_option('disable_shortcode_editing', 'lasso_editor');\n            \n            // support custom taxonomy\n\t\t\t$support_custom_taxonomy = lasso_editor_get_option('support_custom_taxonomy', 'lasso_editor');\n\t\t\t\n\t\t\tif ($show_color) {\n\t\t\t\t//color picker\n\t\t\t\twp_enqueue_style( 'wp-color-picker' );\n\t\t\t\twp_enqueue_script( 'iris', admin_url( 'js/iris.min.js' ), array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), false, 1 );\n\t\t\t}\n\t\t\t\n\t\t\t// click to insert components, not drag and drop\n\t\t\t$insert_comp_ui = lasso_editor_get_option('insert_comp_ui', 'lasso_editor');\n\t\t\t\n\t\t\t// do we support pending status\n\t\t\t$no_pending_status = lasso_editor_get_option('no_pending_status', 'lasso_editor');\n\t\t\t\n\t\t\t\n\t\t\t// custom fields\n\t\t\t\n\t\t\t$custom_fields = apply_filters( 'editus_custom_fields', null ); \n\n\n\t\t\t// post id reference\n\t\t\t$postid \t\t\t= get_the_ID();\n\t\t\t$tz_offset = get_UTC_offset();\n\t\t\t$post_date = get_the_time('U', $postid);\n\t\t\t$time = (time()+$tz_offset);\n            $delta = $time - $post_date;\n            \n\t\t\t$strings = array(\n\t\t\t\t'save' \t\t\t\t=> __('Save','lasso'),\n\t\t\t\t'selectText'\t  \t=> __('Please Select Text First.','lasso'),\n\t\t\t\t'cancel' \t\t\t=> __('Cancel','lasso'),\n\t\t\t\t'exiteditor' \t\t=> __('Exit Editor','lasso'),\n\t\t\t\t'saving' \t\t\t=> __('Saving...','lasso'),\n\t\t\t\t'saved'\t\t\t\t=> __('Saved!','lasso'),\n\t\t\t\t'adding' \t\t\t=> __('Adding...','lasso'),\n\t\t\t\t'added'\t\t\t\t=> __('Added!','lasso'),\n\t\t\t\t'loading' \t\t\t=> __('Loading...','lasso'),\n\t\t\t\t'loadMore'\t\t\t=> __('Load More','lasso'),\n\t\t\t\t'close'\t\t\t=> __('Close','lasso'),\n\t\t\t\t'noPostsFound'\t\t=> __('No more posts found','lasso'),\n\t\t\t\t'fetchFail'\t    \t=> __('Fetching failed.','lasso'),\n\t\t\t\t'galleryCreated' \t=> __('Gallery Created!','lasso'),\n\t\t\t\t'galleryUpdated' \t=> __('Gallery Updated!','lasso'),\n\t\t\t\t'justWrite'\t\t\t=> __('Just write...','lasso'),\n\t\t\t\t'chooseImage'\t\t=> __('Choose an image','lasso'),\n\t\t\t\t'updateImage'\t\t=> __('Update Image','lasso'),\n\t\t\t\t'insertImage'\t\t=> __('Insert Image','lasso'),\n\t\t\t\t'selectImage'\t\t=> __('Select Image','lasso'),\n\t\t\t\t'removeFeatImg'     => __('Remove featured image?','lasso'),\n\t\t\t\t'updateSelectedImg' => __('Update Selected Image','lasso'),\n\t\t\t\t'chooseImages'\t\t=> __('Choose images','lasso'),\n\t\t\t\t'editImage'\t\t\t=> __('Edit Image','lasso'),\n\t\t\t\t'addImages'\t\t\t=> __('Add Images','lasso'),\n\t\t\t\t'addNewGallery'\t\t=> __('Add New Gallery','lasso'),\n\t\t\t\t'selectGallery'\t\t=> __('Select Editus Gallery Image','lasso'),\n\t\t\t\t'useSelectedImages' => __('Use Selected Images','lasso'),\n\t\t\t\t'publishPost'\t\t=> __('Publish Post?','lasso'),\n\t\t\t\t'publishYes'\t\t=> __('Yes, publish it!','lasso'),\n\t\t\t\t'deletePost'\t\t=> __('Trash Post?','lasso'),\n\t\t\t\t'deleteYes'\t\t\t=> __('Yes, trash it!','lasso'),\n\t\t\t\t'warning'\t\t\t=> __('Oh snap!','laso'),\n\t\t\t\t'cancelText'\t\t=> __('O.K. got it!','lasso'),\n\t\t\t\t'missingClass'\t\t=> __('It looks like we are either missing the Article CSS class, or it is configured incorrectly. Editus will not function correctly without this CSS class.','lasso'),\n\t\t\t\t'missingConfirm'\t=> __('Update Settings', 'lasso'),\n\t\t\t\t'helperText'\t\t=> __('one more letter','lasso'),\n\t\t\t\t'editingBackup'  \t=> __('You are currently editing a backup copy of this post.'),\n\t\t\t\t\n\t\t\t\t'catsPlaceholder'     => __('add categories...'),\n\t\t\t\t'tagsPlaceholder'     => __('add tags...'),\n                'taxoPlaceholder'     => __('add taxonomy terms...'),\n\t\t\t\t'editShortcode'     => __('Edit Shortcode'),\n\t\t\t\t\n\t\t\t\t\n\t\t\t);\n\n\t\t\t$api_url = trailingslashit( home_url() ) . 'lasso-internal-api';\n\n\t\t\t$gallery_class = new gallery();\n\t\t\t$gallery_nonce_action = $gallery_class->nonce_action;\n\t\t\t$gallery_nonce = wp_create_nonce( $gallery_nonce_action );\n\t\t\t\n\t\t\t\n            if ($allow_change_date) {\n\t\t\t    $permalink = get_site_url().'/?p='.$postid;\n            } else {\n                $permalink = get_permalink($postid);\n            }\n\t\t\t\n\t\t\t// rest api\n\t\t\t$rest_nonce = '';\n\t\t\t$rest_root = site_url().'/?rest_route=/'; \n\t\t\t  \n\t\t\tif (function_exists('rest_url')) {\n\t\t\t\t//$rest_root = esc_url_raw( rest_url());\n\t\t\t\t$rest_nonce = wp_create_nonce( 'wp_rest' );\n\t\t\t\t$settings = array( 'root' => $rest_root, 'nonce' => $rest_nonce );\n\t\t\t\twp_enqueue_script( 'wp-api', '', array( 'jquery', 'underscore', 'backbone' ), LASSO_VERSION, true );\n\t\t\t\twp_localize_script( 'wp-api', 'wpApiSettings', $settings );\n\t\t\t\twp_localize_script( 'wp-api', 'WP_API_Settings', $settings );\n\t\t\t\t\n\t\t\t\tif ( class_exists( 'WP_REST_Controller' )) {\n\t\t\t\t\t// we are using REST API V2\n\t\t\t\t\t$using_restapiv2 = true;\n\t\t\t\t}\n\t\t\t}\n            \n            //excerpt\n            $post_excerpt = \"\";\n            $post_excerpt = wp_strip_all_tags($post->post_excerpt,true);\n            \n            //find if this is multi page. -1 if not\n            $multipage = self::is_multipage();\n            $post_content = \"\";\n            //pass post_content if we need to process multipage. In future we may need to pass this for other purposes\n            //if ($multipage != -1) {\n               $post_content = $post->post_content;\n            //}\n\t\t\t\n\t\t\t//get custom taxonomy\n\t\t\t$custom_taxonomies         = array_diff(get_object_taxonomies( get_post_type( $postid ), 'names' ), ['category','post_tag','post_format']);\n\t\t\t$post_taxo_arr    = array();\n\t\t\tforeach ($custom_taxonomies as $taxonomy) {\n\t\t\t\t$post_taxo_arr[$taxonomy] = lasso_get_post_objects( $postid, $taxonomy );\n\t\t\t}\n\t\t\t$existing_taxo_arr    = array();\n\t\t\tforeach ($custom_taxonomies as $taxonomy) {\n\t\t\t\t$existing_taxo_arr[$taxonomy] = lasso_get_objects( $taxonomy );\n\t\t\t}\n            \n            $new_post_text    = lasso_editor_get_option( 'new_post_text', 'lasso_editor' );        \n            $new_post_text  = !empty($new_post_text) ? $new_post_text : wp_strip_all_tags(apply_filters( 'lasso_new_object_content', __( 'Once upon a time...','lasso')));\n\t\t\t\n\t\t\twp_reset_query();\n\t\t\t$cat_new_post = ($inherit_categories =='on' && !is_home() && !is_page()) ? get_the_category() : null;\n\n\n\t\t\t// localized objects\n\t\t\t$objects = array(\n\t\t\t\t'ajaxurl' \t\t\t=> esc_url( $api_url ),\n\t\t\t\t'ajaxurl2' \t\t\t=> esc_url( admin_url( 'admin-ajax.php' )),\n\t\t\t\t'siteUrl'           => site_url(),\n\t\t\t\t'rest_root'         => $rest_root,\n\t\t\t\t'rest_nonce'        => $rest_nonce,\n\t\t\t\t'editor' \t\t\t=> 'lasso--content', // ID of editable content (without #) DONT CHANGE\n\t\t\t\t'article_object'\t=> $article_object,\n\t\t\t\t'featImgClass'\t\t=> $featImgClass,\n\t\t\t\t'titleClass'\t\t=> $titleClass,\n\t\t\t\t'strings'\t\t\t=> $strings,\n\t\t\t\t'settingsLink'\t\t=> function_exists('is_multisite') && is_multisite() ? network_admin_url( 'settings.php?page=lasso-editor' ) : admin_url( 'admin.php?page=lasso-editor-settings' ),\n\t\t\t\t'post_status'\t\t=> get_post_status( $postid ),\n\t\t\t\t'postid'\t\t\t=> $postid,\n\t\t\t\t'permalink'\t\t\t=> $permalink,\n\t\t\t\t'edit_others_pages'\t=> current_user_can('edit_others_pages') ? true : false,\n\t\t\t\t'edit_others_posts'\t=> current_user_can('edit_others_posts') ? true : false,\n\t\t\t\t'userCanEdit'\t\t=> current_user_can('edit_post', $postid ),\n\t\t\t\t'can_publish'\t\t=> is_page() ? current_user_can('publish_pages') : current_user_can('publish_posts'),\n\t\t\t\t//'can_publish_posts'\t=> current_user_can('publish_posts'),\n\t\t\t\t//'can_publish_pages'\t=> current_user_can('publish_pages'),\n\t\t\t\t'author'\t\t\t=> is_user_logged_in() ? get_current_user_ID() : false,\n\t\t\t\t'nonce'\t\t\t\t=> wp_create_nonce('lasso_editor'),\n\t\t\t\t'handle'\t\t\t=> lasso_editor_settings_toolbar(),\n\t\t\t\t'toolbar'\t\t\t=> lasso_editor_text_toolbar(),\n                'toolbarPopup'\t\t=> $text_select_popup ? lasso_editor_selected_text_toolbar(): false,\n\t\t\t\t'toolbarHeadings'   => $toolbar_headings,\n\t\t\t\t'toolbarHeadingsH4'   => $toolbar_headings_h4,\n\t\t\t\t'component_modal'\t=> lasso_editor_component_modal(),\n\t\t\t\t'component_sidebar'\t=> lasso_editor_component_sidebar(),\n\t\t\t\t'components'\t\t=> lasso_editor_components(),\n\t\t\t\t'wpImgEdit'\t\t\t=> lasso_editor_wpimg_edit(),\n\t\t\t\t'wpImgBlockEdit'\t=> lasso_editor_wpimg_block_edit(),\n\t\t\t\t'wpVideoEdit'\t\t=> lasso_editor_wpvideo_edit(),\n\t\t\t\t'featImgControls'   => lasso_editor_image_controls(),\n\t\t\t\t'featImgNonce'\t\t=> $gallery_nonce,\n\t\t\t\t'getGallImgNonce'\t=> $gallery_nonce,\n\t\t\t\t'createGallNonce'\t=> $gallery_nonce,\n\t\t\t\t'swapGallNonce'\t\t=> $gallery_nonce,\n\t\t\t\t'titleNonce'\t\t=> wp_create_nonce('lasso_update_title'),\n\t\t\t\t'wpImgNonce'\t\t=> wp_create_nonce('lasso_update_wpimg'),\n\t\t\t\t'deletePost'\t\t=> wp_create_nonce('lasso_delete_post'),\n\t\t\t\t'searchPosts'\t\t=> wp_create_nonce('lasso_search_posts'),\n\t\t\t\t'component_options' => lasso_editor_options_blob(),\n\t\t\t\t'newPostModal'\t\t=> lasso_editor_newpost_modal(),\n\t\t\t\t'allPostModal'\t\t=> lasso_editor_allpost_modal(),\n\t\t\t\t'mapFormFooter'\t\t=> lasso_map_form_footer(),\n\t\t\t\t'refreshRequired'\t=> lasso_editor_refresh_message(),\n\t\t\t\t'objectsNoSave'\t\t=> $objectsNoSave,\n\t\t\t\t'objectsNonEditable' => $objectsNonEditable,\n\t\t\t\t'supportedNoSave'\t=> lasso_supported_no_save(),\n\t\t\t\t'postCategories'    => lasso_get_objects('category'),\n\t\t\t\t'postTags'    \t\t=> lasso_get_objects('tag'),\n\t\t\t\t'postCusTaxonomies' => $post_taxo_arr,\n\t\t\t\t'extCusTaxonomies' => $existing_taxo_arr,\n\t\t\t\t'noResultsDiv'\t\t=> lasso_editor_empty_results(),\n\t\t\t\t'noRevisionsDiv'\t=> lasso_editor_empty_results('revision'),\n\t\t\t\t'mapTileProvider'   => function_exists('aesop_map_tile_provider') ? aesop_map_tile_provider( $postid ) : false,\n\t\t\t\t'mapLocations'\t\t=> get_post_meta( $postid, 'ase_map_component_locations' ),\n\t\t\t\t'mapStart'\t\t\t=> get_post_meta( $postid, 'ase_map_component_start_point', true ),\n\t\t\t\t'mapZoom'\t\t\t=> get_post_meta( $postid, 'ase_map_component_zoom', true ),\n\t\t\t\t'revisionModal' \t=> lasso_editor_revision_modal(),\n\t\t\t\t'isMobile'          => wp_is_mobile(),\n\t\t\t\t'enableAutoSave'    => lasso_editor_get_option( 'enable_autosave', 'lasso_editor' ),\n\t\t\t\t'showColor'         => $show_color,\n\t\t\t\t'showAlignment'     => $show_align,\n\t\t\t\t'showIgnoredItems'  => lasso_editor_get_option('show_ignored_items', 'lasso_editor'),\n\t\t\t\t'restapi2'          => $using_restapiv2,\n\t\t\t\t'saveusingrest'     => $using_restapiv2 && !$disableRESTSave,\n\t\t\t\t'newObjectContent'  => '<p class=\"editus-firstp\" placeholder=\"'. $new_post_text . '\"></p>',\n\t\t\t\t'disableSavePost'   => $save_to_post_disabled,\n\t\t\t\t'disableEditPost'   => $edit_post_disabled,\n\t\t\t\t'disableEditSC'     => $disable_shortcode_editing,\n\t\t\t\t'boldTag'           => $bold_tag,\n\t\t\t\t'iTag'           \t=> $i_tag, \n\t\t\t\t'customFields'      => $custom_fields,\n\t\t\t\t'clickToInsert'     => ($insert_comp_ui =='click'),\n\t\t\t\t'buttonOnEmptyP'     => ($insert_comp_ui =='mediumcom'),      // auto show a button to insert components on an empty paragraph      \n                'rtl'               => is_rtl(),\t\t\t\t\n\t\t\t\t'skipToEdit'        =>( $delta < 10 && $delta >=0 ), // if it's a new post, skip to edit mode\n\t\t\t\t'linksEditable'    => $links_editable,\n\t\t\t\t'supportPendingStatus' => !$no_pending_status,\n\t\t\t\t'tableCode' => apply_filters( 'lasso_table_html_code','<table><tr><th>Cell 1</th><th>Cell 2</th></tr><tr><td>Cell 3</td><td>Cell 4</td></tr></table><p></p>'),\n                'hasGutenberg' => (function_exists( 'has_blocks' ) && has_blocks( $post->post_content)) || self::gutenberg_active(),//,\n                'multipages'=> $multipage,\n                'post_content'=>$post_content,\n                'post_excerpt'=>$post_excerpt,\n                'supCustTaxo' => $support_custom_taxonomy == 'on',\n                'oldWPimg'=> $use_old_wpimg =='on',\n                'useWPImgBlk'=> $use_wpimgblock,\n                'prefixHTTP'=> $link_prefix_http =='on',\n\t\t\t\t'currCat'=> $cat_new_post\n\t\t\t);\n\n\n\t\t\t// wp api \n\t\t\t\n\t\t\t\n\t\t\tif (!$using_restapiv2) {\n               // enqueue REST API V1\n\t\t\t   wp_enqueue_script( 'wp-api-js', LASSO_URL.'/public/assets/js/source/util--wp-api.js', array( 'jquery', 'underscore', 'backbone' ), LASSO_VERSION, true );\n\t\t\t   $settings = array( 'root' => home_url( $home_url ), 'nonce' => wp_create_nonce( 'wp_json' ) );\n\t\t\t   wp_localize_script( 'wp-api-js', 'WP_API_Settings', $settings );\n\t\t\t}\n\t\t\t\n\t\t\tif ($allow_change_date) {\n\t\t\t\twp_enqueue_script('jquery-ui-datepicker');\n\t\t\t\twp_register_style('jquery-ui', '//ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css');\n\t\t\t\twp_enqueue_style('jquery-ui');\n\t\t\t}\n\n\t\t\t$postfix = ( defined( 'SCRIPT_DEBUG' ) && true === SCRIPT_DEBUG ) ? '' : '.min';\n\t\t\tif ($show_color) {\n\t\t\t\twp_enqueue_script('lasso', LASSO_URL. \"/public/assets/js/lasso{$postfix}.js\", array('jquery', 'wp-api','iris'), LASSO_VERSION, true);\n\t\t\t} else {\n\t\t\t    wp_enqueue_script('lasso', LASSO_URL. \"/public/assets/js/lasso{$postfix}.js\", array('jquery', 'wp-api'), LASSO_VERSION, true);\n\t\t\t}\n\t\t\twp_localize_script('lasso', 'lasso_editor', apply_filters('lasso_localized_objects', $objects ) );\n\n\n\t\t}\n\n\t}\n    \n    function gutenberg_active() {\n        \n        // Gutenberg plugin is installed and activated.\n        $gutenberg = ! ( false === has_filter( 'replace_editor', 'gutenberg_init' ) );\n\n        // Block editor since 5.0.\n        $block_editor = version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' );\n\n        if ( ! $gutenberg && ! $block_editor ) {\n            return false;\n        }\n\n        if ( self::is_classic_editor_plugin_active() ) {\n            $editor_option       = get_option( 'classic-editor-replace' );\n            $block_editor_active = array( 'no-replace', 'block' );\n\n            return in_array( $editor_option, $block_editor_active, true );\n        }\n\n        return true;\n    }\n\n    /**\n     * Check if Classic Editor plugin is active.\n     *\n     * @return bool\n     */\n    function is_classic_editor_plugin_active() {\n        if ( ! function_exists( 'is_plugin_active' ) ) {\n            include_once ABSPATH . 'wp-admin/includes/plugin.php';\n        }\n\n        if ( is_plugin_active( 'classic-editor/classic-editor.php' ) ) {\n            return true;\n        }\n\n        return false;\n    }\n\n}\n\n"
  },
  {
    "path": "public/includes/components.php",
    "content": "<?php\n/**\n * The functions in this file register the components that will be shown in the component drop-up menu\n * and are filterable and pluggable\n *\n */\n\n/**\n * Build an array of components that will be shown in the\n * component drop-up menu on click\n *\n * @return array of components\n * @since 1.0\n */\nfunction lasso_editor_components() {\n\n\t$array = array(\n\t\t'quote' => array(\n\t\t\t'name'    => __('Quote','lasso'),\n\t\t\t'content' => lasso_quote_component(),\n\t\t),\n\t\t'image' => array(\n\t\t\t'name'    => __('Image','lasso'),\n\t\t\t'content' => lasso_image_component(),\n\t\t),\n\t\t'parallax' => array(\n\t\t\t'name'    => __('Parallax','lasso'),\n\t\t\t'content' => lasso_parallax_component(),\n\t\t),\n\t\t'audio' => array(\n\t\t\t'name'    => __('Audio','lasso'),\n\t\t\t'content' => lasso_audio_component(),\n\t\t),\n\t\t'content' => array(\n\t\t\t'name'    => __('Content','lasso'),\n\t\t\t'content' => lasso_content_component(),\n\t\t),\n\t\t'character' => array(\n\t\t\t'name'    => __('Character','lasso'),\n\t\t\t'content' => lasso_character_component(),\n\t\t),\n\t\t'collection' => array(\n\t\t\t'name'    => __('Collection','lasso'),\n\t\t\t'content' => lasso_collections_component(),\n\t\t),\n\t\t'document' => array(\n\t\t\t'name'    => __('Document','lasso'),\n\t\t\t'content' => lasso_document_component(),\n\t\t),\n\t\t'gallery' => array(\n\t\t\t'name'    => __('Gallery','lasso'),\n\t\t\t'content' => lasso_gallery_component(),\n\t\t),\n\t\t'chapter' => array(\n\t\t\t'name'    => __('Chapter','lasso'),\n\t\t\t'content' => lasso_heading_component(),\n\t\t),\n\t\t'map' => array(\n\t\t\t'name'    => __('Map','lasso'),\n\t\t\t'content' => lasso_map_component(),\n\t\t),\n\t\t'timeline_stop' => array(\n\t\t\t'name'    => __('Timeline','lasso'),\n\t\t\t'content' => lasso_timeline_component(),\n\t\t),\n\t\t'video' => array(\n\t\t\t'name'    => __('Video','lasso'),\n\t\t\t'content' => lasso_video_component(),\n\t\t),\n\t\t'wpimg' => array(\n\t\t\t'name'    => __('WordPress Image','lasso'),\n\t\t\t'content' => lasso_wp_image(),\n\t\t),\n\t\t'wpimg-block' => array(\n\t\t\t'name'    => __('WordPress Image Block','lasso'),\n\t\t\t'content' => lasso_wp_image_block(),\n\t\t),\n\t\t'wpquote' => array(\n\t\t\t'name'    => __('WordPress Quote','lasso'),\n\t\t\t'content' => lasso_wp_quote(),\n\t\t),\n\t\t'gallery_pop' => array(\n\t\t\t'name'    => __('Gallery Pop','lasso'),\n\t\t\t'content' => lasso_gallery_pop_component(),\n\t\t),\n\t\t'events' => array(\n\t\t\t'name'    => __('Events','lasso'),\n\t\t\t'content' => lasso_event_component(),\n\t\t),\n\t\t'wpvideo' => array(\n\t\t\t'name'    => __('WordPress Image','lasso'),\n\t\t\t'content' => lasso_wp_video(),\n\t\t),\n\t);\n\n\treturn apply_filters( 'lasso_components', $array );\n}\n\n/**\n * Here each of the components content is being registered and retrieved above\n *\n * Notes:  - these functions are pluggable\n *     - custom modules must have data-component-type=\"whatever\"\n *   - custom modules must have all options as data-attributes if utilizing settings panel\n *\n * 1.  Quote\n * 2.  Image\n * 3. Parallax\n * 4. Audio\n * 5. Content\n * 6. Character\n * 7. Collections\n * 8. Document\n * 9. Gallery\n * 10. Heading\n * 11. Map\n * 12. Timeline\n * 13. Video\n */\n\n// 1\nif ( !function_exists( 'lasso_quote_component' ) ):\n\tfunction lasso_quote_component() {\n\n\t\treturn do_shortcode( '[aesop_quote quote=\"The Universe is made of stories, not of atoms.\"]' );\n\t}\nendif;\n\n// 2\nif ( !function_exists( 'lasso_image_component' ) ):\n\tfunction lasso_image_component() {\n\n\t\treturn do_shortcode( '[aesop_image img=\"'.LASSO_URL.'/public/assets/img/empty-img.png\" align=\"center\" imgwidth=\"100%\"]' );\n\t}\nendif;\n\n// 3\nif ( !function_exists( 'lasso_parallax_component' ) ):\n\tfunction lasso_parallax_component() {\n\n\t\treturn do_shortcode( '[aesop_parallax img=\"'.LASSO_URL.'/public/assets/img/empty-img.png\"]' );\n\t}\nendif;\n\n// 4\nif ( !function_exists( 'lasso_audio_component' ) ):\n\tfunction lasso_audio_component() {\n\n\t\treturn do_shortcode( '[aesop_audio src=\"http://users.skynet.be/fa046054/home/P22/track06.mp3\"]' );\n\n\t}\nendif;\n\n// 5\nif ( !function_exists( 'lasso_content_component' ) ):\n\tfunction lasso_content_component() {\n\n\t\treturn do_shortcode( '[aesop_content]Start typing here...[/aesop_content]' );\n\t}\nendif;\n\n// 6\nif ( !function_exists( 'lasso_character_component' ) ):\n\tfunction lasso_character_component() {\n\n\t\treturn do_shortcode( '[aesop_character img=\"'.LASSO_URL.'/public/assets/img/empty-img.png\" name=\"Joes Apartment\" width=\"150px\"]' );\n\n\t}\nendif;\n\n// 7\nif ( !function_exists( 'lasso_collections_component' ) ):\n\tfunction lasso_collections_component() {\n\n\t\treturn do_shortcode( '[aesop_collection]' );\n\t}\nendif;\n\n// 8\nif ( !function_exists( 'lasso_document_component' ) ):\n\tfunction lasso_document_component() {\n\n\t\treturn do_shortcode( '[aesop_document src=\"'.LASSO_URL.'/public/assets/img/empty-img.png\" ]' );\n\n\t}\nendif;\n\n// 9\nif ( !function_exists( 'lasso_gallery_component' ) ):\n\tfunction lasso_gallery_component() {\n\n\t\treturn do_shortcode( '[aesop_gallery]' );\n\n\t}\nendif;\n\n// 10\nif ( !function_exists( 'lasso_heading_component' ) ):\n\tfunction lasso_heading_component() {\n\n\t\treturn do_shortcode( '[aesop_chapter title=\"Chapter One\" img=\"'.LASSO_URL.'/public/assets/img/empty-img.png\" full=\"on\"]' );\n\t}\nendif;\n\n// 11\nif ( !function_exists( 'lasso_map_component' ) ):\n\tfunction lasso_map_component() {\n\n\t\treturn '<form id=\"lasso--map-form\" class=\"aesop-component aesop-map-component lasso--map-drag-holder\" enctype=\"multipart/form-data\">\n\t\t\t\t'.lasso_map_form_footer().'\n\t\t\t\t'.do_shortcode( '[aesop_map sticky=\"off\"]' ).'\n\t\t\t</form>';\n\n\t}\nendif;\n\n// 12\nif ( !function_exists( 'lasso_timeline_component' ) ):\n\tfunction lasso_timeline_component() {\n\n\t\treturn do_shortcode( '[aesop_timeline_stop num=\"2014\" title=\"Title\"]' );\n\n\t}\nendif;\n\n// 13\nif ( !function_exists( 'lasso_video_component' ) ):\n\tfunction lasso_video_component() {\n\n\t\treturn do_shortcode( '[aesop_video src=\"vimeo\" id=\"59940289\" width=\"100%\" align=\"center\"]' );\n\n\t}\nendif;\n\n// 14 - since 0.9.1\nif ( !function_exists('lasso_wp_image') ):\n\n\tfunction lasso_wp_image(){\n        $use_old_wpimg = lasso_editor_get_option('use_old_wpimg', 'lasso_editor','off');\n        $use_wp_block_image = lasso_editor_get_option('use_wp_block_image', 'lasso_editor','off');\n        if ($use_wp_block_image == 'on') {\n        \treturn '<figure class=\"wp-block-image size-large\" data-component-type=\"wpimg-block\"><img  src=\"'.LASSO_URL.'/public/assets/img/empty-img.png\"></figure><p><br></p>';\n        }\n        else if ($use_old_wpimg != 'on') {\n        \treturn '<figure data-component-type=\"wpimg\" class=\"lasso--wpimg__wrap lasso-component\"><img  src=\"'.LASSO_URL.'/public/assets/img/empty-img.png\"></figure><p><br></p>';\n        } else {\n            return '<figure data-component-type=\"wpimg\" data-linkoption=\"img\" class=\"lasso--wpimg__wrap lasso-component\"><img  src=\"'.LASSO_URL.'/public/assets/img/empty-img.png\"></figure><p><br></p>';\n        }\n\t}\n\nendif;\n\n// 15 - since 0.9.2\nif ( !function_exists('lasso_wp_quote') ):\n\n\tfunction lasso_wp_quote(){\n\t\treturn '<blockquote data-component-type=\"wpquote\" class=\"lasso--wpquote lasso-component\"><p>The universe is made of stories.</p></blockquote><p><br></p>';\n\t}\n\nendif;\n\n// 16 gallery pop added but not fully supported as of 0.9.9.11 \n\nif ( !function_exists( 'lasso_gallery_pop_component' ) ):\n\tfunction lasso_gallery_pop_component() {\n\t\treturn do_shortcode( '[aesop_gallery_pop]' );\n\t}\nendif;\n\n// 17 - work in progress\n\nif ( !function_exists( 'lasso_event_component' ) ):\n\tfunction lasso_event_component() {\n\t\t$id = editus_get_one_id('aesop_events');\n\t\treturn '<div data-component-type=\"events\" class=\"aesop-component lasso-component\"><p>Aesop Event: After setting the event, save and reload the page.</p></div>';\n\t}\nendif;\n\n// 18 - work in progress\nif ( !function_exists('lasso_wp_video') ):\n\n\tfunction lasso_wp_video(){\n\t\treturn '<div data-component-type=\"wpvideo\" class=\"lasso--wpvideo__wrap lasso-component\"><video class=\"wp-video-0\"></video>';\n\t}\n\nendif;\n\nif ( !function_exists('lasso_wp_image_block') ):\n\tfunction lasso_wp_image_block(){\n        return '<figure class=\"wp-block-image size-large\" data-component-type=\"wpimg-block\"><img  src=\"'.LASSO_URL.'/public/assets/img/empty-img.png\"></figure><p><br></p>';\n\t}\n\nendif;\n\n// helper function to retrieve one id for default option\nfunction editus_get_one_id($type)\n{\n\t$args = array( 'posts_per_page' => 1, 'post_type' => $type );\n\t$posts = get_posts( $args );\n\tif ( $posts ) {\n\t\tforeach ( $posts as $post ) {\n\t\t\treturn $post->ID;\n\t\t}\n\t}\n\treturn -1;\n}\n\n\n"
  },
  {
    "path": "public/includes/editor-modules--gallery.php",
    "content": "<?php\n\n/**\n * Build the gallery creation and management area shown in panel\n *\n * @since 1.0\n */\nfunction lasso_gallery_editor_module() {\n\n\t$galleries = lasso_editor_galleries_exist();\n\n\tob_start();\n\n\tif ( $galleries ) { ?>\n\t\n\t\t<?php if ( lasso_user_can( 'publish_posts' ) ): ?>\n\t\t\t<div class=\"ase-gallery-opts ase-gallery-opts--create-gallery\" style=\"display:inline !important; postion:relative !important;left:12px !important\">\n\t\t\t\t<div class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t\t<a href=\"#\" class=\"editor-btn-secondary\" id=\"lasso--gallery__create\"><?php _e( 'Create gallery', 'lasso' );?></a>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t<?php endif; ?>\n\n\t\t<div class=\"ase-gallery-opts ase-gallery-opts--edit-gallery\" >\n\t\t\t<div class=\"ase-gallery-opts--single lasso-option\">\n\n\t\t\t\t<label><?php _e( 'Manage Images', 'lasso' );?>\n\t\t\t\t\t<a href=\"#\" id=\"ase-gallery-add-image\" class=\"lasso-editor-tiny-btn\" title=\"<?php esc_attr_e( 'Add Images', 'lasso' );?>\"><i class=\"lasso-icon-pencil\"></i></a>\n\n\t\t\t\t</label>\n\t\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Rearrange or edit the images in this gallery.', 'lasso' );?></small>\n\n\t\t\t\t<div id=\"lasso--gallery__images\"><span class=\"lasso-icon-spinner6\"></span></div>\n\n\t\t\t</div>\n\n\t\t</div>\n\n\t<?php }\n\n\tif ( lasso_user_can( 'publish_posts' ) ): ?>\n\n\t\t<div class=\"ase-gallery-opts ase-gallery-opts--create-gallery2\" style=\"display:none;\">\n\n\t\t\t<div class=\"ase-gallery-opts--single lasso-option\">\n\n\t\t\t\t<label><?php _e( 'Create a Gallery', 'lasso' );?></label>\n\t\t\t\t<small class=\"lasso-option-desc\">Gallery Name:</small>\n                <input type=\"text\" id=\"lasso--gallery__galleryname\" value=\"New Gallery\"><br>\n\t\t\t\t\n\t\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Select images to create a gallery.', 'lasso' );?></small>\n\t\t\t\t<a href=\"#\" class=\"editor-btn-secondary\" id=\"lasso--gallery__selectImages\"><?php _e( 'Select Images', 'lasso' );?></a>\n\n\t\t\t\t<div id=\"ase-gallery-images\"></div>\n\n\t\t\t\t<a style=\"display:none;\" class=\"editor-btn-secondary\" data-post-title=\"<?php echo esc_attr( strtolower( the_title_attribute() ) );?>\" id=\"lasso--gallery__save\" href=\"#\"><?php _e( 'Create Gallery', 'lasso' );?></a>\n\n\t\t\t</div>\n\n\t\t</div>\n\n\t<?php endif; ?>\n\n\t<!-- Gallery Layout/Type Chooser -->\n\t<div class=\"ase-gallery-opts ase-gallery-opts--type\" >\n\t\t<div data-option=\"gallery-type\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<label><?php _e( 'Gallery Type', 'lasso' );?></label>\n\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Select the type of gallery.', 'lasso' );?></small>\n\t\t\t<fieldset>\n\t      \t\t<label for=\"lasso_gallery_type\" class=\"ase-gallery-layout-label\"><input class=\"lasso-generator-attr ase-gallery-type-radio\" type=\"radio\" name=\"lasso_gallery_type\" value=\"grid\"><?php _e( 'Grid', 'lasso' );?></label>\n\t        \t<label for=\"lasso_gallery_type\" class=\"ase-gallery-layout-label\"><input class=\"lasso-generator-attr ase-gallery-type-radio\" type=\"radio\" name=\"lasso_gallery_type\" value=\"thumbnail\"><?php _e( 'Thumbnail', 'lasso' );?></label>\n\t\t\t\t<label for=\"lasso_gallery_type\" class=\"ase-gallery-layout-label\"><input class=\"lasso-generator-attr ase-gallery-type-radio\" type=\"radio\" name=\"lasso_gallery_type\" value=\"sequence\">Sequence</label>\n\t\t\t\t<label for=\"lasso_gallery_type\" class=\"ase-gallery-layout-label\"><input class=\"lasso-generator-attr ase-gallery-type-radio\" type=\"radio\" name=\"lasso_gallery_type\" value=\"photoset\"><?php _e( 'Photoset', 'lasso' );?></label>\n\t\t\t\t<label for=\"lasso_gallery_type\" class=\"ase-gallery-layout-label\"><input class=\"lasso-generator-attr ase-gallery-type-radio\" type=\"radio\" name=\"lasso_gallery_type\" value=\"stacked\"><?php _e( 'Parallax', 'lasso' );?></label>\n\t\t\t\t<label for=\"lasso_gallery_type\" class=\"ase-gallery-layout-label\"><input class=\"lasso-generator-attr ase-gallery-type-radio\" type=\"radio\" name=\"lasso_gallery_type\" value=\"hero\">Hero</label>\n\t\t\t</fieldset>\n\t\t</div>\n\t</div>\n\n\t<!-- Conditionally Loaded Gallery Option - Grid Options -->\n\t<div class=\"ase-gallery-opts ase-gallery-opts--grid\" style=\"display:none;\">\n\n\t\t<div data-option=\"itemwidth\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<label for=\"lasso_grid_gallery_width\"><?php _e( 'Grid Item Width', 'lasso' );?></label>\n\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Adjust the width of the individual grid items, only if using Grid gallery style. Default is 400.', 'lasso' );?></small>\n\t\t\t<input type=\"text_small\" class=\"lasso-generator-attr\" name=\"lasso_grid_gallery_width\" value=\"\">\n\t\t</div>\n\n\t</div>\n\n\t<!-- Conditionally Loaded Gallery Option - Thumb Options -->\n\t<div class=\"ase-gallery-opts ase-gallery-opts--thumb\" style=\"display:none;\">\n\n\t\t<div data-option=\"transition\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<label for=\"lasso_thumb_gallery_transition\"><?php _e( 'Gallery Transition', 'lasso' );?></label>\n\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Adjust the transition effect for the Thumbnail gallery. Default is slide.', 'lasso' );?></small>\n\t\t   \t<select name=\"lasso_thumb_gallery_transition\" class=\"lasso-generator-attr\">\n\t\t      <option value=\"crossfade\"><?php _e( 'Fade', 'lasso' );?></option>\n\t\t      <option value=\"slide\"><?php _e( 'Slide', 'lasso' );?></option>\n\t\t      <option value=\"dissolve\"><?php _e( 'Dissolve', 'lasso' );?></option>\n\t\t    </select>\n\t\t</div>\n\n\t\t<div data-option=\"speed\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<label for=\"lasso_thumb_gallery_transition_speed\"><?php _e( 'Gallery Transition Speed', 'lasso' );?></label>\n\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Activate slideshow by setting a speed for the transition.5000 = 5 seconds.', 'lasso' );?></small>\n\t\t\t<input type=\"text\" class=\"lasso-generator-attr\" name=\"lasso_thumb_gallery_transition_speed\" value=\"\">\n\t\t</div>\n\n\t\t<div data-option=\"hide-thumbs\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<input class=\"lasso-generator-attr\" type=\"checkbox\" name=\"lasso_thumb_gallery_hide_thumbs\">\n\t\t\t<label for=\"lasso_thumb_gallery_hide_thumbs\"><?php _e( 'Hide Gallery Thumbnails', 'lasso' );?></label>\n\t\t</div>\n\n\t</div>\n\n\t<!-- Conditionally Loaded Gallery Option - Photoset Options -->\n\t<div class=\"ase-gallery-opts ase-gallery-opts--photoset\" style=\"display:none;\">\n\n\t\t<div data-option=\"pslayout\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<label for=\"lasso-photoset-gallery-layout\"><?php _e( 'Gallery Layout', 'lasso' );?></label>\n\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Let\\'s say you have 4 images in this gallery. If you enter 121 you will have one image on the top row, two images on the second row, and one image on the third row.', 'lasso' );?></small>\n\t\t\t<input type=\"text\" class=\"lasso-generator-attr\" name=\"lasso_photoset_gallery_layout\" value=\"\">\n\t\t</div>\n\n\t\t<!--div data-option=\"pslightbox\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<input type=\"checkbox\" class=\"lasso-generator-attr\" name=\"lasso_photoset_gallery_lightbox\">\n\t\t\t<label for=\"lasso_photoset_gallery_lightbox\"><!--?php _e( 'Enable Lightbox', 'lasso' );?--><!--/label-->\n\t\t<!--/div-->\n\n\t</div>\n\t\n\t<!-- Conditionally Loaded Gallery Option - Hero Options -->\n\t<div class=\"ase-gallery-opts ase-gallery-opts--hero\" style=\"display:none;\">\n\n\t\t<div data-option=\"height\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<label for=\"lasso_gallery_height\"><?php _e( 'Main Gallery Height', 'lasso' );?></label>\n\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Adjust the overall height of the gallery. Acceptable values include 500px or 50% etc.', 'lasso' );?></small>\n\t\t\t<input type=\"text_small\" class=\"lasso-generator-attr\" name=\"lasso_gallery_height\" value=\"\">\n\t\t</div>\n\n\t</div>\n\n\t<!-- Global Gallery Options -->\n\t<div class=\"ase-gallery-opts ase-gallery-opts--global\">\n\n\t\t<div data-option=\"width\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<label for=\"lasso_gallery_width\"><?php _e( 'Main Gallery Width', 'lasso' );?></label>\n\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Adjust the overall width of the gallery. Acceptable values include 500px or 50% etc.', 'lasso' );?></small>\n\t\t\t<input type=\"text_small\" class=\"lasso-generator-attr\" name=\"lasso_gallery_width\" value=\"\">\n\t\t</div>\n\t\t<div data-option=\"caption\" class=\"ase-gallery-opts--single lasso-option\">\n\t\t\t<label for=\"lasso_gallery_caption\"><?php _e( 'Gallery Caption', 'lasso' );?></label>\n\t\t\t<small class=\"lasso-option-desc\"><?php _e( 'Add an optional caption for the gallery.', 'lasso' );?></small>\n\t\t\t<textarea name=\"lasso_gallery_caption\" class=\"lasso-generator-attr\"></textarea>\n\t\t</div>\n\n\t</div>\n\n\n\t<input type=\"hidden\" id=\"ase_gallery_ids\" name=\"ase_gallery_ids\" value=\"\">\n\t<input type=\"hidden\" id=\"ase_gallery_type\" name=\"ase_gallery_type\" value=\"\">\n\t<?php\n\n\treturn ob_get_clean();\n}"
  },
  {
    "path": "public/includes/editor-modules.php",
    "content": "<?php\n\n/**\n * These functions are then localized and then appended with JS in enter-editor.js\n *\n * @since 1.0\n */\n\n/**\n * Add the editor controls to any singular post object\n *\n * @since 1.0\n */\nadd_action( 'wp_footer', 'lasso_editor_controls' );\nfunction lasso_editor_controls() {\n\n\tglobal $post;\n\n\tif ( lasso_user_can('edit_posts') ) {\n\n\t\t$status = get_post_status( get_the_ID() );\n\t\t$use_old_ui   = lasso_editor_get_option( 'use_old_ui', 'lasso_editor' );\n\t\t$button_color1 = lasso_editor_get_option('button-color1', 'lasso_editor','#0000ff');\n\t\t$button_color2 = lasso_editor_get_option('button-color2', 'lasso_editor','#000000');\n\t\t$dialog_color = lasso_editor_get_option('dialog-color', 'lasso_editor','#000055');\n\t\t$text_color = lasso_editor_get_option('text-color', 'lasso_editor','#ffffff');\n\t\t$hover_color1 = lasso_editor_adjustBrightness($button_color1, 50);\n\t\t$hover_color2 = lasso_editor_adjustBrightness($button_color2, 50);\n\n\t\t// let users add custom css classes\n\t\t$custom_classes = apply_filters( 'lasso_control_classes', '' );\n\n\t\t$post_access_class   = '';\n\t\t$post_new_disabled   = lasso_editor_get_option( 'post_adding_disabled', 'lasso_editor' );\n\t\t$post_settings_disabled = lasso_editor_get_option( 'post_settings_disabled', 'lasso_editor' );\n\t\t$shortcodify_disabled = lasso_editor_get_option( 'shortcodify_disabled', 'lasso_editor' );\n\n\n\t\t// CSS class if adding new post objects is disabled\n\t\tif ( 'on' == $post_new_disabled ) { $post_access_class = 'lasso--post-new-disabled'; }\n\n\t\t// CSS class if adjust settings is disabled\n\t\tif ( 'on' == $post_settings_disabled ) { $post_access_class = 'lasso--post-settings-disabled'; }\n\n\t\t// CSS class if adding new post objects AND settings are disabled\n\t\tif ( 'on' == $post_new_disabled && 'on' == $post_settings_disabled ) { $post_access_class = 'lasso--post-all-disabled'; }\n\n\t\t// CSS class if shortcodify or (Aesop Shortcode Conversion) is disabled\n\t\t$sc_saving_class = 'on' == $shortcodify_disabled ? 'shortcodify-disabled' : 'shortcodify-enabled';\n\n\t\t// user is capable\n\t\t$is_capable = is_singular() && lasso_user_can('edit_post');\n\t\t$is_mobile = wp_is_mobile();\n\t\t\n\t\t$mobile_style = $is_mobile ? 'style=\"bottom:0px;\"' : null;\n\t\t$can_publish = lasso_user_can('publish_posts') || lasso_user_can('publish_pages');\n\t\t?>\n\t\t<style>\n\t\t#lasso-html--table:before {\n\t\t\tcontent: \"<?php esc_attr_e( 'Table', 'lasso' );?>\";\n\t\t}\n\t\t\n\t\t\n\t\t<?php\n\n\t\tif (!$use_old_ui) {\n\t\t?>\n\t\t\n\t\t.lasso-editor-controls--wrap, #lasso--post-settings2,#lasso--save,#lasso--post-delete,#lasso--exit,#lasso--publish {\n\t\t\tbackground-image: -webkit-linear-gradient(top,<?php echo $button_color1;?> 0,<?php echo $button_color2;?> 100%);\n\t\t\tbackground-image: -o-linear-gradient(top,<?php echo $button_color1;?> 0,<?php echo $button_color2;?> 100%);\n\t\t\tbackground-image: linear-gradient(to bottom,<?php echo $button_color1;?> 0,<?php echo $button_color2;?> 100%);\n\t\t\tcolor: <?php echo $text_color;?>;\n\t\t}\n\t\t\n\t\t.lasso--controls__right a:before, #lasso-toolbar--html__footer_desc, ul.lasso-editor-controls li:before,#lasso-side-comp-button.toolbar--side li:before\n        {\n\t\t\tcolor: <?php echo $text_color;?>;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\tul.lasso-editor-controls li:hover, #lasso--exit:hover,#lasso--post-settings2:hover,#lasso--post-delete:hover,#lasso--publish:hover,#lasso--save:hover {\n\t\t\tbackground-image: -webkit-linear-gradient(top,<?php echo $hover_color1;?> 0,<?php echo $hover_color2;?> 100%);\n\t\t\tbackground-image: -o-linear-gradient(top,<?php echo $hover_color1;?> 0,<?php echo $hover_color2;?> 100%);\n\t\t\tbackground-image: linear-gradient(to bottom,<?php echo $hover_color1;?> 0,<?php echo $hover_color2;?> 100%);\n\t\t}\n\t\t\n\t\t.lasso--modal__inner,.sweet-alert,#lasso-toolbar--components.toolbar--drop-up ul,#lasso-toolbar--components__list,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap,\n\t\t#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap\t\t{\n\t\t\tbackground: <?php echo $dialog_color;?>;\n\t\t\tcolor: <?php echo $text_color;?>;\n\t\t}\n\t\t.sweet-alert p,.lasso--modal__inner label,.lasso--toolbar__inner label {\n\t\t\tcolor: <?php echo $text_color;?> !important;\n\t\t}\n\t\t\n\t\t<?php if (!$is_mobile) { ?>\n\t\t\t.lasso-editor-controls--wrap {\n\t\t\t\tdisplay:table;\n\t\t\t}\n\t\t\tul.lasso-editor-controls {\n\t\t\t\theight:42px;\n\t\t\t\tfont-size: 22px;\n\t\t\t}\n\t\t\t.lasso-editor-controls--wrap {\n\t\t\t\theight:42px;\n\t\t\t}\n\t\t\t#lasso--post-all:before {\n\t\t\t\tfont-size: 22px;\n\t\t\t}\n\n\t\t\tul.lasso-editor-controls li {\n\t\t\t\theight: 42px;\n\t\t\t}\n\t\t<?php\n            } \n\t\t} else { \n\t\t?> \n\n            #lasso-toolbar--components__list {\n                background:black !important;\n            }\n            \n        <?php\n        }\n        ?>\n        </style>\n\t\t<div id=\"lasso--controls\" class=\"lasso-post-status--<?php echo sanitize_html_class( $status );?> <?php echo sanitize_html_class( $custom_classes );?>\" data-post-id=\"<?php echo get_the_ID();?>\" >\n\n\t\t\t<ul class=\"lasso--controls__center lasso-editor-controls lasso-editor-controls--wrap <?php echo $post_access_class;?> \"  <?php echo $mobile_style ?> >\n\n\t\t\t\t<?php do_action( 'lasso_editor_controls_before' );\n\n\t\t\t\tif ( $is_capable ) { ?>\n\n\t\t\t\t\t<li id=\"lasso--edit\" title=\"<?php esc_attr_e( 'Edit Post', 'lasso' );?>\"><a href=\"#\" class=\"lasso--button__primary\"></a></li>\n\n\t\t\t\t\t<?php if ( 'off' == $post_settings_disabled || empty( $post_settings_disabled ) ) { ?>\n\t\t\t\t\t\t<li id=\"lasso--post-settings\" title=\"<?php esc_attr_e( 'Post Settings', 'lasso' );?>\"><a href=\"#\" class=\"lasso--button__primary\"></a></li>\n\t\t\t\t\t<?php }\n\n\t\t\t\t} ?>\n\n\t\t\t\t<li id=\"lasso--post-all\" title=\"<?php esc_attr_e( 'All Posts', 'lasso' );?>\"><a href=\"#\" class=\"lasso--button__primary\"></a></li>\n\n\t\t\t\t<?php if ( $is_capable && wp_revisions_enabled( $post ) ) { ?>\n\t\t\t\t\t<li id=\"lasso--post-revisions\" title=\"<?php esc_attr_e( 'Revisions', 'lasso' );?>\"><a href=\"#\" class=\"lasso--button__primary\"></a></li>\n\t\t\t\t<?php } ?>\n\n\t\t\t\t<?php if ( ( 'off' == $post_new_disabled || empty( $post_new_disabled ) && lasso_user_can('edit_posts') ) ) { ?>\n\t\t\t\t\t<li id=\"lasso--post-new\" title=\"<?php esc_attr_e( 'Add Post', 'lasso' );?>\"><a href=\"#\" class=\"lasso--button__primary\"></a></li>\n\t\t\t\t<?php } ?>\n\n\t\t\t\t<?php do_action( 'lasso_editor_controls_after' );?>\n\n\t\t\t</ul>\n\n\t\t\t<?php if ( is_singular() && !$is_mobile ) { ?>\n\n\t\t\t\t<div class=\"lasso--controls__right\" data-posttype=\"<?php echo get_post_type( get_the_ID() );?>\" data-status=\"<?php echo $status;?>\">\n\t\t\t\t\n\t\t\t\t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Delete Post', 'lasso' );?>\" id=\"lasso--post-delete\" class=\"lasso-save-post lasso--button <?php echo $sc_saving_class;?>\"></a>\n\t\t\t\t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Post Settings', 'lasso' );?>\" id=\"lasso--post-settings2\" class=\"lasso-save-post lasso--button <?php echo $sc_saving_class;?>\"></a>\n\n\n\t\t\t\t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Save Post', 'lasso' );?>\" id=\"lasso--save\" class=\"lasso-save-post lasso--button <?php echo $sc_saving_class;?>\"></a>\n\n\t\t\t\t\t<?php if ( ('draft' == $status ) || ('pending' == $status && $can_publish) ) { ?>\n\t\t\t\t\t\t<a href=\"#\" title=\"<?php $can_publish ? esc_attr_e( 'Publish Post', 'lasso' ) : esc_attr_e( 'Submit For Review', 'lasso' );?>\" id=\"lasso--publish\" class=\"lasso-publish-post lasso--button <?php echo $sc_saving_class;?>\"></a>\n\t\t\t\t\t<?php } ?>\n\t\t\t\t\t\n\n\t\t\t\t</div>\n\n\t\t\t<?php } ?>\n\n\t\t</div>\n\t\t\n\t\t\n\t\t<?php do_action( 'lasso_editor_controls_after_outside' );?>\n\n\t<?php }\n}\n\n/**\n * Draw the side panel that houses the component settings\n * This is opened when the settings icon is clicked on a single component\n * JS detects the type and will fill in the necessary options for the shortcode based on  lasso_editor_options_blob() at the end of this file\n *\n * @since 1.0\n */\nfunction lasso_editor_component_sidebar() {\n\n\tob_start();\n\n\n\t// let users add custom css classes\n\t$custom_classes = apply_filters( 'lasso_sidebar_classes', '' );\n\t?>\n\t<div id=\"lasso--sidebar\" class=\"<?php echo sanitize_html_class( $custom_classes );?>\" >\n\t\t<div class=\"lasso--sidebar__inner\">\n\t\t\t<div id=\"aesop-generator-settings\"><div id=\"lasso--component__settings\"></div></div>\n\t\t</div>\n\t</div>\n\n\t<?php return ob_get_clean();\n}\n\n\nfunction lasso_editor_selected_text_toolbar() {\n\n\tob_start();\n\n\t\n\t$is_mobile = wp_is_mobile();\n\n\t// check for lasso story engine and add a class doniting this\n\t$ase_status = class_exists( 'Aesop_Core' ) || defined( 'LASSO_CUSTOM' ) ? 'ase-active' : 'ase-not-active';\n\n\t// let users add custom css classes\n\t$custom_classes = apply_filters( 'lasso_toolbar_classes', '' );\n\n\t// are toolbar headings enabled\n\t$toolbar_headings      = lasso_editor_get_option( 'toolbar_headings', 'lasso_editor' );\n\t$toolbar_headings_h4      = lasso_editor_get_option( 'toolbar_headings_h4', 'lasso_editor' );\n\t$toolbar_list      = lasso_editor_get_option( 'toolbar_list', 'lasso_editor' );\n\n\t$toolbar_class  = $toolbar_headings ? 'toolbar-extended' : false;\t\n\t\n\t//show color\n\t$show_color = lasso_editor_get_option('toolbar_show_color', 'lasso_editor');\n\t\n\t//show alignment\n\t$show_align = lasso_editor_get_option('toolbar_show_alignment', 'lasso_editor');\n\t\n\t$status = get_post_status( get_the_ID() );\n\t\n\t$shortcodify_disabled = lasso_editor_get_option( 'shortcodify_disabled', 'lasso_editor' );\n\t\n\t$sc_saving_class = ('on' == $shortcodify_disabled || $ase_status == 'ase-not-active')  ? 'shortcodify-disabled' : 'shortcodify-enabled';\n\n    $use_wp_block_image = lasso_editor_get_option('use_wp_block_image', 'lasso_editor','off');\n\n\t?>\n\t<div class=\"lasso--text-popup lasso-editor-controls--wrap <?php echo $toolbar_class.' '.$ase_status.' '.sanitize_html_class( $custom_classes );?>\"  style=\"display:none;\">\n\t\t<ul class=\"lasso--toolbar__inner lasso-editor-controls\" <?php if ($is_mobile) {echo 'style=\"float:left;\"';}?>>\n\t\t\t<?php do_action( 'lasso_toolbar_components_before' );?>\n\t\t    <li id=\"lasso-toolbar--bold\" title=\"<?php esc_attr_e( 'Bold', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--underline\" title=\"<?php esc_attr_e( 'Underline', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--italic\" title=\"<?php esc_attr_e( 'Italicize', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--strike\" title=\"<?php esc_attr_e( 'Strikethrough', 'lasso' );?>\"></li>\n\t\t\t\n\t\t    <?php if ( $toolbar_headings ): ?>\n\t\t    <li id=\"lasso-toolbar--h2\" title=\"<?php esc_attr_e( 'H2 Heading', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--h3\" title=\"<?php esc_attr_e( 'H3 Heading', 'lasso' );?>\"></li>\n\t\t\t<?php endif; ?>\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t<?php if ( $toolbar_headings_h4 ): ?>\n\t\t    <li id=\"lasso-toolbar--h4\" title=\"<?php esc_attr_e( 'H4 Heading', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--h5\" title=\"<?php esc_attr_e( 'H5 Heading', 'lasso' );?>\"></li>\n\t\t\t<li id=\"lasso-toolbar--h6\" title=\"<?php esc_attr_e( 'H6 Heading', 'lasso' );?>\"></li>\n\t\t\t<?php endif; ?>\n\t\t\t\n\t\t\t<?php if ( $show_color ): ?>\n\t\t    <li id=\"lasso-toolbar--color-set\" title=\"<?php esc_attr_e( 'Set Color for Selected Text', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--color-pick\" title=\"<?php esc_attr_e( 'Choose Color', 'lasso' );?>\"></li>\n\t\t\t<?php endif; ?>\n\t\t\t\n\t\t\t<?php if ( $toolbar_list ): ?>\n\t\t    <li id=\"lasso-toolbar--ol\" title=\"<?php esc_attr_e( 'Ordered List', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--ul\" title=\"<?php esc_attr_e( 'Unordered List', 'lasso' );?>\"></li>\n\t\t\t<?php endif; ?>\n\t\t\t\t\t\n\t\t    \n\t\t\t<li id=\"lasso-toolbar--link\" title=\"<?php esc_attr_e( 'Anchor Link', 'lasso' );?>\">\n\t\t    \t<div id=\"lasso-toolbar--link__wrap\" <?php echo $mobile_style ?> >\n\t\t    \t\t<div id=\"lasso-toolbar--link__inner\" contenteditable=\"true\" placeholder=\"<?php esc_attr_e( 'http://url.com', 'lasso' );?>\"></div>\n\t\t    \t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Create Link', 'lasso' );?>\" class=\"lasso-toolbar--link__control\" id=\"lasso-toolbar--link__create\" ></a>\n\t\t\t\t\t<input class=\"styled-checkbox\" type=\"checkbox\" id=\"aesop-toolbar--link_newtab\" checked/>\n                    <label for=\"aesop-toolbar--link_newtab\"><?php esc_attr_e( 'Open in a New Tab', 'lasso' );?></label>\n\t\t    \t</div>\n\t\t    </li>\n\t\t    <?php do_action( 'lasso_toolbar_components_after' );?>\n\t\t</ul>\t\t\t\t\n\t</div>\n\n\t<?php return ob_get_clean();\n}\n\n/**\n * Draw the main toolbar used to edit the text\n *\n * @since 1.0\n */\nfunction lasso_editor_text_toolbar() {\n\n\tob_start();\n    $text_select_popup = lasso_editor_get_option('text_select_popup', 'lasso_editor', false);\n\n\t\n\t$is_mobile = wp_is_mobile();\n\n\t// check for lasso story engine and add a class doniting this\n\t$ase_status = class_exists( 'Aesop_Core' ) || defined( 'LASSO_CUSTOM' ) ? 'ase-active' : 'ase-not-active';\n\n\t// let users add custom css classes\n\t$custom_classes = apply_filters( 'lasso_toolbar_classes', '' );\n\n\t// are toolbar headings enabled\n\t$toolbar_headings      = lasso_editor_get_option( 'toolbar_headings', 'lasso_editor' );\n\t$toolbar_headings_h4      = lasso_editor_get_option( 'toolbar_headings_h4', 'lasso_editor' );\n\t$toolbar_list      = lasso_editor_get_option( 'toolbar_list', 'lasso_editor' );\n\n\t$toolbar_class  = $toolbar_headings ? 'toolbar-extended' : false;\n\t\n\t// mobile styles\n    $mobile_class = $is_mobile ? 'lasso-mobile' : false;\n\t$mobile_style =$is_mobile ? 'style=\"bottom:0px;\"' : null;\n\t\n\t//show color\n\t$show_color = lasso_editor_get_option('toolbar_show_color', 'lasso_editor');\n\t\n\t//show alignment\n\t$show_align = lasso_editor_get_option('toolbar_show_alignment', 'lasso_editor');\n\t\n\t$status = get_post_status( get_the_ID() );\n\t\n\t$shortcodify_disabled = lasso_editor_get_option( 'shortcodify_disabled', 'lasso_editor' );\n\t\n\t$sc_saving_class = ('on' == $shortcodify_disabled || $ase_status == 'ase-not-active')  ? 'shortcodify-disabled' : 'shortcodify-enabled';\n\n    $use_wp_block_image = lasso_editor_get_option('use_wp_block_image', 'lasso_editor','off');\n\n\t?>\n\t<div class=\"lasso--toolbar_wrap lasso-editor-controls--wrap <?php echo $toolbar_class.' '.$mobile_class.' '.$ase_status.' '.sanitize_html_class( $custom_classes );?>\" <?php echo $mobile_style ?>>\n\t\t<ul class=\"lasso--toolbar__inner lasso-editor-controls\" <?php if ($is_mobile) {echo 'style=\"float:left;\"';}?>>\n\t\t\t<?php do_action( 'lasso_toolbar_components_before' );?>\n            <?php if (!$text_select_popup) { ?>\n\t\t    <li id=\"lasso-toolbar--bold\" title=\"<?php esc_attr_e( 'Bold', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--underline\" title=\"<?php esc_attr_e( 'Underline', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--italic\" title=\"<?php esc_attr_e( 'Italicize', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--strike\" title=\"<?php esc_attr_e( 'Strikethrough', 'lasso' );?>\"></li>\n            <?php }?>\n\t\t\t<li id=\"lasso-toolbar--components\" class=\"lasso-toolbar--components\" title=\"<?php esc_attr_e( 'Insert Component', 'lasso' );?>\" style=\"color:#ffffa0;\">\n\t\t\t    <ul id=\"lasso-toolbar--components__list\" style=\"display:none;color:white;\">\n\t\t\t    \t<?php if ( 'ase-active' == $ase_status ): ?>\n\t\t\t\t\t\t<li data-type=\"image\" title=\"<?php esc_attr_e( 'Image', 'lasso' );?>\" class=\"lasso-toolbar--component__image\"></li>\n\t\t\t\t\t\t<li data-type=\"character\" title=\"<?php esc_attr_e( 'Character', 'lasso' );?>\" class=\"lasso-toolbar--component__character\"></li>\n\t\t\t\t\t\t<li data-type=\"quote\" title=\"<?php esc_attr_e( 'Quote', 'lasso' );?>\"  class=\"lasso-toolbar--component__quote\"></li>\n\t\t\t\t\t\t<!--li data-type=\"content\" title=\"<?php esc_attr_e( 'Content', 'lasso' );?>\"  class=\"lasso-toolbar--component__content\"></li-->\n\t\t\t\t\t\t<li data-type=\"chapter\" title=\"<?php esc_attr_e( 'Chapter', 'lasso' );?>\"  class=\"lasso-toolbar--component__chapter\"></li>\n\t\t\t\t\t\t<li data-type=\"parallax\" title=\"<?php esc_attr_e( 'Parallax', 'lasso' );?>\"  class=\"lasso-toolbar--component__parallax\"></li>\n\t\t\t\t\t\t<li data-type=\"audio\" title=\"<?php esc_attr_e( 'Audio', 'lasso' );?>\"  class=\"lasso-toolbar--component__audio\"></li>\n\t\t\t\t\t\t<li data-type=\"video\" title=\"<?php esc_attr_e( 'Video', 'lasso' );?>\"  class=\"lasso-toolbar--component__video\"></li>\n\t\t\t\t\t\t<li data-type=\"map\" title=\"<?php esc_attr_e( 'Map', 'lasso' );?>\"  class=\"lasso-toolbar--component__map\"></li>\n\t\t\t\t\t\t<li data-type=\"timeline_stop\" title=\"<?php esc_attr_e( 'Timeline', 'lasso' );?>\"  class=\"lasso-toolbar--component__timeline\"></li>\n\t\t\t\t\t\t<li data-type=\"document\" title=\"<?php esc_attr_e( 'Document', 'lasso' );?>\"  class=\"lasso-toolbar--component__document\"></li>\n\t\t\t\t\t\t<li data-type=\"collection\" title=\"<?php esc_attr_e( 'Collection', 'lasso' );?>\"  class=\"lasso-toolbar--component__collection\"></li>\n\t\t\t\t\t\t<li data-type=\"gallery\" title=\"<?php esc_attr_e( 'Gallery', 'lasso' );?>\"  class=\"lasso-toolbar--component__gallery\"></li>\n\t\t\t\t\t\t<?php if ( class_exists ('Aesop_GalleryPop') ) { ?>\n\t\t\t\t\t\t     <li data-type=\"gallery\" title=\"<?php esc_attr_e( 'Gallery Pop', 'lasso' );?>\"  class=\"lasso-toolbar--component__gallerypop\"></li>\n\t\t\t\t\t\t<?php }?>\n\t\t\t\t\t\t<?php if ( class_exists ('Aesop_Events') ) { ?>\n\t\t\t\t\t\t     <li data-type=\"events\" title=\"<?php esc_attr_e( 'Event', 'lasso' );?>\"  class=\"lasso-toolbar--component__event\"></li>\n\t\t\t\t\t\t<?php }?>\n\t\t\t\t\t<?php else: ?>\n                        <?php if ($use_wp_block_image == 'on') { ?>\n                            <li data-type=\"wpimg-block\" title=\"<?php esc_attr_e( 'WordPress Image', 'lasso' );?>\" class=\"image lasso-toolbar--component__image\"></li>\n                        <?php } else { ?>\n\t\t\t\t\t\t    <li data-type=\"wpimg\" title=\"<?php esc_attr_e( 'WordPress Image', 'lasso' );?>\" class=\"image lasso-toolbar--component__image\"></li>\n                        <?php } ?>\n\t\t\t\t\t\t<li data-type=\"wpquote\" title=\"<?php esc_attr_e( 'WordPress Quote', 'lasso' );?>\" class=\"quote lasso-toolbar--component__quote\"></li>\n\t\t\t\t\t\t<!--li data-type=\"wpvideo\" title=\"<?php esc_attr_e( 'WordPress Video', 'lasso' );?>\" class=\"video lasso-toolbar--component__video\"></li-->\n\t\t\t\t\t<?php endif; ?>\n\t\t\t\t\t<?php do_action( 'lasso_toolbar_components' );?>\n\t\t\t    </ul>\n\t\t\t</li>\n            <?php if (!$text_select_popup) { ?>\n            \n\t\t    <?php if ( $toolbar_headings ): ?>\n\t\t    <li id=\"lasso-toolbar--h2\" title=\"<?php esc_attr_e( 'H2 Heading', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--h3\" title=\"<?php esc_attr_e( 'H3 Heading', 'lasso' );?>\"></li>\n\t\t\t<?php endif; ?>\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t<?php if ( $toolbar_headings_h4 ): ?>\n\t\t    <li id=\"lasso-toolbar--h4\" title=\"<?php esc_attr_e( 'H4 Heading', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--h5\" title=\"<?php esc_attr_e( 'H5 Heading', 'lasso' );?>\"></li>\n\t\t\t<li id=\"lasso-toolbar--h6\" title=\"<?php esc_attr_e( 'H6 Heading', 'lasso' );?>\"></li>\n\t\t\t<?php endif; ?>\n\t\t\t\n\t\t\t<?php if ( $show_color ): ?>\n\t\t    <li id=\"lasso-toolbar--color-set\" title=\"<?php esc_attr_e( 'Set Color for Selected Text', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--color-pick\" title=\"<?php esc_attr_e( 'Choose Color', 'lasso' );?>\"></li>\n\t\t\t<?php endif; ?>\n\t\t\t\n\t\t\t<?php if ( $toolbar_list ): ?>\n\t\t    <li id=\"lasso-toolbar--ol\" title=\"<?php esc_attr_e( 'Ordered List', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--ul\" title=\"<?php esc_attr_e( 'Unordered List', 'lasso' );?>\"></li>\n\t\t\t<?php endif; ?>\n\t\t\t\t\t\n\t\t    \n\t\t\t<li id=\"lasso-toolbar--link\" title=\"<?php esc_attr_e( 'Anchor Link', 'lasso' );?>\">\n\t\t    \t<div id=\"lasso-toolbar--link__wrap\" <?php echo $mobile_style ?> >\n\t\t    \t\t<div id=\"lasso-toolbar--link__inner\" contenteditable=\"true\" placeholder=\"<?php esc_attr_e( 'http://url.com', 'lasso' );?>\"></div>\n\t\t    \t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Create Link', 'lasso' );?>\" class=\"lasso-toolbar--link__control\" id=\"lasso-toolbar--link__create\" ></a>\n\t\t\t\t\t<input class=\"styled-checkbox\" type=\"checkbox\" id=\"aesop-toolbar--link_newtab\" checked/>\n                    <label for=\"aesop-toolbar--link_newtab\"><?php esc_attr_e( 'Open in a New Tab', 'lasso' );?></label>\n\t\t    \t</div>\n\t\t    </li>\n            \n            <?php } ?>\n            \n\t\t    <?php do_action( 'lasso_toolbar_components_after' );?>\n\t\t    <li id=\"lasso-toolbar--html\" title=\"<?php esc_attr_e( 'Insert HTML or Code', 'lasso' );?>\">\n\t\t    \t<div id=\"lasso-toolbar--html__wrap\" <?php echo $mobile_style ?>>\n\t\t    \t\t<div id=\"lasso-toolbar--html__inner\" contenteditable=\"true\" placeholder=\"<?php esc_attr_e( 'Enter HTML to insert', 'lasso' );?>\"></div>\n\t\t    \t\t<div id=\"lasso-toolbar--html__footer\">\n\t\t\t\t\t<div id=\"lasso-toolbar--html__footer_desc\" >\n\t\t\t\t\t<?php esc_attr_e( 'Enter HTML to insert', 'lasso' );?><br>\n\t\t\t\t\t<?php esc_attr_e( 'You can also use Shortcodes', 'lasso' );?><br>\n\t\t\t\t\t<?php esc_attr_e( 'You can also enter a URL to embed, such as Youtube, Vimeo and Twitter URLs.', 'lasso' );?>\n\t\t\t\t\t</div>\n\t\t    \t\t\t<ul class=\"lasso-toolbar--html-snips\">\n\t\t\t\t\t\t\n\t\t    \t\t\t\t<?php if ( !$toolbar_headings ): ?>\n\t\t    \t\t\t\t<li id=\"lasso-html--h2\" title=\"<?php esc_attr_e( 'H2 Heading', 'lasso' );?>\">\n\t\t    \t\t\t\t<li id=\"lasso-html--h3\" title=\"<?php esc_attr_e( 'H3 Heading', 'lasso' );?>\">\n\t\t    \t\t\t\t<?php endif; ?>\n\t\t    \t\t\t\t<li id=\"lasso-html--ol\" title=\"<?php esc_attr_e( 'Ordered List', 'lasso' );?>\">\n\t\t\t\t\t\t\t<li id=\"lasso-html--ul\" title=\"<?php esc_attr_e( 'Unordered List', 'lasso' );?>\">\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<li id=\"lasso-html--table\" title=\"<?php esc_attr_e( 'Table', 'lasso' );?>\">\n\t\t    \t\t\t</ul>\n\t\t    \t\t\t<a class=\"lasso-toolbar--html__control lasso-toolbar--html__cancel\" href=\"#\"><?php _e( 'Cancel', 'lasso' );?></a>\n\t\t    \t\t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Insert HTML or Code', 'lasso' );?>\" class=\"lasso-toolbar--html__control\" id=\"lasso-toolbar--html__insert\" ><?php _e( 'Insert', 'lasso' );?></a>\n\t\t    \t\t</div>\n\t\t    \t</div>\n\t\t    </li>\n             \n\t\t\t<?php if ( $show_align ): ?>\n\t\t    <li id=\"lasso-toolbar--left-align\" title=\"<?php esc_attr_e( 'Text Left Align', 'lasso' );?>\"></li>\n\t\t    <li id=\"lasso-toolbar--center-align\" title=\"<?php esc_attr_e( 'Text Center Align', 'lasso' );?>\"></li>\n\t\t\t<li id=\"lasso-toolbar--right-align\" title=\"<?php esc_attr_e( 'Text Right Align', 'lasso' );?>\"></li>\n\t\t\t<?php endif; ?>\n           \n\t\t</ul>\n\t\t<?php if ( is_singular() && $is_mobile ) { ?>\n\n\t\t\t\t<div class=\"lasso--controls__right\" data-posttype=\"<?php echo get_post_type( get_the_ID() );?>\" data-status=\"<?php echo $status;?>\" style=\"position:static;bottom:0px;right;0px;left:auto;\">\n\n\t\t\t\t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Delete Post', 'lasso' );?>\" id=\"lasso--post-delete\" class=\"lasso-save-post lasso--button <?php echo $sc_saving_class;?>\"></a>\n\t\t\t\t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Post Settings', 'lasso' );?>\" id=\"lasso--post-settings2\" class=\"lasso-save-post lasso--button <?php echo $sc_saving_class;?>\"></a>\n\n\t\t\t\t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Save Post', 'lasso' );?>\" id=\"lasso--save\" class=\"lasso-save-post lasso--button <?php echo $sc_saving_class;?>\"></a>\n\n\t\t\t\t\t<?php if ( 'draft' == $status && ( lasso_user_can('publish_posts') || lasso_user_can('publish_pages') )  ) { ?>\n\t\t\t\t\t\t<a href=\"#\" title=\"<?php esc_attr_e( 'Publish Post', 'lasso' );?>\" id=\"lasso--publish\" class=\"lasso-publish-post lasso--button <?php echo $sc_saving_class;?>\"></a>\n\t\t\t\t\t<?php } ?>\n\n\t\t\t\t</div>\n\n\t\t<?php } ?>\n\t</div>\n\n\t<?php return ob_get_clean();\n}\n\n\n\n/**\n * Draw the controls used for the component settings within each component\n *\n * @since 1.0\n */\nfunction lasso_editor_settings_toolbar() {\n\n\t$delete_nonce = wp_create_nonce( 'lasso-delete-nonce' );\n\n\tob_start();\n\n\n\t// let users add custom css classes\n\t$custom_classes = apply_filters( 'lasso_component_classes', '' );\n\n\t?>\n\t<ul class=\"lasso-component--controls editus-center <?php echo sanitize_html_class( $custom_classes );?>\" contenteditable=\"false\">\n\t\t<li class=\"lasso-drag\" title=\"<?php esc_attr_e( 'Move', 'lasso' );?>\"></li>\n\t\t<li class=\"lasso-component--settings__trigger  lasso-settings\" title=\"<?php esc_attr_e( 'Settings', 'lasso' );?>\"></li>\n\t\t<li class=\"lasso-clone\" title=\"<?php esc_attr_e( 'Clone', 'lasso' );?>\"></li>\n\t\t<li class=\"lasso-delete\" data-postid=\"<?php echo get_the_ID();?>\" data-nonce=\"<?php echo $delete_nonce;?>\" title=\"<?php esc_attr_e( 'Delete', 'lasso' );?>\"></li>\n\t</ul>\n\n\t<?php return ob_get_clean();\n}\n\n/**\n * Draws the controls used for changing the featured image\n *   These controls are appended based on the class set in the define\n *\n * @since 1.0\n */\nfunction lasso_editor_image_controls() {\n\n\tob_start();\n\n\n\t// has post thumbnail\n\t$has_thumbnail = has_post_thumbnail( get_the_ID() ) ? 'class=\"lasso--featImg--has-thumb\"' : false;\n\n\t?>\n\t<ul id=\"lasso--featImgControls\" <?php echo $has_thumbnail;?>>\n\t\t<li id=\"lasso--featImgUpload\"><a title=\"<?php esc_attr_e( 'Replace Image', 'lasso' );?>\" href=\"#\"><i class=\"lasso-icon-image\"></i></a></li>\n\t\t<li id=\"lasso--featImgDelete\"><a title=\"<?php esc_attr_e( 'Delete Image', 'lasso' );?>\" href=\"#\"><i class=\"lasso-icon-bin2\"></i></a></li>\n\t\t<li id=\"lasso--featImgSave\"><a href=\"#\"><?php esc_attr_e( 'save', 'lasso' );?></a></li>\n\t</ul>\n\n\t<?php return ob_get_clean();\n}\n\n\n/**\n * Used to house post settings like scheduling, slugs and draft status\n * Note: the \"add new\" will use the same object as the currently shown. For example, if the user\n * is currently on a post, and clicks add new, then it'll add a new post. If the user is on a\n * post type like \"dog\", then it will create a new post type called \"dog\"\n *\n * @since 1.0\n */\nfunction lasso_editor_component_modal() {\n\n\tob_start();\n\n\n\tglobal $post;\n\n\t$postid = get_the_ID();\n\n\t$status = get_post_status( $postid );\n\t$nonce = wp_create_nonce( 'lasso-update-post-settings' );\n\n\t// let users add custom css classes\n\t$custom_classes = apply_filters( 'lasso_modal_settings_classes', '' );\n\n\t// objects categories\n\t$categories \t\t= lasso_get_post_objects( $postid, 'category' );\n\t$tags \t\t\t\t= lasso_get_post_objects( $postid, 'tag' );\n\t\n\t// modal tabs\n\t$tabs  \t\t\t\t= lasso_modal_addons('tab');\n\t$content \t\t\t= lasso_modal_addons('content');\n\t\n\t//editor options\n\t$allow_change_date = lasso_editor_get_option('allow_change_date', 'lasso_editor');\n    $allow_edit_excerpt = lasso_editor_get_option('allow_edit_excerpt', 'lasso_editor');\n\t$no_url_setting = lasso_editor_get_option('no_url_setting', 'lasso_editor');\n\t$support_custom_taxonomy   = lasso_editor_get_option( 'support_custom_taxonomy', 'lasso_editor' );\n\t\n\t//get custom taxonomy\n\tif ($support_custom_taxonomy) {\n\t\t$custom_taxonomies         = array_diff(get_object_taxonomies( get_post_type( $postid ), 'names' ), ['category','post_tag','post_format']);\n\t} else {\n\t\t$custom_taxonomies = [];\n\t}\n\n\t// are we singular\n\t$is_singular \t\t= is_singular();\n\t$is_singular_class \t= $is_singular ? 'lasso--postsettings__2col' : 'lasso--postsettings__1col';\n\t$has_thumb_class    = has_post_thumbnail() ? 'has-thumbnail' : 'no-thumbnail';\n\t$theme_supports     = current_theme_supports('post-thumbnails');\n\t$default_image \t\t= LASSO_URL.'/admin/assets/img/empty-img.png';\n\t\n\t// do we support pending status\n\t$no_pending_status = lasso_editor_get_option('no_pending_status', 'lasso_editor');\n    \n    $excerpt = $post->post_excerpt;\n\n?>\n\t<div id=\"lasso--post-settings__modal\" class=\"lasso--modal lassoShowAnimate <?php echo sanitize_html_class( $custom_classes );?>\">\n\t\t<div class=\"lasso--modal__inner\">\n\n\t\t\t<?php if( $tabs ) { echo $tabs; } ?>\n\n\t\t\t<div class=\"lasso--modal__content modal__content--core visible\" data-addon-content=\"core\">\n\t\t\t\t<form id=\"lasso--postsettings__form\" enctype=\"multipart/form-data\" class=\"lasso--post-form <?php echo $is_singular_class.' '.$has_thumb_class;?>\" >\n\n\t\t\t\t\t<?php if ( $is_singular && $theme_supports ) : ?>\n\t\t\t\t\t<div class=\"lasso--postsettings__left\">\n\t\t\t\t\t\t<label><?php _e( 'Featured Image', 'lasso' );?><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"<?php esc_attr_e( 'Change the featured image for this post.', 'lasso' );?>\"><i class=\"lasso-icon-help\"></i></span></label>\n\t\t\t\t\t\t<div class=\"lasso--post-thumb\" data-default-thumb=\"<?php echo esc_url( $default_image );?>\">\n\n\t\t\t\t\t\t\t<div id=\"lasso--post-thumb__controls\" class=\"lasso--post-thumb__controls\">\n\t\t\t\t\t\t\t\t<i id=\"lasso--post-thumb__add\" title=\"<?php _e('Change Featured Image','lasso');?>\" class=\"dashicons dashicons-edit\"></i>\n\t\t\t\t\t\t\t\t<i id=\"lasso--post-thumb__delete\" title=\"<?php _e('Delete Featured Image','lasso');?>\" class=\"dashicons dashicons-no-alt\"></i>\n\t\t\t\t\t\t\t\t<i id=\"lasso--save-status\" class=\"lasso-icon lasso-icon-spinner6 not-visible\"></i>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<?php echo has_post_thumbnail() ? get_the_post_thumbnail( $post->ID, 'medium' ) : '<img src=\"'.$default_image.'\">'; ?>\n\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div id=\"lasso--featImgSave\"><a href=\"#\" class=\"not-visible\">Save</a></div>\n\n\t\t\t\t\t</div>\n\t\t\t\t\t<?php endif; ?>\n\n\t\t\t\t\t<div class=\"lasso--postsettings__right\">\n\n\t\t\t\t\t\t<?php if( lasso_user_can('publish_posts') || lasso_user_can('publish_pages') ): ?>\n\t\t\t\t\t\t<div class=\"lasso--postsettings__option story-status-option\">\n\t\t\t\t\t\t\t<label><?php _e( 'Status', 'lasso' );?><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"<?php esc_attr_e( 'Change the status of the post to draft or publish.', 'lasso' );?>\"><i class=\"lasso-icon-help\"></i></span></label>\n\t\t\t\t\t\t\t<ul class=\"story-status story-status-<?php echo sanitize_html_class( $status );?>\">\n\t\t\t\t\t\t\t\t<li id=\"lasso--status-draft\"><?php _e( 'Draft', 'lasso' );?></li>\n\t\t\t\t\t\t\t\t<?php if( !$no_pending_status ): ?>\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<li id=\"lasso--status-pending\"><?php _e( 'Pending', 'lasso' );?></li>\n\t\t\t\t\t\t\t\t<?php endif; ?>\n\t\t\t\t\t\t\t\t<li id=\"lasso--status-publish\"><?php _e( 'Publish', 'lasso' );?></li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t<div class=\"lasso--slider_wrap\">\n\t\t\t\t\t\t\t\t<div id=\"lasso--slider\"></div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<?php endif; ?>\n\n\t\t\t\t\t\t<?php if ( 'publish' == $status  && !$no_url_setting): ?>\n\t\t\t\t\t\t<div class=\"lasso--postsettings__option story-slug-option\">\n\t\t\t\t\t\t\t<label><?php _e( 'Post URL', 'lasso' );?><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"<?php esc_attr_e( 'Change the URL (slug) of this post.', 'lasso' );?>\"><i class=\"lasso-icon-help\"></i></span></label>\n\t\t\t\t\t\t\t<input class=\"lasso--modal__trigger-footer\" type=\"text\" name=\"story_slug\" value=\"<?php echo isset( $post ) ? esc_attr( $post->post_name ) : false;?>\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<?php endif; ?>\n\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"lasso--postsettings__middle\">\n\n\t\t\t\t\t\t<div class=\"lasso--postsettings__option story-categories-option\">\n\t\t\t\t\t\t\t<label style=\"width:120px;\"><?php _e( 'Categories', 'lasso' );?><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"<?php esc_attr_e( 'Type a category name and press enter.', 'lasso' );?>\"><i class=\"lasso-icon-help\"></i></span></label>\n\t\t\t\t\t\t\t<input id=\"lasso--cat-select\" class=\"lasso--modal__trigger-footer\" type=\"hidden\" name=\"story_cats\" value=\"<?php echo $categories;?>\">\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"lasso--postsettings__option story-tags-option\">\n\t\t\t\t\t\t\t<label><?php _e( 'Tags', 'lasso' );?><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"<?php esc_attr_e( 'Type a tag name and press enter.', 'lasso' );?>\"><i class=\"lasso-icon-help\"></i></span></label>\n\t\t\t\t\t\t\t<input id=\"lasso--tag-select\" class=\"lasso--modal__trigger-footer\" type=\"hidden\" name=\"story_tags\" value=\"<?php echo $tags;?>\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<?php\n\t\t\t\t\t\tif (!empty($custom_taxonomies)) {\n\t\t\t\t\t\t?>\n\t\t\t\t\t\t<div class=\"lasso--postsettings__option story-custom-taxonomy-option\">\n\t\t\t\t\t\t\t<label><?php _e( 'Custom Taxonomy', 'lasso' );?><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"<?php esc_attr_e( 'Choose custom taxonomy.', 'lasso' );?>\"><i class=\"lasso-icon-help\"></i></span></label>\n\t\t\t\t\t\t\t<select id=\"lasso--custom-taxo-select\" class=\"lasso--modal__trigger-footer\" name=\"custom_taxo\">\n\t\t\t\t\t\t\t<?php foreach ($custom_taxonomies as $taxonomy) {?>\n\t\t\t\t\t\t\t<option value=\"<?php echo $taxonomy?>\"><?php echo $taxonomy?></option>\n\t\t\t\t\t\t\t<?php }?>\n\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t<input id=\"lasso--custom-taxo-input\" class=\"lasso--modal__trigger-footer\" type=\"hidden\" name=\"custom_taxo_input\" value=\"Uncategorized\">\n\t\t\t\t\t\t\t<input id=\"lasso--custom-taxo-store\" class=\"lasso--modal__trigger-footer\" type=\"hidden\" name=\"story_custom_taxonomies\" value=\"\">\n\t\t\t\t\t\t</div>\n\t\t\t\t\t    <?php\n\t\t\t\t\t\t}\n\t\t\t\t\t\t?>\n\t\t\t\t\t\t\n                        <?php \n\t\t\t\t\t\tif ($allow_edit_excerpt) { \n\t\t\t\t\t\t?>\n                        <div class=\"lasso--postsettings__option story-excerpt-option\">\n\t\t\t\t\t\t\t<label><?php _e( 'Excerpt', 'lasso' );?><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"<?php esc_attr_e( 'Edit excerpt', 'lasso' );?>\"><i class=\"lasso-icon-help\"></i></span></label>\n\t\t\t\t\t\t\t<input id=\"lasso--excerpt\" class=\"lasso--modal__trigger-footer\" type=\"text\" name=\"excerpt\" value=\"<?php echo $excerpt;?>\" style=\"width:100%\">\n\t\t\t\t\t\t</div>\n                        <?php\n\t\t\t\t\t\t}?>\n\t\t\t\t\t\t<?php \n\t\t\t\t\t\tif ($allow_change_date) { \n\t\t\t\t\t\t    $dateformat = get_option( 'date_format' ); \n\t\t\t\t\t\t?>\n\t\t\t\t\t\t    <label><?php _e( 'Post Date', 'lasso' ); ?></label>\n\t\t\t\t\t\t\t<input type=\"text\" class=\"editus_custom_date\" name=\"post_date\" value=\"<?php echo get_the_time($dateformat, $postid);?>\"/>\n\t\t\t\t\t\t\t<a href=\"#\" id=\"lasso--postsettings-setnow\"><?php _e( 'Set to Now', 'lasso' ); ?></a>\n\t\t\t\t\t\t<?php\n\t\t\t\t\t\t}?>\n\n\t\t\t\t\t</div>\n\t\t\t\t\t<!-- alternate way to display categories disabled now -->\n\t\t\t\t\t<!--div style=\"max-height:300px;overflow-y: scroll;\"-->\n                    <?php\n\t\t\t\t\t\t\t/*$allcats = explode(\",\",lasso_get_objects('category'));\n\t\t\t\t\t\t\t$currcats = explode(\",\",$categories);\n\t\t\t\t\t\t\tforeach ( $allcats  as $category ) {\n\t\t\t\t\t\t\t\tif (empty($category)) continue;\n\t\t\t\t\t\t\t   $checked =\"\";\n\t\t\t\t\t\t\t   if (  in_array( $category, $currcats ) ) {\n\t\t\t\t\t\t\t\t\t$checked = 'checked=\"checked\"';\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t   }\n\t\t\t\t\t\t\t   echo '<label><input type=\"checkbox\" '.$checked.' name=\"categories\" id=\"'.$category.'\" >'.$category.'</label>';\n\t\t\t\t\t\t\t}*/\n\t\t\t\t\t?>\n\t\t\t\t\t<!--/div-->\n\n\t\t\t\t\t<?php do_action( 'lasso_modal_post_form' ); // action ?>\n\n\t\t\t\t\t<div class=\"lasso--postsettings__footer\" >\n\t\t\t\t\t\t<a href=\"#\" class=\"lasso--postsettings-cancel\"><?php _e( 'Cancel', 'lasso' );?></a>\n\t\t\t\t\t\t<input type=\"hidden\" name=\"status\" value=\"\">\n\t\t\t\t\t\t<input type=\"hidden\" name=\"categories\" value=\"\">\n\t\t\t\t\t\t<input type=\"hidden\" name=\"postid\" value=\"<?php echo get_the_ID();?>\">\n\t\t\t\t\t\t<input type=\"hidden\" name=\"action\" value=\"process_update-object_post\">\n\t\t\t\t\t\t<input type=\"hidden\" name=\"nonce\" value=\"<?php echo $nonce;?>\">\n\t\t\t\t\t\t<?php do_action( 'lasso_modal_post_form_footer' ); // action ?>\n\t\t\t\t\t\t<input type=\"submit\" id=\"lasso--postsettings-submit\" value=\"<?php esc_attr_e( 'Save', 'lasso' );?>\">\n\t\t\t\t\t</div>\n\n\t\t\t\t</form>\n\t\t\t</div>\n\n\t\t\t<?php if( $tabs ) { echo $content; } ?>\n\n\t\t</div>\n\n\t</div>\n\t<div id=\"lasso--modal__overlay\"></div>\n\n\t<?php return ob_get_clean();\n}\n\n/**\n * Used to house the form for creating a new post within amodal\n *\n * @since 1.0\n */\nfunction lasso_editor_newpost_modal() {\n\n\tglobal $post;\n\n\tob_start();\n\n\n\t$status = get_post_status( get_the_ID() );\n\n\t$nonce = wp_create_nonce( 'lasso-editor-new-post' );\n\n\t// let users add custom css classes\n\t$custom_classes = apply_filters( 'lasso_modal_post_classes', '' );\n\n\t// return the post type\n\t$type = get_post_type( get_the_ID() );\n\n\t$mobile_style = \"\";\n\tif (wp_is_mobile()) {\n\t\t//$mobile_style = 'style=\"top:140px !important;\"';\n\t}\n\t?>\n\t<div id=\"lasso--post-new__modal\" class=\"lasso--modal lasso--modal__med lassoShowAnimate <?php echo sanitize_html_class( $custom_classes );?>\" <?php echo $mobile_style;?>\">\n\t\t<div class=\"lasso--modal__inner lasso--hasnewform\">\n\n\t\t\t<form id=\"lasso--postnew__form\" enctype=\"multipart/form-data\" class=\"lasso--post-form\">\n\n\t\t\t\t<div class=\"lasso--postsettings__option story-slug-option lasso--last-option\">\n\t\t\t\t\t<label><?php esc_attr_e( 'New <span>post</span> title', 'lasso' );?><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"<?php esc_attr_e( 'Specify title for new post, then save to edit.', 'lasso' );?>\"><i class=\"lasso-icon-help\"></i></span></label>\n\t\t\t\t\t<input class=\"lasso--modal__trigger-footer\" type=\"text\" required name=\"story_title\" value=\"\" placeholder=\"<?php esc_attr_e( 'Type Your Title Here', 'lasso' );?>\">\n\t\t\t\t\t\t<div class=\"lasso--select-wrap\" style=\"width:90px\">\n\t\t\t\t\t\t<select id=\"lasso--select-type\" name=\"story_type\">\n\n\t\t\t\t\t\t\t<?php\n\t\t\t\t\t\t\t\t$types = lasso_post_types_names();\n\t\t\t\t\t\t\t\tif ( !empty( $types ) ) {\n\t\t\t\t\t\t\t\t\tforeach( $types as $name => $label ) \n                                    {   \t\n                                        $type = $name;\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t//$type = preg_replace( '/s\\b/','', $name );\n\t\t\t\t\t\t\t\t\t\tif ($type == 'page' && !current_user_can('edit_pages')) {\n\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tprintf( '<option value=\"%s\">%s</option>', lcfirst( esc_attr( $type ) ) , ucfirst( esc_attr( $label ) ) );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t?>\n\n\t\t\t\t\t\t</select>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"lasso--postsettings__footer\">\n\t\t\t\t\t<a href=\"#\" class=\"lasso--postsettings-cancel\"><?php _e( 'Cancel', 'lasso' );?></a>\n\t\t\t\t\t<input type=\"hidden\" name=\"action\" value=\"process_new-object_post\">\n\t\t\t\t\t<?php\n\t\t\t\t\t\tif ( !empty( $types ) ) {\n\t\t\t\t\t\t\t// get the first element\n\t\t\t\t\t\t\t$keys = array_keys($types);\n\t\t\t\t\t\t    $type =$keys[0];\t\t\t\t\t\t\n\t\t\t\t\t\t\t//$type = preg_replace( '/s\\b/','', $type );\n\t\t\t\t\t\t\tprintf( '<input type=\"hidden\" name=\"object\" value=\"%s\">', lcfirst( esc_attr( $type ) ) );\t\t\n\t\t\t\t\t\t}\n\t\t\t\t\t?>\n\t\t\t\t\t<input type=\"hidden\" name=\"nonce\" value=\"<?php echo $nonce;?>\">\n\t\t\t\t\t<input type=\"submit\" value=\"<?php esc_attr_e( 'Create', 'lasso' );?>\">\n\t\t\t\t</div>\n\n\t\t\t</form>\n\n\t\t</div>\n\t</div>\n\t<div id=\"lasso--modal__overlay\"></div>\n\n\t<?php return ob_get_clean();\n}\n\n/**\n * Used to house the all posts pop-up\n *\n * @since 0.9.3\n */\nfunction lasso_editor_allpost_modal() {\n\n\tglobal $post;\n\t\n\tglobal $wp_post_types;\n    $labels = &$wp_post_types['post']->labels;\n    $labels->name = 'Articles';\n\n\tob_start();\n\n\t// post status\n\t$status = get_post_status( get_the_ID() );\n\n\t// let users add custom css classes\n\t$custom_classes = apply_filters( 'lasso_modal_all_post_classes', '' );\n\n\t?>\n\t<div id=\"lasso--all-posts__modal\" class=\"lasso--modal lasso--modal__full lassoShowAnimate <?php echo sanitize_html_class( $custom_classes );?>\" style=\"max-height:100%\">\n\t\t<div class=\"lasso--modal__inner\">\n\n\t\t\t<div class=\"lasso--post-filtering not-visible\">\n\t\t\t\t<div class=\"lasso--search__results\">\n\t\t\t\t\t<span id=\"lasso--results-found\"></span><?php _e('results found','lasso');?>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"lasso--search\">\n\t\t\t\t\t<i id=\"lasso--search__toggle\" class=\"dashicons dashicons-search\"></i>\n\t\t\t\t\t<input id=\"lasso--search-field\" type=\"text\" placeholder=\"search...\">\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<ul class=\"lasso--post-object-list\">\n\t\t\t\t<?php\n\n\t\t\t\t$post_types = lasso_post_types_names();\n\t\t\t\t$rest_bases = lasso_post_types_rest_base();\n\n\t\t\t\tif ( ! empty( $post_types ) ) {\n\t\t\t\t\t$first = 'active';\n\t\t\t\t\tforeach( $post_types as $name => $label ) {\n\t\t\t\t\t\tif (array_key_exists($name, $rest_bases)) {\n\t\t\t\t\t\t\tprintf( '<li class=\"%1s lasso--show-objects\" data-post-type=\"%2s\">%3s</li>', esc_attr( $first), esc_attr( $rest_bases[$name] ), esc_attr( $label ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$first = '';\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tdo_action('lasso_modal_post_objects');?>\n\n\t\t\t</ul>\n\t\t\t<div id=\"lasso--loading\" class=\"lasso--loading\"><div class=\"lasso--loader\"></div></div>\n\n\t\t\t<ul id=\"lasso--post-list\" class=\"lasso--post-list\"></ul>\n\n\t\t</div>\n\t</div>\n\t<div id=\"lasso--modal__overlay\"></div>\n\n\t<?php return ob_get_clean();\n}\n\nfunction lasso_editor_wpimg_edit() {\n\n\tob_start();\n\n\n    $use_old_wpimg = lasso_editor_get_option('use_old_wpimg', 'lasso_editor','off');\n    \n\t// let users add custom css classes\n\t$custom_classes = apply_filters( 'lasso_wpimg_classes', '' );\n\n\t?>\n\t<ul class=\"lasso-component--controls editus-center <?php echo sanitize_html_class( $custom_classes );?>\" contenteditable=\"false\">\n\t\t<li class=\"lasso-drag\" title=\"<?php esc_attr_e( 'Move', 'lasso' );?>\"></li>\n        <?php if ($use_old_wpimg=='on') {?>\n            <li  class=\"lasso--wpimg-edit lasso-settings\" title=\"<?php esc_attr_e( 'Settings', 'lasso' );?>\"></li>\n        <?php } else {?>\n            <li  class=\"lasso-component--settings__trigger lasso-settings\" title=\"<?php esc_attr_e( 'Settings', 'lasso' );?>\"></li>\n        <?php } ?>\n\t\t<li class=\"lasso-clone\" title=\"<?php esc_attr_e( 'Clone', 'lasso' );?>\"></li>\n\t\t<li class=\"lasso-delete\" title=\"<?php esc_attr_e( 'Delete', 'lasso' );?>\"></li>\n\t</ul>\n\n\t<?php return ob_get_clean();\n}\n\nfunction lasso_editor_wpimg_block_edit() {\n\tob_start();\n\n\t?>\n\t<ul class=\"lasso-component--controls editus-center\" contenteditable=\"false\">\n\t\t<li class=\"lasso-drag\" title=\"<?php esc_attr_e( 'Move', 'lasso' );?>\"></li>\n            <li  class=\"lasso-component--settings__trigger lasso-settings\" title=\"<?php esc_attr_e( 'Settings', 'lasso' );?>\"></li>\n\t\t<li class=\"lasso-clone\" title=\"<?php esc_attr_e( 'Clone', 'lasso' );?>\"></li>\n\t\t<li class=\"lasso-delete\" title=\"<?php esc_attr_e( 'Delete', 'lasso' );?>\"></li>\n\t</ul>\n\n\t<?php return ob_get_clean();\n}\n\nfunction lasso_editor_wpvideo_edit() {\n\n\tob_start();\n\n\n\t// let users add custom css classes\n\t$custom_classes = apply_filters( 'lasso_wpimg_classes', '' );\n\n\t?>\n\t<ul class=\"lasso-component--controls editus-center <?php echo sanitize_html_class( $custom_classes );?>\" contenteditable=\"false\">\n\t\t<li class=\"lasso-drag\" title=\"<?php esc_attr_e( 'Move', 'lasso' );?>\"></li>\n\t\t<li id=\"lasso--wpvideo-edit\" class=\"lasso-settings\" title=\"<?php esc_attr_e( 'Settings', 'lasso' );?>\"></li>\n\t\t<li class=\"lasso-clone\" title=\"<?php esc_attr_e( 'Clone', 'lasso' );?>\"></li>\n\t\t<li class=\"lasso-delete\" title=\"<?php esc_attr_e( 'Delete', 'lasso' );?>\"></li>\n\t</ul>\n\n\t<?php return ob_get_clean();\n}\n\n/**\n * Used to house the hidden input fields for actions and process saving for the map component\n *\n * @since 1.0\n */\nfunction lasso_map_form_footer() {\n\n\t$nonce = wp_create_nonce( 'lasso-process-map' );\n\n\tob_start();\n\n\t?>\n\t<div class=\"lasso--map-form__footer\">\n\t\t<input type=\"hidden\" name=\"postid\" value=\"<?php echo get_the_ID();?>\">\n\t\t<input type=\"hidden\" name=\"nonce\" value=\"<?php echo $nonce;?>\">\n\t\t<input type=\"hidden\" name=\"action\" value=\"process_map_save\">\n\t\t<input type=\"submit\" class=\"lasso--map-form__submit\" value=\"<?php esc_attr_e( 'Save Locations', 'lasso' );?>\">\n\t</div>\n\n\t<?php return ob_get_clean();\n\n}\n\n/**\n * Some things aren't real-time updatable so we need to append a message in certain areas on certain actions\n *\n * @since 1.0\n */\nfunction lasso_editor_refresh_message() {\n\n\tob_start();\n\n\t?>\n\t<div id=\"lasso--pagerefresh\" class=\"visible\">\n\t\t<?php _e( 'Save this post and refesh the page to see these changes.', 'lasso' );?>\n\t</div>\n\n\t<?php return ob_get_clean();\n}\n\n/**\n * Draw out the settings field based on the shortcodes array with options foudn in Aesop Story Engine\n *  This was mostly backported from aesop story engine and modified to allow for non aesop shortcodes and components\n *\n * @since 1.0\n */\nfunction lasso_editor_options_blob() {\n\n\t$codes   = function_exists( 'aesop_shortcodes' ) ? aesop_shortcodes() : array();\n    $codes   = add_wpimg_options( $codes );\n\t$codes   = add_wpimg_block_options( $codes );\n\t$codes   = add_wpcover_block_options( $codes );\n    $codes   = apply_filters( 'lasso_custom_options', $codes );\n\t$galleries  = function_exists( 'lasso_editor_galleries_exist' ) && lasso_editor_galleries_exist() ? 'has-galleries' : 'creating-gallery';\n\n\t$nonce = wp_create_nonce( 'lasso_gallery' );\n\n\t$blob = array();\n\n\tif ( empty( $codes ) )\n\t\treturn;\n\n\tforeach ( $codes as $slug => $shortcode ) {\n\t\t$return = '';\n\t\t// Shortcode has atts\n\n\t\tif ( count( $shortcode['atts'] ) && $shortcode['atts'] ) {\n\n\t\t\tforeach ( $shortcode['atts'] as $attr_name => $attr_info ) {\n\n\n\t\t\t\t$prefix = isset( $attr_info['prefix'] ) ? sprintf( '<span class=\"lasso-option-prefix\">%s</span>', $attr_info['prefix'] ) : null;\n\n\t\t\t\t$return .= '<form id=\"aesop-generator-settings\" class=\"lasso--component-settings-form\" class=\"'.$galleries.'\" method=\"post\">';\n\t\t\t\t$return .= '<p data-option=\"'.$attr_name.'\" class=\"lasso-option aesop-'.$slug.'-'.$attr_name.'\">';\n\t\t\t\t$return .= '<label for=\"aesop-generator-attr-' . $attr_name . '\">' . $attr_info['desc'] . '</label>';\n\t\t\t\t$return .= '<small class=\"lasso-option-desc\">'.$attr_info['tip'].'</small>';\n\t\t\t\t// Select\n\n\t\t\t\tif ( isset( $attr_info['values'] ) ) {\n\n\t\t\t\t\t$return .= '<select name=\"' . $attr_name . '\" id=\"aesop-generator-attr-' . $attr_name . '\" class=\"lasso-generator-attr\">';\n\n\t\t\t\t\t$i=0;\n\n\t\t\t\t\tforeach ( $attr_info['values'] as $attr_value ) {\n\t\t\t\t\t\t$attr_value_selected = $attr_info['default'] == $attr_value ? ' selected=\"selected\"' : '';\n\n\t\t\t\t\t\t$return .= '<option value=\"'.$attr_info['values'][$i]['value'].'\" ' . $attr_value_selected . '>'.$attr_info['values'][$i]['name'].'</option>';\n\n\t\t\t\t\t\t$i++;\n\t\t\t\t\t}\n\n\t\t\t\t\t$return .= '</select>';\n\n\t\t\t\t} else {\n\n\t\t\t\t\t$attr_field_type = isset( $attr_info['type'] ) ? $attr_info['type'] : 'text';\n\n\t\t\t\t\t// image upload\n\t\t\t\t\tif ( 'media_upload' == $attr_info['type'] ) {\n\n\t\t\t\t\t\t$return .= '<input type=\"' . $attr_field_type . '\" name=\"' . $attr_name . '\" value=\"'.$attr_info['default'].'\" id=\"aesop-generator-attr-' . $attr_name . '\" class=\"lasso-generator-attr aesop-generator-attr-'.$attr_field_type.'\" />';\n\t\t\t\t\t\t$return .= '<a href=\"#\" id=\"lasso-upload-img\" class=\"lasso-option-button\" /></a>';\n\n\t\t\t\t\t} elseif ( 'color' == $attr_info['type'] ) {\n\n\t\t\t\t\t\t$return .= '<input type=\"color\" name=\"' . $attr_name . '\" value=\"'.$attr_info['default'].'\" id=\"aesop-generator-attr-' . $attr_name . '\" class=\"lasso-generator-attr aesop-generator-attr-'.$attr_field_type.'\" />';\n\n\t\t\t\t\t} elseif ( 'text_area' == $attr_info['type'] ) {\n\n\t\t\t\t\t\t$return .= '<textarea name=\"' . $attr_name . '\" id=\"aesop-generator-attr-' . $attr_name . '\" class=\"lasso-generator-attr aesop-generator-attr-'.$attr_field_type.'\" placeholder=\"'.$attr_info['default'].'\" /></textarea>'.$prefix.'';\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$return .= '<input type=\"' . $attr_field_type . '\" name=\"' . $attr_name . '\" value=\"'.$attr_info['default'].'\" id=\"aesop-generator-attr-' . $attr_name . '\" class=\"lasso-generator-attr aesop-generator-attr-'.$attr_field_type.'\" />'.$prefix.'';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$return .= '</p>';\n\n\t\t\t}\n\t\t}\n\n\t\t///////////////////////////\n\t\t// START GALLERY AND MAP FRONT END STUFFS\n\t\t///////////////////////////\n\t\tif ( isset( $shortcode['front'] ) && true == $shortcode['front'] ) {\n\n\t\t\tif ( 'gallery' == $shortcode['front_type'] ) {\n\n\t\t\t\t$return .= lasso_gallery_editor_module();\n\n\t\t\t}\n\t\t}\n\t\t///////////////////////////\n\t\t// END GALLERY AND MAP FRONT END STUFFS\n\t\t///////////////////////////\n\n\t\t// Single shortcode (not closed)\n\t\tif ( 'single' == $shortcode['type'] ) {\n\n\t\t\t$return .= '<input type=\"hidden\" name=\"lasso-generator-content\" id=\"lasso-generator-content\" value=\"false\" />';\n\n\t\t} else {\n\n\t\t\t$return .= '<p data-option=\"content\" class=\"lasso-option lasso-c-comp-text\"><label>' . __( 'Content', 'lasso' ) . '</label><textarea type=\"text\" name=\"lasso-generator-content\" id=\"lasso-generator-content\" value=\"' . $shortcode['content'] . '\" /></textarea></p>';\n\t\t}\n\n\t\t$return .= '<p class=\"lasso-buttoninsert-wrap\"><a href=\"#\" class=\"lasso-generator-cancel\" id=\"lasso--sidebar__close\">Cancel</a><input type=\"submit\" id=\"lasso-generator-insert\" value=\"Save Settings\"></p>';\n\t\t$return .= '<input class=\"component_type\" type=\"hidden\" name=\"component_type\" value=\"\">';\n\t\t$return .= '<input type=\"hidden\" name=\"unique\" value=\"\">';\n\t\t$return .= '<input type=\"hidden\" name=\"nonce\" id=\"lasso-generator-nonce\" value=\"'.$nonce.'\" />';\n\t\t$return .= '</form>';\n\n\t\t// extra JS codes\n        if (isset($shortcode['codes'])) {\n\t\t    $return .= $shortcode['codes'];\n        }\n\t\t$blob[$slug] = $return;\n\t}\n\n\treturn $blob;\n}\n\n\nfunction add_wpimg_options( $shortcodes ) {\n    $custom = array(\n        'wpimg'    => array(\n            'name'     => __( 'Image', 'lasso' ),\n            'type'     => 'single',\n            'atts'     => array(\n                'img'    => array(\n                    'type'  => 'media_upload',\n                    'default'  => '',\n                    'desc'   => __( 'Image URL', 'lasso' ),\n                    'tip'  => __( 'URL for the image. Click <em>Select Media</em> to open the WordPress Media Library.', 'aesop-core' )\n                ),\n                'align'    => array(\n                    'type'  => 'select',\n                    'values'  => array(\t\t\t\t\t\t\n                        array(\n                            'value' => 'center',\n                            'name' => __( 'Center', 'aesop-core' )\n                        ),\n                        array(\n                            'value' => 'left',\n                            'name' => __( 'Left', 'aesop-core' )\n                        ),\n                        array(\n                            'value' => 'right',\n                            'name' => __( 'Right', 'aesop-core' )\n                        ),\n                    ),\n                    'default'  => 'center',\n                    'desc'   => __( 'Alignment', 'lasso' ),\n                    'tip'=>''\n                ),\t\t\t\n                \n                'imgwidth'    => array(\n                    'type'  => 'text_small',\n                    'default'  => '300px',\n                    'desc'   => __( 'Image Width', 'lasso' ),\n                    'tip'  => __( 'Width of the image. You can enter the size in pixels or percentage such as <code>40%</code> or <code>500px</code>.', 'aesop-core' )\n                ),\n                'imgheight'    => array(\n                    'type'  => 'text_small',\n                    'default'  => '',\n                    'desc'   => __( 'Image Height', 'lasso' ),\n                    'tip'  => __( 'Used only for the Panorama mode. Can be set using pixel values such as <code>500px</code>. If unspecified, the original height would be used. ', 'aesop-core' )\n                ),\t\n                'linkoption'    => array(\n                    'type'  => 'select',\n                    'values'  => array(\t\t\t\t\t\t\n                        array(\n                            'value' => 'none',\n                            'name' => __( 'None', 'aesop-core' )\n                        ),\n                        array(\n                            'value' => 'img',\n                            'name' => __( 'Image', 'aesop-core' )\n                        ),\n                        array(\n                            'value' => 'url',\n                            'name' => __( 'URL', 'aesop-core' )\n                        ),\n                    ),\n                    'default'  => 'none',\n                    'desc'   => __( 'Link', 'lasso' ),\n                    'tip'  => __( 'Click leads to:', 'lasso' )\n                ),\t\t\t\t\n                \n                'link'    => array(\n                    'type'  => 'text',\n                    'default'  => '',\n                    'desc'   => __( 'URL Link', 'lasso' ),\n                    'tip'  => __( 'URL link', 'lasso' )\n                ),\n                'alt'    => array(\n                    'type'  => 'text',\n                    'default'  => '',\n                    'desc'   => __( 'Image ALT', 'lasso' ),\n                    'tip'  => __( 'ALT tag used for the image. Primarily used for SEO purposes.', 'lasso' )\n                ),\n                \n                'caption'    => array(\n                    'type'  => 'text_area',\n                    'default'  => '',\n                    'desc'   => __( 'Caption', 'lasso' ),\n                    'tip'  => __( 'Optional caption for the image.', 'lasso' )\n                ),\n                \n\n            ),\n            'desc'     => __( 'An image.', 'aesop-core' ),\n            'codes'    => '<script>\t            \n\t\t\t\t\t\tjQuery(document).ready(function($){\n                            function linkSetting(l){\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t    if ( l==\"url\") {\n\t\t\t\t\t\t\t\t\tjQuery(\".aesop-wpimg-link\").slideDown();\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse  {\n\t\t\t\t\t\t\t\t\tjQuery(\".aesop-wpimg-link\").slideUp();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tsetTimeout( function() { \n                                linkSetting(jQuery(\"#aesop-generator-attr-linkoption\" ).val()); \n\t\t\t\t\t\t\t\t}, 500);\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tjQuery( \"#aesop-generator-attr-linkoption\" ).change(function() {\n\t\t\t\t\t\t\t\tlinkSetting( this.value);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t});\n\t\t\t           </script>'\n        )\n    );\n\n    return array_merge( $shortcodes, $custom );\n}\n\nfunction add_wpimg_block_options( $shortcodes ) {\n    $custom = array(\n        'wpimg-block'    => array(\n            'name'     => __( 'Image', 'lasso' ),\n            'type'     => 'single',\n            'atts'     => array(\n                'img'    => array(\n                    'type'  => 'media_upload',\n                    'default'  => '',\n                    'desc'   => __( 'Image URL', 'lasso' ),\n                    'tip'  => __( 'URL for the image. Click <em>Select Media</em> to open the WordPress Media Library.', 'aesop-core' )\n                ),\n                'align'    => array(\n                    'type'  => 'select',\n                    'values'  => array(\t\t\t\t\t\t\n                        array(\n                            'value' => 'center',\n                            'name' => __( 'Center', 'aesop-core' )\n                        ),\n                        array(\n                            'value' => 'left',\n                            'name' => __( 'Left', 'aesop-core' )\n                        ),\n                        array(\n                            'value' => 'right',\n                            'name' => __( 'Right', 'aesop-core' )\n                        ),\n                    ),\n                    'default'  => 'center',\n                    'desc'   => __( 'Alignment', 'lasso' ),\n                    'tip'=>''\n                ),\t\t\n                'alt'    => array(\n                    'type'  => 'text',\n                    'default'  => '',\n                    'desc'   => __( 'Image ALT', 'lasso' ),\n                    'tip'  => __( 'ALT tag used for the image. Primarily used for SEO purposes.', 'lasso' )\n                ),\n                'caption'    => array(\n                    'type'  => 'text',\n                    'default'  => '',\n                    'desc'   => __( 'Caption', 'lasso' ),\n                    'tip'  => __( 'Optional caption for the image.', 'lasso' )\n                ),\n                'link'    => array(\n                    'type'  => 'text',\n                    'default'  => '',\n                    'desc'   => __( 'Link URL', 'lasso' ),\n                    'tip'  => __( 'Optional URL to link.', 'lasso' )\n                ),\n               \n\n            ),\n            'desc'     => __( 'A WP Image Block.', 'aesop-core' ),\n            'codes'    => '<script>\t            \n\t\t\t\t\t\tjQuery(document).ready(function($){\n                            \n\t\t\t\t\t\t});\n\t\t\t           </script>'\n        )\n    );\n\n    return array_merge( $shortcodes, $custom );\n}\n\nfunction add_wpcover_block_options( $shortcodes ) {\n    $custom = array(\n        'wpcover-block'    => array(\n            'name'     => __( 'Cover', 'lasso' ),\n            'type'     => 'single',\n            'atts'     => array(\n                'img'    => array(\n                    'type'  => 'media_upload',\n                    'default'  => '',\n                    'desc'   => __( 'Image URL', 'lasso' ),\n                    'tip'  => __( 'URL for the image. Click <em>Select Media</em> to open the WordPress Media Library.', 'aesop-core' )\n                )\n\n            ),\n            'desc'     => __( 'A WP Cover Block.', 'aesop-core' ),\n            'codes'    => '<script>\t            \n\t\t\t\t\t\tjQuery(document).ready(function($){\n                            \n\t\t\t\t\t\t});\n\t\t\t           </script>'\n        )\n    );\n\n    return array_merge( $shortcodes, $custom );\n}\n\n/**\n * Revisions modal\n *\n * @since 0.9.8\n *\n * @return string\n */\nfunction lasso_editor_revision_modal() {\n\n\tob_start();\n\t?>\n\t\t<div id=\"lasso--revision__modal\" class=\"lasso--modal lassoShowAnimate \">\n\n\t\t\t<div class=\"lasso--modal__inner\">\n\t\t\t\t<div id=\"lasso--loading\" class=\"lasso--loading\"><div class=\"lasso--loader\"></div></div>\n\t\t\t\t<div id=\"lasso--hide\" style=\"display:none;\" class=\"lasso--post-form\">\n\t\t\t\t\t<i class=\"lasso-icon lasso-icon-move\"></i>\n\t\t\t\t\t<label><?php _e( 'Revisions', 'lasso' );?><span class=\"lasso-util--help lasso-util--help-top\" data-tooltip=\"<?php esc_attr_e( 'Use the slider to view the revision live on the page.', 'lasso' );?>\"><i class=\"lasso-icon-help\"></i></span></label>\n\t\t\t\t\t<div class=\"lasso--slider_wrap\">\n\t\t\t\t\t\t<div id=\"lasso--slider\"></div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul id=\"lasso--revision-list\"></ul>\n\t\t\t\t\t<div class=\"lasso--btn-group lasso--btn-group-small\">\n\t\t\t\t\t\t<a href=\"#\" class=\"lasso--btn-secondary\" id=\"lasso--close-modal\"><?php _e( 'Cancel', 'lasso' );?></a>\n\t\t\t\t\t\t<a href=\"#\" class=\"lasso--btn-primary\" id=\"lasso--select-revision\"><?php _e( 'Select', 'lasso' );?></a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t</div>\n\t\t</div>\n\t<?php\n\treturn ob_get_clean();\n}\n\n/**\n * \n * Takes a color code and returns an adjusted value\n * @since 1.0.0\n * Steps should be between -255 and 255. Negative = darker, positive = lighter\n * @return string\n */\nfunction lasso_editor_adjustBrightness($hex, $steps) { \n    $steps = max(-255, min(255, $steps));\n\n    // Normalize into a six character long hex string\n    $hex = str_replace('#', '', $hex);\n    if (strlen($hex) == 3) {\n        $hex = str_repeat(substr($hex,0,1), 2).str_repeat(substr($hex,1,1), 2).str_repeat(substr($hex,2,1), 2);\n    }\n\n    // Split into three parts: R, G and B\n    $color_parts = str_split($hex, 2);\n    $return = '#';\n\n    foreach ($color_parts as $color) {\n        $color   = hexdec($color); // Convert to decimal\n        $color   = max(0,min(255,$color + $steps)); // Adjust color\n        $return .= str_pad(dechex($color), 2, '0', STR_PAD_LEFT); // Make two char hex code\n    }\n\n    return $return;\n}\n"
  },
  {
    "path": "public/includes/helpers.php",
    "content": "<?php\n\n/**\n * Grab an option from our settings\n *\n * If we're on multsite we'll grab the site option which is stored in the main blogs site option tables, otherwise\n * we'll grab the option which is stored on the single blogs option tables\n *\n * @param unknown $option  string name of the option\n * @param unknown $section string name of the section\n * @param unknown $default string/int default option value\n * @return the option value\n * @since 1.0\n */\nif( !function_exists('lasso_editor_get_option')):\n\tfunction lasso_editor_get_option( $option, $section, $default = '' ) {\n\n\t\tif ( empty( $option ) )\n\t\t\treturn;\n\n\t\tif ( function_exists( 'is_multisite' ) && is_multisite() ) {\n\n\t\t\t$options = get_site_option( $section );\n\n\t\t} else {\n\n\t\t\t$options = get_option( $section );\n\t\t}\n\t\t\n\t\t$options = apply_filters( 'editus_filter_options', $options );\n\n\t\tif ( isset( $options[$option] ) ) {\n\t\t\treturn $options[$option];\n\t\t}\n\n\t\treturn $default;\n\t}\nendif;\n\n/**\n * Check to see if any Aesop galleries exist\n *\n * @since 1.0\n */\nfunction lasso_editor_galleries_exist() {\n\n\t$q = new wp_query( array( 'post_type' => 'ai_galleries', 'post_status' => 'publish' ) );\n\n\tif ( $q->have_posts() )\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\n/**\n * Return a CSS class of an automatically supported theme\n *\n * @since 0.8.6\n * @return a css class if the theme is supported, false if nothing\n */\nfunction lasso_get_supported_theme_class() {\n\n\t$name  \t= wp_get_theme()->get('Name');\n\t$slug  \t= lasso_clean_string( $name );\n\n\tswitch ( $slug ) {\n\t\tcase 'aesop-story-theme': // aesop\n\t\t\t$out = '.aesop-entry-content';\n\t\t\tbreak;\n\t\tcase 'jorgen': // aesop\n\t\t\t$out = '.jorgen-entry-content';\n\t\t\tbreak;\n\t\tcase 'novella': // aesop\n\t\t\t$out = '.novella-entry-content';\n\t\t\tbreak;\n\t\tcase 'genji': // aesop\n\t\t\t$out = '.genji-entry-content';\n\t\t\tbreak;\n\t\tcase 'kerouac': // aesop\n\t\t\t$out = '.kerouac-entry-content';\n\t\t\tbreak;\n\t\tcase 'zealot': // aesop\n\t\t\t$out = '.zealot-entry-content';\n\t\t\tbreak;\n\t\tcase 'fable': // aesop\n\t\t\t$out = '.fable--entry-content';\n\t\t\tbreak;\n\t\tcase 'canvas': // wootheme..err...Automattic\n\t\t\t$out = '.entry';\n\t\t\tbreak;\n\t\tcase 'kleo': // \n\t\t\t$out = '.article-content';\n\t\t\tbreak;\n\t\t//case 'exposure': // \n\t\t//\t$out = '.entry-content';\n\t\t//\tbreak;\n\t\t//case 'lore': // \n\t\t//\t$out = '.entry-content';\n\t\t//\tbreak;\n\t\t//case 'worldview': // upthemes\n\t\t//\t$out = '.entry-content';\n\t\t//\tbreak;\n\t\t//case 'genesis': // genesis\n\t\t//\t$out = '.entry-content';\n\t\t//\tbreak;\n\t\t//case 'camera': // array.is\n\t\t//\t$out = '.entry-content';\n\t\t//\tbreak;\n\t\tcase 'longform': \n\t\t\t$out = '.entry-content-wrapper';\n\t\t\tbreak;\n\n\t}\n\n\treturn apply_filters('lasso_content_class', !empty( $out ) ? $out : false);\n\t//return !empty( $out ) ? $out : false;\n}\n\nfunction lasso_get_supported_theme_title_class() {\n\n\t$name  \t= wp_get_theme()->get('Name');\n\t$slug  \t= lasso_clean_string( $name );\n\n\tswitch ( $slug ) {\n\n\t\tcase 'aesop-story-theme': // aesop\n\t\t\t$out = '.aesop-entry-title';\n\t\t\tbreak;\n\t\tcase 'jorgen': // aesop\n\t\t\t$out = '.jorgen-entry-title';\n\t\t\tbreak;\n\t\tcase 'genji': // aesop\n\t\t\t$out = '.genji-entry-title';\n\t\t\tbreak;\n\t\tcase 'kerouac': // aesop\n\t\t\t$out = '.kerouac-entry-title';\n\t\t\tbreak;\n\t\tcase 'zealot': // aesop\n\t\t\t$out = '.zealot-entry-title';\n\t\t\tbreak;\n\t\tcase 'fable': // aesop\n\t\t\t$out = '.fable--entry-title';\n\t\t\tbreak;\n\t\tcase 'kleo': // \n\t\t\t$out = '.page-title';\n\t\t\tbreak;\n\t\tcase 'longform': // \n\t\t\t$out = '.entry-title';\n\t\t\tbreak;\n\t}\n\n\treturn apply_filters('lasso_title_class', !empty( $out ) ? $out : false);\n}\n\n//since 0.9.9.6\nfunction lasso_get_supported_theme_featured_image_class() {\n\n\t$name  \t= wp_get_theme()->get('Name');\n\t$slug  \t= lasso_clean_string( $name );\n\n\treturn apply_filters('lasso_featured_image_class', !empty( $out ) ? $out : false);\n}\n\n\n/**\n*\tReturn a string of classes with items that Editus will remove when entering the editor\n*\tso that we don't save them as HTML\n*\n*\t@since 0.8.7\n*\t@return string of comma separated classes\n*/\nfunction lasso_supported_no_save(){\n\n\treturn apply_filters('lasso_dont_save', '.lasso--ignore,.sharedaddy,.us_wrapper,.meta,.edit-link,.ssba,.addtoany_share_save_container,.mashsb-container,.heateor_sss_sharing_container,.nc_socialPanel,.jp-relatedposts,.fb-comments,.adsbygoogle,.swp_social_panel,.code-block');\n}\n\n/**\n * Generic sanitization, useful for sanitization of arrays.\n *\n * @since 0.9.2\n *\n * @param array|object|string $data Data to sanatize.\n *\n * @return array|mixed|object|string|void\n */\nfunction lasso_sanitize_data( $data ) {\n\treturn \\lasso\\sanatize::do_sanitize( $data );\n\n}\n\n/**\n *\tReturn a comma delimited list of categories for a specific post object\n *\n *\t@since 0.9.3\n *\t@return string of comma delimited category slugs\n*/\nfunction lasso_get_post_objects( $postid, $taxonomy) {\n\n\tif ( empty( $postid ) )\n\t\t$postid = get_the_ID();\n\n    if ('category' == $taxonomy)  {\n        $objects = get_the_category( $postid );\n    } else if ('tag' == $taxonomy)  {\n        $objects = get_the_tags( $postid );\n    } else {\n        $objects = get_the_terms( $postid, $taxonomy );\n    }\n\n\tif ( empty( $objects) )\n\t\treturn;\n\n\t$out = '';\n\tforeach( $objects as $object ) {\n\t\t$out .= $object->name.',';\n\t}\n\n\treturn rtrim($out, ', ');\n\n}\n\n/**\n *\tReturn an array of categories for autocomplete\n *\n *\t@since 0.9.3\n *\t@return array all categoiries\n*/\nfunction lasso_get_objects( $taxonomy = 'category' ) {\n\n    if ('category' == $taxonomy)  {\n        $objects = get_categories(array('hide_empty' => 0));\n    } else if ('tag' == $taxonomy)  {\n        $objects = get_tags(array('hide_empty' => 0));\n    } else {\n        $objects = get_terms( array(\n            'taxonomy' => $taxonomy,\n            'hide_empty' => false,\n        ));\n    }\n\t\n\tif ( empty( $objects) )\n\t\treturn;\n\n\t$out = \"\";\n\tforeach( $objects as $object ) {\n\t\t$out .= $object->name.',';\n\t}\n\n\treturn $out;\n}\n\n\n/**\n * Get allowed post types for the post chooser modal.\n *\n *\n * @since 0.9.4\n */\nfunction lasso_post_types_names() {\n\t$post_types = get_post_types( array(\n\t\t'public' => true,\n\t), 'objects' );\n\t$post_types = array_combine( array_keys( $post_types ), wp_list_pluck( $post_types, 'label' ) );\n    unset( $post_types[ 'attachment' ] );\n\n\t/**\n\t * Set which post types are allowed\n\t *\n\t * @since 0.9.4\n\t *\n\t * @param array $allowed_post_types Array of names (not labels) of allowed post types. Must be registered.\n\t */\n\t$allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', array( 'post', 'page') );\n\t$allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types );\n\tif (!current_user_can('edit_pages')) {\n\t\t$allowed_post_types = array_diff($allowed_post_types,array('page'));\n\t}\n\tforeach( $post_types as $name => $label ) {\n\t\tif ( ! in_array( $name, $allowed_post_types ) ) {\n\t\t\tunset( $post_types[ $name ] );\n\t\t}\n\t}\n\treturn $post_types;\n}\n\n\nfunction lasso_post_types() {\n\t$post_types = get_post_types( array(\n\t\t'public' => true,\n\t), 'names' );\n    unset( $post_types[ 'attachment' ] );\n\n\t/**\n\t * Set which post types are allowed\n\t *\n\t * @since 0.9.4\n\t *\n\t * @param array $allowed_post_types Array of names (not labels) of allowed post types. Must be registered.\n\t */\n\t$allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', array( 'post') );\n\t$allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types );\n\tforeach( $post_types as $name => $label ) {\n\t\tif ( ! in_array( $name, $allowed_post_types ) ) {\n\t\t\tunset( $post_types[ $name ] );\n\t\t}\n\t}\n\treturn $post_types;\n}\n\nfunction lasso_post_types_rest_base() {\n\tglobal $wp_post_types;\n\t$post_types = lasso_post_types();\n\t$rest_base = array();\n\tforeach ( $post_types as $post_type) {\n\t\t$rest_base[$post_type] = $wp_post_types[$post_type]->rest_base;\n\t}\n    \n\treturn $rest_base;\n}\n\n////////////////////\n// INTERNAL\n////////////////////\n/**\n*\tUsed internally as a callback to build a tab or content area for modal addons\n*\n*\t@param $tab object\n*\t@param $type string tab or content\n*\t@uses lasso_modal_addons()\n*\t@since 0.9.4\n*/\nfunction lasso_modal_addons_content( $tab = '', $type ){\n\n\t$name = lasso_clean_string( $tab['name'] );\n\n\tif ( 'tab' == $type ) {\n\n\t\t$out = sprintf( '<li data-addon-name=\"%s\">%s</li>', $name, $tab['name'] );\n\n\t} else if ( 'content' == $type ){\n\n\t\t$content = isset( $tab['content'] ) && is_callable( $tab['content'] ) ? call_user_func( $tab['content'] ) : false;\n\t\t$options = isset( $tab['options'] ) && is_callable( $tab['options'] ) ? call_user_func( $tab['options'] ) : false;\n\n\t\t$out = sprintf( '<div class=\"lasso--modal__content not-visible\" data-addon-content=\"%s\">\n\t\t\t%s%s\n\t\t\t</div>', $name, $content, lasso_option_form( $name, $options ) );\n\n\t}\n\n\treturn $out;\n}\n\n/**\n*\tHelper function to clean a string and replace spaces with dash\n*\n*\t@param $string string content\n*\t@since 0.9.4\n*\n* @return void|string\n*/\nfunction lasso_clean_string( $string = '' ) {\n\n\tif ( empty( $string ) )\n\t\treturn;\n\n\treturn sanitize_text_field( strtolower( preg_replace('/[\\s_]/', '-', $string ) ) );\n}\n\n/**\n *\tHelper function to switch - to _ after having.\n *\n * This is the evil twin of lasso_clean_string() and may or may not make your data forever unclean.\n *\n *\t@param $string string content\n *\t@since 0.9.5\n *\n * @return void|string\n */\nfunction lasso_unclean_string( $string = '' ) {\n\n\tif ( empty( $string ) ) {\n\t\treturn;\n\t}\n\n\treturn sanitize_text_field( strtolower( str_replace( '-', '_', $string ) ) );\n}\n\n\n////////////////////\n// PLUGGABLE\n////////////////////\n\n/**\n * Check if the user is logged in and has the correctly passed capability\n *\n * @param unknown $action string a capability such as edit_posts or publish_posts\n * @param unknown $postid int the id of the post object to check against\n * @since 0.9.9.7 added filter 'lasso_user_can_filter'\n */\nif ( !function_exists( 'lasso_user_can' ) ):\n\tfunction lasso_user_can( $action = '', $postid = 0 ) {\n        $result = false;\n\t\tif ( empty( $action ) )\n\t\t\t$action = 'edit_posts';\n\n\t\tif ( empty( $postid ) && $action != 'edit_posts' && $action != 'publish_posts' && $action != 'delete_posts')\n\t\t\t$postid = get_the_ID();\n\n\t\tif ( is_user_logged_in() && current_user_can( $action, $postid ) ) {\n\t\t\t// check against post types:\n\t\t\t$allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', array( 'post', 'page') );\n\t\t\t\n\t\t\tif (!current_user_can('edit_pages')) {\n\t\t\t\t$allowed_post_types = array_diff($allowed_post_types,array('page'));\n\t\t\t}\n\t\t\t\n            if (!empty($allowed_post_types) && !empty($postid)) {\n\t\t\t\t$type = get_post_type( $postid );\n                $allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types );\n\t\t\t\t\n                if ( in_array( $type, $allowed_post_types ) ) {\n\t\t\t\t   $result =  true;\n\t\t\t    }\n            } else {\n                //we are not checking against a post, return true\n\t\t\t\t$result =  true;\n        \t}\n\t\t} else {\n\t\t\t$result = false;\n\t\t}\n\t\t//if ( function_exists( 'is_gutenberg_page' ) && has_blocks() ) return false;\n\t\t\n\t\treturn apply_filters( 'lasso_user_can_filter', $result,  $action, $postid);\n\t}\nendif;\n\n/**\n*\tEmpty state message thats shown when no data available\n*\n*\t@since 0.9.5\n*/\nif ( !function_exists('lasso_editor_empty_results') ):\n\n\tfunction lasso_editor_empty_results( $type = 'posts' ){\n\n\t\tif ( 'posts' == $type ) {\n\n\t\t\t$string = apply_filters('lasso_empty_state_message', __('No posts to show', 'lasso') );\n\t\t\t$icon = 'lasso-icon-file-text2';\n\t\t\t$button = false;\n\n\t\t} elseif ( 'revision' == $type ) {\n\n\t\t\t$string = apply_filters('lasso_empty_state_message', __('No revisions found', 'lasso') );\n\t\t\t$icon = 'lasso-icon-history';\n\t\t\t$button = sprintf('<a href=\"#\" class=\"lasso--btn-secondary\" id=\"lasso--close-modal\">%s</a>', __('Close','lasso') );\n\n\t\t}\n\n\t\treturn sprintf('<div id=\"lasso--empty-state\" class=\"lasso--empty-state\"><i class=\"lasso--empty-state-icon lasso-icon %s\"></i><p>%s</p>%s</div>', $icon, $string, $button );\n\t}\n\nendif;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "public/includes/lasso.php",
    "content": "<?php\n/**\n * AH Editor\n *\n * @package   Lasso\n * @author    Nick Haskins <nick@aesopinteractive.com>\n * @license   GPL-2.0+\n * @link      http://aesopinteractive.com\n * @copyright 2015-2017 Aesopinteractive \n */\nnamespace lasso_public_facing;\n/**\n *\n *\n * @package Lasso\n * @author  Nick Haskins <nick@aesopinteractive.com>\n */\nclass lasso {\n\n\t/**\n\t *\n\t *\n\t * @since    0.0.1\n\t *\n\t * @var      string\n\t */\n\tprotected $plugin_slug = 'lasso';\n\n\t/**\n\t * Instance of this class.\n\t *\n\t * @since    0.0.1\n\t *\n\t * @var      object\n\t */\n\tprotected static $instance = null;\n\n\t/**\n\t *\n\t *\n\t * @since     0.0.1\n\t */\n\tprivate function __construct() {\n\n\t\trequire_once LASSO_DIR.'/public/includes/underscore-templates.php';\n\n\t\trequire_once LASSO_DIR.'/public/includes/editor-modules.php';\n\t\trequire_once LASSO_DIR.'/public/includes/helpers.php';\n\t\trequire_once LASSO_DIR.'/public/includes/editor-modules--gallery.php';\n\t\trequire_once LASSO_DIR.'/public/includes/components.php';\n\t\trequire_once LASSO_DIR.'/public/includes/option-engine.php';\n\t\trequire_once LASSO_DIR.'/public/includes/wrap-shortcodes.php';\n\n\t\t// Activate plugin when new blog is added\n\t\tadd_action( 'wpmu_new_blog', array( $this, 'activate_new_site' ) );\n\n\t\t// Load plugin text domain\n\t\tadd_action( 'init', array( $this, 'load_plugin_textdomain' ) );\n\t\t\n\t\tadd_action( 'wp_ajax_get_aesop_component',     array( $this, 'get_aesop_component' ) );\n\t\tadd_action( 'wp_ajax_editus_do_shortcode',     array( $this, 'editus_do_shortcode' ) );\n        add_action( 'wp_ajax_editus_do_block',     array( $this, 'editus_do_block' ) );\n\t\tadd_action( 'wp_ajax_editus_lock_post',     array( $this, 'editus_lock_post' ) );\n\t\tadd_action( 'wp_ajax_editus_unlock_post',     array( $this, 'editus_unlock_post' ) );\n\t\tadd_action( 'wp_ajax_editus_hide_tour',     array( $this, 'editus_hide_tour' ) );\n\t\tadd_action( 'wp_ajax_editus_set_post_setting',     array( $this, 'editus_set_post_setting' ) );\n\t\tadd_action( 'wp_ajax_editus_get_ase_options',     array( $this, 'get_ase_options' ) );\n\t\tadd_action( 'wp_ajax_editus_delete_post',     array( $this, 'delete_post' ) );\n\t\tadd_action( 'wp_ajax_editus_featured_img',     array( $this, 'set_featured_img' ) );\n\t\tadd_action( 'wp_ajax_editus_del_featured_img',     array( $this, 'del_featured_img' ) );\n        \n        add_action( 'wp_ajax_editus_publish_post',     array( $this, 'on_publish_post' ) );\n        \n        add_action( 'wp_ajax_editus_create_gallery',     array( $this, 'create_gallery' ) );\n        add_action( 'wp_ajax_editus_update_gallery',     array( $this, 'update_gallery' ) );\n\n\t\t// enable saving custom fields through REST API\n\t\tself::enable_metasave('post');\n\t\tself::enable_metasave('page');\n        \n        $default_post_types = apply_filters( 'lasso_allowed_post_types', array( 'post', 'page'));\n\t\t$allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor',  $default_post_types);\n        foreach ( $allowed_post_types  as $post_type ) {\n           self::enable_metasave($post_type);\n\t\t}\n\t\t//enqueue assets\n\t\tnew assets();\n\n\t}\n\n\t/**\n\t * Return the plugin slug.\n\t *\n\t * @since    0.0.1\n\t *\n\t * @return    Plugin slug variable.\n\t */\n\tpublic function get_plugin_slug() {\n\t\treturn $this->plugin_slug;\n\t}\n\n\t/**\n\t * Return an instance of this class.\n\t *\n\t * @since     0.0.1\n\t *\n\t * @return    object    A single instance of this class.\n\t */\n\tpublic static function get_instance() {\n\n\t\t// If the single instance hasn't been set, set it now.\n\t\tif ( null == self::$instance ) {\n\t\t\tself::$instance = new self;\n\t\t}\n\n\t\treturn self::$instance;\n\t}\n\n\t/**\n\t * Fired when the plugin is activated.\n\t *\n\t * @since    0.0.1\n\t *\n\t * @param boolean $network_wide True if WPMU superadmin uses\n\t *                                       \"Network Activate\" action, false if\n\t *                                       WPMU is disabled or plugin is\n\t *                                       activated on an individual blog.\n\t */\n\tpublic static function activate( $network_wide ) {\n\n\t\tif ( function_exists( 'is_multisite' ) && is_multisite() ) {\n\n\t\t\tif ( $network_wide  ) {\n\n\t\t\t\t// Get all blog ids\n\t\t\t\t$blog_ids = self::get_blog_ids();\n\n\t\t\t\tforeach ( $blog_ids as $blog_id ) {\n\n\t\t\t\t\tswitch_to_blog( $blog_id );\n\t\t\t\t\tself::single_activate();\n\t\t\t\t}\n\n\t\t\t\trestore_current_blog();\n\n\t\t\t} else {\n\t\t\t\tself::single_activate();\n\t\t\t}\n\n\t\t} else {\n\t\t\tself::single_activate();\n\t\t}\n\n\t}\n\n\t/**\n\t * Fired when the plugin is deactivated.\n\t *\n\t * @since    0.0.1\n\t *\n\t * @param boolean $network_wide True if WPMU superadmin uses\n\t *                                       \"Network Deactivate\" action, false if\n\t *                                       WPMU is disabled or plugin is\n\t *                                       deactivated on an individual blog.\n\t */\n\tpublic static function deactivate( $network_wide ) {\n\n\t\tif ( function_exists( 'is_multisite' ) && is_multisite() ) {\n\n\t\t\tif ( $network_wide ) {\n\n\t\t\t\t// Get all blog ids\n\t\t\t\t$blog_ids = self::get_blog_ids();\n\n\t\t\t\tforeach ( $blog_ids as $blog_id ) {\n\n\t\t\t\t\tswitch_to_blog( $blog_id );\n\t\t\t\t\tself::single_deactivate();\n\n\t\t\t\t}\n\n\t\t\t\trestore_current_blog();\n\n\t\t\t} else {\n\t\t\t\tself::single_deactivate();\n\t\t\t}\n\n\t\t} else {\n\t\t\tself::single_deactivate();\n\t\t}\n\n\t}\n\n\t/**\n\t * Fired when a new site is activated with a WPMU environment.\n\t *\n\t * @since    0.0.1\n\t *\n\t * @param int     $blog_id ID of the new blog.\n\t */\n\tpublic function activate_new_site( $blog_id ) {\n\n\t\tif ( 1 !== did_action( 'wpmu_new_blog' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch_to_blog( $blog_id );\n\t\tself::single_activate();\n\t\trestore_current_blog();\n\n\t}\n\n\t/**\n\t * Get all blog ids of blogs in the current network that are:\n\t * - not archived\n\t * - not spam\n\t * - not deleted\n\t *\n\t * @since    0.0.1\n\t *\n\t * @return   array|false    The blog ids, false if no matches.\n\t */\n\tprivate static function get_blog_ids() {\n\n\t\tglobal $wpdb;\n\n\t\t// get an array of blog ids\n\t\t$sql = \"SELECT blog_id FROM $wpdb->blogs\n\t\t\tWHERE archived = '0' AND spam = '0'\n\t\t\tAND deleted = '0'\";\n\n\t\treturn $wpdb->get_col( $sql );\n\n\t}\n\n\t/**\n\t * Fired for each blog when the plugin is activated.\n\t *\n\t * @since    0.0.1\n\t */\n\tprivate static function single_activate() {\n\n\t\t$curr_version = get_option( 'lasso_version' );\n\n\t\t// update upgraded from\n\t\tif ( $curr_version ) {\n\t\t\tupdate_option( 'lasso_updated_from', $curr_version );\n\t\t}\n\n\t\t// update lasso version option\n\t\tupdate_option( 'lasso_version', LASSO_VERSION );\n\n\t\t// set transietn for activation welcome\n\t\tset_transient( '_lasso_welcome_redirect', true, 30 );\n\n\n\t}\n\n\t/**\n\t * Fired for each blog when the plugin is deactivated.\n\t *\n\t * @since    0.0.1\n\t */\n\tprivate static function single_deactivate() {\n\t\t// @TODO: Define deactivation functionality here\n\t}\n\n\t/**\n\t * Load the plugin text domain for translation.\n\t *\n\t * @since    1.0.0\n\t */\n\tpublic function load_plugin_textdomain() {\n\n\t\t$domain = $this->plugin_slug;\n\t\t$locale = apply_filters( 'plugin_locale', get_locale(), $domain );\n\n\t\t$out = load_textdomain( $domain, trailingslashit( LASSO_DIR ). 'languages/' . $domain . '-' . $locale . '.mo' );\n\t}\n\t\n    // new ajax function to lock post for editing\n\tpublic function editus_lock_post()\n\t{\n\t\t$post_id= $_POST[\"postid\"];\n\t\t$locked = wp_check_post_lock($post_id);\n\t\t\n\t\tif (!$locked) {\n\t\t    wp_set_post_lock($post_id);\n\t\t\techo \"true\";\n\t\t} else {\n\t\t\t$user_info = get_userdata($locked);\n\t\t\techo _e( 'Post being edited by ', 'lasso' ).$user_info->first_name .  \" \" . $user_info->last_name;\n\t\t}\n\t\texit;\n\t}\n\t\n\tpublic function editus_unlock_post()\n\t{\n\t\t$post_id= $_POST[\"postid\"];\n\t\t$locked = wp_check_post_lock($post_id);\n        if (!$locked) {\n            delete_post_meta( $post_id, '_edit_lock');\n        }\n\t\techo \"true\";\n\t\t\n\t\texit;\n\t}\n\t\n\t// new ajax function to update tour setting\n\tpublic function editus_hide_tour()\n\t{\n\t\t$user_id = get_current_user_ID();\n\t\t\t\t\n\t\tupdate_user_meta( $user_id, 'lasso_hide_tour', true );\n\t\texit;\n\t}\n\t\n\tpublic function editus_set_post_setting()\n\t{\n\t\t$data = array();\n\t\tparse_str($_POST['data'], $data);\n\t\t\n\t\tif (!wp_verify_nonce( $data[ 'nonce' ], 'lasso-update-post-settings' )) {\n\t\t\twp_send_json_error();\n\t\t\texit;\n\t\t}\n\t\t\n\t\t$status = isset( $data['status'] ) ? $data['status'] : false;\n\t\t$postid = isset( $data['postid'] ) ? $data['postid'] : false;\n\t\t$slug   = isset( $data['story_slug'] ) ? $data['story_slug'] : false;\n        $excerpt   = isset( $data['excerpt'] ) ? $data['excerpt'] : false;\n\t\n\n\t\t$args = array(\n\t\t\t'ID'   \t\t\t=> (int) $postid,\n\t\t\t'post_name'  \t=> $slug,\n\t\t\t'post_status' \t=> $status,\n            'post_excerpt'  => wp_strip_all_tags($excerpt,true)\n\t\t);\n\t\t\n\t\t\n\n\t\twp_update_post( apply_filters( 'lasso_object_status_update_args', $args ) );\n\t\t\n\t\t// update categories\n\t\t$cats  = isset( $data['story_cats'] ) ? $data['story_cats'] : false;\n\t\t\n\t\tself::set_post_terms( $postid, $cats, 'category' );\n\t\t\n\t\t// update tags\n\t\t$tags = isset( $data['story_tags'] ) ? $data['story_tags'] : false;\n\t\tself::set_post_terms( $postid, $tags, 'post_tag' );\n\t\t\n\t\t// update custom taxonomy\n\t\t$custom_taxonomies = isset( $data['story_custom_taxonomies'] ) ? json_decode($data['story_custom_taxonomies']) : false;\n        \n\t\tforeach ($custom_taxonomies as $x => $x_value) {\n\t\t\tself::set_post_terms( $postid, $x_value, $x );\n\t\t}\n\t\t\n\t\t//update date\n\t\t$date  = isset( $data['post_date'] ) ? $data['post_date'] : false;\n\t\tself::set_date( $postid, $date );\n\t\t\n\t\tdo_action( 'lasso_post_updated', $postid, $slug, $status, get_current_user_ID() );\n\t\t$response= array(\n\t\t\t'link'   => get_permalink($postid). (($status=='publish') ? '' : '&preview=true')\n\t\t);\n\t\twp_send_json_success($response);\n\t\texit;\n\t}\n\t\n\tpublic static function enable_metasave($type)\n\t{\n\t\tregister_rest_field( $type, 'metadata', array(\n\t\t\t'get_callback' => function ( $data ) {\n\t\t\t\treturn get_post_meta( $data['id']);//, '', '' );\n\t\t\t}, \n\t\t\t'update_callback' => function( $data, $post ) {\n\t\t\t\tforeach ($data as $key => $value) {\n\t\t\t\t\tupdate_post_meta($post->ID, $key, $value);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t));\n\t}\n\t\n\tpublic function editus_do_shortcode()\n\t{\n\t\t\n\t\t$code= $_POST[\"code\"];\n\t\t$code = str_replace('\\\"', '\"', $code);\n\t\t\n\t\t$code_wrapped = lasso_wrap_shortcodes( $code);\n\t\t$out =  do_shortcode($code);\n\t\tif ($out != '') {\n\t\t\t$out =  do_shortcode($code_wrapped);\n\t\t\techo $out;\n\t\t\texit;\n\t\t}\n\t\t\n\t\t// do_shortcode didn't work. Try again using wp_embed\n\n\t\t/** @var \\WP_Embed $wp_embed */\n\t\tglobal $wp_embed;\n\t\t$wp_embed->post_ID = $_POST[\"ID\"];\n\t\t$out =$wp_embed->run_shortcode( $code_wrapped );\n\t\t\n\t\techo $out;\n\t\texit;\n\t}\n    \n    public function editus_do_block()\n\t{\n\t\t\n\t\t$code= $_POST[\"code\"];\n\n        $out = do_blocks( $code );\n\t\t\n\t\techo $out;\n\t\texit;\n\t}\n\t\n\tpublic function get_aesop_component()\n\t{\n\t\t\n\t\t\n\t\t$code= $_POST[\"code\"];\n\t\t$atts = array(\n\t\t );\n\t\tforeach ($_POST as $key => $value) {\n\t\t\tif ($key !=\"code\" && $key !=\"action\") {\n\t\t\t\t$atts[$key] = $value;\n\t\t\t}\n\t\t}\n\t\tif ($code == \"aesop_video\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-video.php');\n\t\t    echo aesop_video_shortcode($atts);\n\t\t}\n\t\telse if ($code == \"aesop_image\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-image.php');\n\t\t    echo aesop_image_shortcode($atts);\n\t\t}\n\t\telse if ($code == \"aesop_quote\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-quote.php');\n\t\t    echo aesop_quote_shortcode($atts);\n\t\t}\n\t\telse if ($code == \"aesop_parallax\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-parallax.php');\n\t\t    echo aesop_parallax_shortcode($atts);\n\t\t}\n\t\telse if ($code == \"aesop_character\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-character.php');\n\t\t    echo aesop_character_shortcode($atts);\n\t\t}\n\t\telse if ($code == \"aesop_collection\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-collections.php');\n\t\t    echo aesop_collection_shortcode($atts);\n\t\t}\n\t\telse if ($code == \"aesop_chapter\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-heading.php');\n\t\t    echo aesop_chapter_shortcode($atts);\n\t\t}\n\t\telse if ($code == \"aesop_content\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-cbox.php');\n\t\t    echo aesop_content_shortcode($atts, $atts['content_data']);\n\t\t}\n\t\telse if ($code == \"aesop_gallery\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-gallery.php');\n\t\t    echo do_shortcode( '[aesop_gallery id=\"'.$atts[\"id\"].'\"]');\n\t\t}\n\t\telse if ($code == \"aesop_audio\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-audio.php');\n\t\t    echo aesop_audio_shortcode($atts);\n\t\t}\n\t\telse if ($code == \"aesop_document\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-document.php');\n\t\t    echo aesop_document_shortcode($atts);\n\t\t}\n\t\telse if ($code == \"aesop_timeline_stop\") {\t\t\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-timeline.php');\n\t\t    echo aesop_timeline_stop_shortcode($atts);\n\t\t}\n        /*else if ($code == \"aesop_content\") {\n\t\t    require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-content.php');\n\t\t    echo aesop_content_shortcode($atts);\n\t\t}*/\n        else if ($code == \"aesop_wpimg\") {\n            self::wpimg($atts);\n\t\t}\n\t\telse if ($code == \"aesop_wpimg-block\") {\n            self::wpimg_block($atts);\n\t\t}\n\t\telse {\n\t\t\t$code = '['.$code.' ';\n\t\t\tforeach ($atts as $key => $value) {\n\t\t\t    $code = ''.$key.'=\"'.$value.'\" ';\n\t\t\t}\n\t\t\t$code = $code.']';\n\t\t\techo do_shortcode($code);\n\t\t}\n\t\techo '<p contenteditable=\"true\"><br></p>';\n\t\texit; \n\t}\n    \n    public static function wpimg($atts) {\n\n        echo '<figure data-component-type=\"wpimg\"';\n        \n        $extra = \"\";\n        \n        // try to use srcset and sizes on new WP installs\n\t\tif ( function_exists('wp_get_attachment_image_srcset') && $attachment_id = attachment_url_to_postid( $atts['img'] ) ) {\n\t\t\t$srcset = wp_get_attachment_image_srcset( $attachment_id, 'full' );\n\t\t\t$sizes = wp_get_attachment_image_sizes( $attachment_id, 'full' );\n            $extra = \"srcset='$srcset' sizes='$sizes' \";\n        }\n        if ($atts['align']==\"left\") {\n            $extra .= 'class=\"alignleft';\n        } else if ($atts['align']==\"right\") {\n            $extra .= 'class=\"alignright';\n        } else {\n            $extra .= 'class=\"aligncenter';\n        }\n        if ($atts['imgwidth'] || $atts['imgheight']) {\n            if ($atts['imgwidth']) {\n                $extra .= 'width:'. $atts['imgwidth'].';';\n            }\n            if ($atts['imgheight']) {\n                $extra .= 'height:'. $atts['imgheight'].';';\n            }\n            \n        }\n        $extra .= '\"';\n        \n        foreach ($atts as $key => $value) {\n\t\t\t echo ' data-'.$key.'=\"'.$value.'\"';\n\t\t}\n        //echo ' class=\"wp-image- lasso--wpimg__wrap lasso-component\">';\n        echo ' class=\"wp-caption lasso-component\">';\n        $hrefset = false;\n        if ($atts['link'] != '' && (!isset($atts['linkoption']) || $atts['linkoption']==\"url\" ))\n        {\n            echo '<a href=\"' . $atts['link'] . '\">';\n            $hrefset = true;\n        } else if (isset($atts['linkoption']) && $atts['linkoption'] == 'img' ) {\n            echo '<a href=\"' . $atts['img'] . '\">';\n            $hrefset = true;\n        }\n        echo '<img src=\"' . $atts['img'] . '\" alt=\"'. $atts['alt']  .  '\" '. $extra. '>';\n        if ($hrefset)\n        {\n            echo '</a>';\n        }\n        if ($atts['caption'])\n        {\n            echo '<figcaption class=\"wp-caption-text\">'.$atts['caption'].'</figcaption>';\n        }\n        echo '</figure>';\n        echo '<p><br></p>';\n        return;\n    }\n\t\n\tpublic static function wpimg_block($atts) {\n\t\t$imgextra = '';\n\t\tif (!empty($atts['id'])) {\n\t\t\t$imgextra = 'class=\"wp-image-'.$atts['id'].'\"';\n\t\t}\n        $figclass = 'aligncenter';\n        if ($atts['align']==\"left\") {\n            $figclass = 'alignleft';\n        } else if ($atts['align']==\"right\") {\n            $figclass = 'alignright';\n        } else {\n            $figclass = 'aligncenter';\n        }\n        \n        if ($atts['align']==\"left\" || $atts['align']==\"right\") {\n            echo '<div class=\"wp-block-image\" data-component-type=\"wpimg-block\">';\n            echo '<figure class=\"'.$figclass.' size-large\" contenteditable=\"false\">'; \n        } else {      \n            echo '<figure class=\"wp-block-image '.$figclass.' size-large\" contenteditable=\"false\">';  \n        }        \n        if (!empty($atts['link'])) {\n            echo '<a href=\"'.$atts['link'].'\">';\n        }        \n        echo '<img src=\"' . $atts['img'] . '\" alt=\"'. $atts['alt']  . '\"' . $imgextra . ' >';\n        if ($atts['caption'])\n        {\n            echo '<figcaption>'.$atts['caption'].'</figcaption>';\n        }\n        if (!empty($atts['link'])) {\n            echo '</a>';\n        }\n        echo '</figure>';\n        if ($atts['align']==\"left\" || $atts['align']==\"right\") {\n            echo '</div>';\n        }  \n        echo '<p><br></p>';\n        return;\n    }\n\t\n\t\n\tpublic function get_ase_options()\n\t{\n\t\t$blob = lasso_editor_options_blob();\n\t\t$code= $_POST[\"component\"];\n\t\techo $blob[$code];\n\t\texit; \n\t}\n\t\n\tpublic function delete_post( ) {\n\n\t\t$postid = isset( $_POST['postid'] ) ? $_POST['postid'] : false;\n\n\t\t// bail out if the current user can't publish posts\n\t\tif ( !lasso_user_can( 'delete_post', $postid ) )\n\t\t\treturn;\n\t\t\n\t\tif (!wp_verify_nonce( $_POST[ 'nonce' ], 'lasso_delete_post' )) {\n\t\t\twp_send_json_error();\n\t\t\texit;\n\t\t}\n\n\t\t$args = array(\n\t\t\t'ID'   \t\t\t=> (int) $postid,\n\t\t\t'post_status' \t=> 'trash'\n\t\t);\n\n\t\twp_update_post( apply_filters( 'lasso_object_deleted_args', $args ) );\n\n\t\tdo_action( 'lasso_object_deleted', $postid, get_current_user_ID() );\n\n\t\texit;\n\t}\n    \n    /* This function doesn't actually publish post, but should be called when a post is published */\n    public function on_publish_post( ) {\n\n\t\t$post_id = isset( $_POST['postid'] ) ? $_POST['postid'] : false;\n        \n        do_action( 'transition_post_status', 'publish', 'draft', get_post( $post_id ) );\n\n\t\texit;\n\t}\n\t\n\tpublic function set_featured_img( ) {\n\n\t\t$postid  \t= isset( $_POST['postid'] ) ? $_POST['postid'] : false;\n\t\t$image_id  \t= isset( $_POST['image_id'] ) ? absint( $_POST['image_id'] ) : false;\n\t\tif (!wp_verify_nonce( $_POST[ 'nonce' ], 'lasso_gallery' )) {\n\t\t\twp_send_json_error();\n\t\t\texit;\n\t\t}\t\n\n\t\tset_post_thumbnail( $postid, $image_id );\n\n\t\tdo_action( 'lasso_featured_image_set', $postid, $image_id, get_current_user_ID() );\n\n\t\texit;\n\t}\n\t\n\tpublic function del_featured_img( ) {\n\n\t\t$postid  = isset( $_POST['postid'] ) ? $_POST['postid'] : false;\n\t\tif (!wp_verify_nonce( $_POST[ 'nonce' ], 'lasso_gallery' )) {\n\t\t\twp_send_json_error();\n\t\t\texit;\n\t\t}\t\n\n\t\tdelete_post_thumbnail( $postid );\n\n\t\tdo_action( 'lasso_featured_image_deleted', $postid, get_current_user_ID() );\n\n\t\texit;\n\t}\n\t\n\t/*public function revision_get( ) {\n\t\t$args = array();\n\t\tif ( isset( $_POST[ 'limit' ] ) ) {\n\t\t\t$args[ 'posts_per_page' ] = $data[ 'limit' ];\n\t\t}else{\n\t\t\t$args[ 'posts_per_page' ] = 6; // we start at revision 0\n\t\t}\n\n\t\t$revisions = wp_get_post_revisions( $_POST[ 'postid' ], $args  );\n\t\tif ( is_array( $revisions )  && ! empty( $revisions )  ) {\n\t\t\tself::set_revisions( $data[ 'postid' ], $revisions );\n\t\t}\n\n\t\treturn self::$revisions;\n\t}*/\n\t\n\tpublic function set_post_terms( $postid, $value, $taxonomy ) {\n\t\tif( $value ) {\n\t\t\t$value = explode( ',', $value );\n\t\t\t$allow_new_category = lasso_editor_get_option( 'allow_new_category', 'lasso_editor' );\n\t\t\t\n\t\t\tif ($taxonomy =='category') {\n                // convert from names to category ids\n\t\t\t\t$cats = array();\n\t\t\t\tforeach ($value as $cat) {\n\t\t\t\t\t$cat_id = get_cat_ID($cat);\n\t\t\t\t\tif ($cat_id !=0) {\n\t\t\t\t\t\t$cats [] = $cat_id;\n\t\t\t\t\t} else if ($allow_new_category) {\n\t\t\t\t\t    $cats [] = wp_create_category($cat);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$value = $cats;\n\t\t\t}\n\t\n\t\t\t$result = wp_set_object_terms( $postid, $value, $taxonomy );\n\t\t}\n\t\telse  {\n\t\t\t//remove all terms from post\n\t\t\t$result = wp_set_object_terms( $postid, null, $taxonomy );\n\t\t}\n\n\t\tif ( ! is_wp_error( $result ) ) {\n\t\t\treturn true;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n    \n    public function create_gallery( ) {\n\n\t\t$postid  \t= isset( $_POST['postid'] ) ? $_POST['postid'] : false;\n        \n\t\tif (!wp_verify_nonce( $_POST[ 'nonce' ], 'lasso_gallery' )) {\n\t\t\twp_send_json_error();\n\t\t\texit;\n\t\t}\t\n\n\t\tif (  ! lasso_user_can( 'publish_posts' ) ) {\n\t\t\treturn false;\n\n\t\t}\n\n\t\t$gallery_ids = isset( $_POST['gallery_ids'] ) ? $_POST['gallery_ids'] : false;\n\n\t\t// bail if no gallery ids\n\t\tif ( empty( $gallery_ids ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t$type   \t\t = isset( $_POST['gallery_type'] ) ? $_POST['gallery_type'] : false;\n\t\t$edgallerytitle\t = isset( $_POST['edgallerytitle'] ) ? $_POST['edgallerytitle'] : $postid.'-'.rand();\n\n\t\t// insert a new gallery\n\t\t$args = array(\n\t\t\t'post_title'    => $edgallerytitle ,\n\t\t\t'post_status'   => 'publish',\n\t\t\t'post_type'     => 'ai_galleries'\n\t\t);\n\n\t\t$postid = wp_insert_post( apply_filters( 'lasso_insert_gallery_args', $args ) );\n\n\t\t// update gallery ids\n\t\tif ( $gallery_ids ) {\n\n\t\t\tupdate_post_meta( $postid, '_ase_gallery_images', $gallery_ids );\n\n\t\t}\n\n\t\t// update the gallery type\n\t\tif ( !empty( $type ) ) {\n\n\t\t\tupdate_post_meta( $postid, 'aesop_gallery_type', $type );\n\n\t\t}\n\n\t\tdo_action( 'lasso_gallery_published', $postid, $gallery_ids, get_current_user_ID() );\n\n\n\t\techo json_encode( array(\n\t\t\t'message' => 'gallery-created',\n\t\t\t'id' => $postid)\n\t\t);\n        exit;\n\t}\n    \n    public function update_gallery( ) {\n        \n\t\t$options      = isset( $_POST['fields'] ) ? $_POST['fields'] : false;\n        \n\t\t$postid   \t  = !empty( $options ) ? (int) $options['id'] : false;\n\t\t$gallery_ids  = isset( $_POST['gallery_ids'] ) ? $_POST['gallery_ids'] : false;\n\t\tif ( $_POST[ 'gallery_type' ] ) {\n\t\t\t$type = $_POST[ 'gallery_type' ];\n\t\t}elseif ( ! empty( $options ) && $options[ 'galleryType' ] ) {\n\t\t\t$type = $options[ 'galleryType' ];\n\t\t}else{\n\t\t\t$type = false;\n\t\t}\n\n\t\tself::save_gallery_options( $postid, $gallery_ids, $options, $type );\n\n        echo json_encode( array('message' => 'gallery-updated') );\n\n        exit;\n\t}\n    \n    public function save_gallery_options( $postid, $gallery_ids, $options, $type = false ) {\n\n\t\t// gallery width\n\t\t$gallery_width = isset( $options['width'] ) ? $options['width'] : false;\n\n\t\t// gallery grid item width\n\t\t$item_width = isset( $options['itemwidth'] ) ? $options['itemwidth'] : false;\n\n\t\t// caption\n\t\t$caption = isset( $options['caption'] ) ? $options['caption'] : false;\n\n\t\t// gallery transition\n\t\t$transition = isset( $options['transition'] ) ? $options['transition'] : false;\n\n\t\t// gallery transition speed\n\t\t$transitionSpeed = isset( $options['speed'] ) ? $options['speed'] : false;\n\n\t\t// gallery hide thumbs\n\t\t$hideThumbs = isset( $options['hideThumbs'] ) ? $options['hideThumbs'] : false;\n\n\t\t// photoset layout hardwired to on for now\n\t\t$psLayout = isset( $options['pslayout'] ) ? $options['pslayout'] : false;\n\n\t\t// photoset layout\n\t\t$psLightbox = 'on';//isset( $options['pslightbox'] ) ? $options['pslightbox'] : false;\n\t\t\n\t\t// hero gallery height\n\t\t$gallery_height = isset( $options['height'] ) ? $options['height'] : false;\n\n\t\t// update gallery ids\n\t\tif ( !empty( $gallery_ids ) ) {\n\n\t\t\tupdate_post_meta( $postid, '_ase_gallery_images', $gallery_ids );\n\n\t\t}\n\n\t\tupdate_post_meta( $postid, 'aesop_gallery_type', sanitize_text_field( trim( $type ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_gallery_width', sanitize_text_field( trim( $gallery_width ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_grid_gallery_width', sanitize_text_field( trim( $item_width ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_gallery_caption', sanitize_text_field( trim( $caption ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_thumb_gallery_transition', sanitize_text_field( trim( $transition ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_thumb_gallery_transition_speed', absint( trim( $transitionSpeed ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_thumb_gallery_hide_thumbs', sanitize_text_field( trim( $hideThumbs ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_photoset_gallery_layout', sanitize_text_field( trim( $psLayout ) ) );\n\n\t\tupdate_post_meta( $postid, 'aesop_photoset_gallery_lightbox', sanitize_text_field( trim( $psLightbox ) ) );\n\t\t\n\t\tupdate_post_meta( $postid, 'aesop_hero_gallery_height', sanitize_text_field( trim( $gallery_height ) ) );\n\t\t\n\t\t//hardwired for now\n\t\t\n\t\tupdate_post_meta( $postid, 'aesop_hero_gallery_transition_speed', 300 );\n\n\t}\n\t\n\tfunction getEnglishMonthName($foreignMonthName){\n\n\t\t  setlocale(LC_ALL, 'en_US');\n\n\t\t  $month_numbers = range(1,12);\n\n\t\t  foreach($month_numbers as $month)\n\t\t\t$english_months[] = strftime('%B',mktime(0,0,0,$month,1,2011));\n\n\t\t  setlocale(LC_ALL, get_locale());\n\n\t\t  foreach($month_numbers as $month)\n\t\t\t$foreign_months[] = utf8_encode(strftime('%B',mktime(0,0,0,$month,1,2011)));\n\n\t\t  return str_replace($foreign_months, $english_months, $foreignMonthName);\n\t}\n\n\n\t\n\tpublic function set_date( $postid, $value) {\n\t\tif( $value ) {\n\t\t\t$value = self::getEnglishMonthName($value).\" \".date(\"H:i:s\", current_time( 'timestamp', 1 ));\n            wp_update_post(\n\t\t\t\tarray (\n\t\t\t\t\t'ID'            => $postid, // ID of the post to update\n\t\t\t\t\t'post_date'     => date( 'Y-m-d H:i:s',  strtotime($value) ),\n\t\t\t\t\t'post_date_gmt'     => gmdate( 'Y-m-d H:i:s',  strtotime($value) ),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "public/includes/option-engine.php",
    "content": "<?php\n/**\n*\tThis is used by addons to add cool stuff to the settings modal as an additional tab\n*\n*\tExample:\n*\tadd_filter('lasso_modal_tabs', 'try_tabs');\n*\tfunction try_tabs( $tabs ){\n*\t\t$tabs[] = array(\n*\t  \t\t'name' \t=> 'Tab',\n*\t  \t\t'content' => 'mytestcallback',\n*\t  \t\t'options'\t=> 'myOptionsCallback'\n*\t\t);\n*\n*\t\treturn $tabs;\n*\t}\n*\tfunction myOptionsCallback(){\n*\n*\t\t$options = array(\n*\t\t\tarray(\n*\t\t\t\t'id'\t\t=> 'title',\n*\t\t\t\t'name' \t\t=> 'Title',\n*\t\t\t\t'type'\t\t=> 'text',\n*\t\t\t\t'default'\t=> 'default',\n*\t\t\t\t'desc'\t\t=> 'Cool'\n*\t\t\t),\n*\t\t\tarray(\n*\t\t\t\t'id'\t\t=> 'another',\n*\t\t\t\t'name' \t\t=> 'Another',\n*\t\t\t\t'type'\t\t=> 'textarea',\n*\t\t\t\t'default'\t=> 'default',\n*\t\t\t\t'desc'\t\t=> 'Awesome'\n*\t\t\t)\n*\t\t);\n*\n*\t\treturn $options;\n*\n*\t}\n*\n*\t@since 0.9.4\n*/\n\n/**\n*\tGet an array of addon data for the settings modal\n*\t@since 0.9.4\n*/\nfunction lasso_get_modal_tabs(){\n\n\t$tabs = array();\n\n\treturn apply_filters('lasso_modal_tabs', $tabs);\n\n}\n\n/**\n*\tBuild a side tabs to fit alongside the post settings modal\n*\tThis is used by addons to add cool stuff to the settings modal as an additional tab\n*\n*\t@param $type string tab or content\n*\t@uses lasso_get_modal_tabs()\n*\t@uses lasso_modal_addons_content()\n*\t@since 0.9.4\n*/\nfunction lasso_modal_addons( $type = 'tab' ){\n\n\t$tabs = lasso_get_modal_tabs();\n\t$out = '';\n\n\tif ( $tabs ):\n\n\t\tif ( 'tab' == $type ) {\n\n\t\t\t$out = '<ul class=\"lasso--modal__tabs\">';\n\n\t\t\t\t$out .= '<li class=\"active-tab\" data-addon-name=\"core\">Editus</li>';\n\n\t\t\t\tforeach ( $tabs as $tab ) {\n\n\t\t\t\t\tif ( isset( $tab ) ) {\n\n\t\t\t\t\t\t$out .= lasso_modal_addons_content( $tab, $type );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t$out .= '</ul>';\n\n\t\t} elseif ( 'content' == $type ) {\n\t\t\tforeach ( $tabs as $tab ) {\n\n\t\t\t\tif ( isset( $tab ) ) {\n\t\t\t\t\t$out .= lasso_modal_addons_content( $tab , $type );\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\tendif;\n\n\treturn !empty( $out ) ? $out : false;\n}\n\n/**\n*\tBuild a post meta options form\n*\n*\t@param $name string the name of this tab being logged\n*\t@param $options array an array of option fields in the format below\n*\n*\t\t\t\t\tarray(\n*\t\t\t\t\t\t'id'\t\t=> 'title',\n*\t\t\t\t\t\t'name' \t\t=> 'Title',\n*\t\t\t\t\t\t'type'\t\t=> 'text',\n*\t\t\t\t\t\t'default'\t=> 'default',\n*\t\t\t\t\t\t'desc'\t\t=> 'My description'\n*\t\t\t\t\t)\n*\n*\t@since 0.9.5\n*\t@subpackage lasso_modal_addons_content\n*/\nfunction lasso_option_form( $name = '', $options = array() ){\n\n\tob_start();\n\n\tif ( empty( $name ) || empty( $options ) || !is_array( $options ) )\n\t\treturn;\n\n\t$nonce = wp_create_nonce('lasso-process-post-meta');\n\t$key   = sprintf('_lasso_%s_settings', $name );\n\n\t$out = sprintf('<form id=\"lasso--custom-field-form\" class=\"lasso--post-form\">' );\n\n\t\t$out .= lasso_option_fields( $name, $options );\n\t\t$out .='<div class=\"form--bottom\">';\n\t\t\t$out .='<input type=\"submit\" value=\"'.__( 'Save', 'lasso' ).'\">';\n\t\t\t$out .='<input type=\"hidden\" name=\"tab_name\" value=\"'.$key.'\">';\n\t\t\t$out .='<input type=\"hidden\" name=\"post_id\" value=\"'.get_the_ID().'\">';\n\t\t\t$out .='<input type=\"hidden\" name=\"nonce\" value=\"'.$nonce.'\">';\n\t\t\t$out .='<input type=\"hidden\" name=\"action\" value=\"process_meta_update\">';\n\t\t$out .='</div>';\n\n\t$out .= '</form>';\n\t\n\t$out .= \"<script>(function( $ ) {\n\t\t\t\t\t$(document).ready(function(){\n\t\t\t\t\t   \n\t\t\t\t\t\tfunction imgCustomTabDialog( ){\n                \t\t\tvar that = this;\n                \n                \t\t    // Create the media frame.\n                \t\t    var lasso_file_frame = wp.media.frames.file_frame = wp.media({\n                \t\t      \ttitle: 'Select Image',\n                \t\t      \tbutton: {\n                \t\t        \ttext: 'Insert Image',\n                \t\t      \t},\n                \t\t      \tmultiple: false  // Set to true to allow multiple files to be selected\n                \t\t    });\n                \n                \t\t    // When an image is selected, run a callback.\n                \t\t    lasso_file_frame.on( 'select', function() {\n                \t\t      \tvar attachment = lasso_file_frame.state().get('selection').first().toJSON();\n                \t\t        $(that).parent().find('input').val(attachment.url );\n                \t\t        $(that).parent().find('img').attr('src', attachment.url );\n                \n                \t\t    });\n                \n                \t\t    // Finally, open the modal\n                \t\t\tlasso_file_frame.open();\n                \t\t};\n\t\t\t\t\t\t\n\t\t\t\t\t\tfunction imgCustomTabRemove( ){\n                \t\t    $(this).parent().find('input').val('');\n                \t\t    $(this).parent().find('img').attr('src', '' );\n                \t\t};\n                \t\t\n                \t\tjQuery('.editus-customtab-image-control').mousedown(imgCustomTabDialog);\n\t\t\t\t\t\tjQuery('.editus-customtab-image-remove').mousedown(imgCustomTabRemove);\n\t\t\t\t\t});\n\t\t\t\t})( jQuery );\n\t        \n    \t\t\n    \t\t</script>\";\n\n\techo $out;\n\n\treturn ob_get_clean();\n\n}\n\n/**\n*\tBuild settings fields for lasso_option_form\n*\n*\t@param $name string the name of this tab being logged\n*\t@param $options array an array of option fields in the format above\n*\t@since 0.9.5\n*\t@subpackage lasso_modal_addons_content\n*/\nfunction lasso_option_fields( $name = '', $options = array() ){\n\n\t$out \t= '';\n\t$before = '<div class=\"lasso--postsettings__option\">';\n\t$after \t= '</div>';\n\n\tif ( empty( $name ) || empty( $options ) )\n\t\treturn;\n\n\tforeach ( (array) $options as $option ) {\n\n\t\t$type = isset( $option['type'] ) ? $option['type'] : 'text';\n\t\t\n\t\t$out .= sprintf('%s%s%s', $before, lasso_option_engine_option( $name, $option,$type ), $after );\n\n\t}\n\t\n\t\n\n\treturn $out;\n}\n\n\n/**\n*\tBuild settings inputs for settings fields\n*\n*\t@param $name\n*\t@param $option mixed object\n*\t@param $type string text, textarea, checkbox, color\n*\t@since 5.0\n*/\nfunction lasso_option_engine_option( $name = '', $option = '', $type = '') {\n\n\tif ( empty( $type ) || empty( $option ) )\n\t\treturn;\n\n\t$id = isset( $option['id'] ) ? $option['id'] : false;\n\t//$id = $id ? lasso_clean_string( $id ) : false;\n\n\t$desc = isset( $option['desc'] ) ? $option['desc'] : false;\n\n\t$value = get_post_meta( get_the_id(), $option[ 'id' ], true );\n\n\tswitch ( $type ) {\n\t\tcase 'text':\n\t\t\t$out = sprintf('<label for=\"lasso--post-option-%s\">%s</label><input id=\"lasso--post-option-%s\" class=\"editus-custom-field-text\" name=\"%s\" type=\"text\" value=\"%s\">',$id, esc_html( $desc ), $id, $id, $value );\n\t\t\tbreak;\n\t\tcase 'textarea':\n\t\t\t$out = sprintf('<label for=\"lasso--post-option-%s\">%s</label><textarea id=\"lasso--post-option-%s\" name=\"%s\">%s</textarea>',$id, esc_html( $desc ), $id, $id, $value );\n\t\t\tbreak;\n\t\tcase 'imgurl':\n\t\t\t$out = sprintf('<label for=\"lasso--post-option-%s\">%s</label><img src=\"%s\" style=\"height:80px;\"><input id=\"lasso--post-option-%s\" class=\"editus-custom-field-text\" name=\"%s\" type=\"text\" value=\"%s\" style=\"display:none;\"><div title=\"Replace Image\"  class=\"editus-customtab-image-control\" style=\"float:left;\"><i class=\"lasso-icon-image\" style=\"font-size:20px;padding:5px;\"></i></div><div title=\"Remove Image\"  class=\"editus-customtab-image-remove\" style=\"float:left;\"><i class=\"lasso-icon-bin2\" style=\"font-size:20px;padding:5px;\"></i></div>',$id, esc_html( $desc ), $value, $id, $id,  $value );\n\t\t\tbreak;\n\t\tcase 'checkbox':\n\t\t\t$out = sprintf('<label for=\"lasso--post-option-%s\" class=\"checkbox-control checkbox\"><input id=\"lasso--post-option-%s\" type=\"checkbox\" name=\"%s\" class=\"checkbox\"><span class=\"control-indicator\"></span>%s',$id, $id, $id ,esc_html( $desc ) );\n\t\t\tbreak;\n\t\tcase 'dropdown':\n\t\t\t$out = sprintf('<label for=\"lasso--post-option-%s\">%s</label><select id=\"lasso--post-option-%s\" name=\"%s\">',$id, esc_html( $desc ), $id, $id);\n\t\t\t$options = explode(\";\", $option['options']);\n\t\t\tforeach ($options as &$opt) {\n\t\t\t\t$opts = explode(\":\", $opt);\n\t\t\t\tif ($opts[0] == $value) {\n\t\t\t\t\t$out .= sprintf('<option value = \"%s\" selected>%s</option>',$opts[0], $opts[1]);\n\t\t\t\t} else {\n\t\t\t\t\t$out .= sprintf('<option value = \"%s\">%s</option>',$opts[0], $opts[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t$out .='</select>';\n\t\t\tbreak;\n\t}\n\n\treturn $out;\n\n}\n\n"
  },
  {
    "path": "public/includes/register_meta_field.php",
    "content": "<?php\n/**\n * Helper class for registering meta fields to work with Editus Options API\n */\n\nnamespace lasso_public_facing;\n\n\nclass register_meta_field {\n\n\t/**\n\t * Constructor for class.\n\t *\n\t * Pass an array of field_name => sanatization_callback\n\t *\n\t * @param array $fields\n\t */\n\tpublic function __construct( $fields ) {\n\t\t$this->fields = $fields;\n\t\tadd_filter( 'lasso_api_params', function( $params ) {\n\t\t\tforeach( $this->fields as $field => $cbs ) {\n\t\t\t\t//$field = lasso_clean_string( $field );\n\t\t\t\t$params[ 'process_meta_update' ][ $field ] = $cbs;\n\t\t\t}\n\n\t\t\treturn $params;\n\n\t\t});\n\n\t\tadd_filter( 'lasso_meta_fields', function( $allowed ) {\n\n\t\t\tforeach( array_keys( $this->fields ) as $field  ) {\n\t\t\t\t//$field = lasso_clean_string( $field );\n\t\t\t\t$allowed[] = $field;\n\n\t\t\t}\n\t\t\treturn $allowed;\n\t\t});\n\n\t}\n\n}\n"
  },
  {
    "path": "public/includes/tour.php",
    "content": "<?php\n/**\n * Class responsible for creating the welcome walkthrough on the editor\n *\n * @since 0.6\n */\n\nnamespace lasso_public_facing;\n\nclass tour {\n\n\tpublic function __construct() {\n\n\t    $disable_tour = lasso_editor_get_option('disable_tour', 'lasso_editor');\n\t\tif (!$disable_tour) {\n\t\t    add_action( 'wp_footer',       array( $this, 'draw_tour' ) );\n\t\t}\n\t}\n\n\t/**\n\t*\tDraw the modal used to house the walk through\n\t*\t@since 0.6\n\t*/\n\tpublic function draw_tour() {\n\n\t\t$tour_hidden = get_user_meta( get_current_user_ID(), 'lasso_hide_tour', true );\n\n\t\tif ( lasso_user_can() && !$tour_hidden ) {\n\n\t\t\tglobal $post;\n\n\t\t\t$nonce = wp_create_nonce( 'lasso-editor-tour' );\n\n\t\t\t// let users add custom css classes\n\t\t\t$custom_classes = apply_filters( 'lasso_modal_tour_classes', '' );\n\n\t\t\t?>\n\t\t\t<div id=\"lasso--tour__modal\" class=\"lasso--modal lasso--tour__modal lasso--modal__checkbox <?php echo sanitize_html_class( $custom_classes );?>\">\n\t\t\t    <script>\n\t\t\t\t(function( $ ) {\n\t\t\t\t\t$(document).ready(function(){\n\t\t\t\t\t\tjQuery(document).on('click','#editus_tour_submit', function(e){\n\t\t\t\t\t\t\tif ($('#hide_tour').prop('checked')) {\n\t\t\t\t\t\t\t\tvar data = {\n\t\t\t\t\t\t\t\t\t\taction: 'editus_hide_tour'\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tjQuery.post(lasso_editor.ajaxurl2, data, function(response) {\n\t\t\t\t\t\t\t\t\t    \n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t})( jQuery );\n\t\t\t\t</script>\n\t\t\t\t<div class=\"lasso--modal__inner\">\n\n\t\t\t\t\t<?php echo self::tour_slides();?>\n\n\t\t\t\t\t<div class=\"lasso--postsettings__footer\">\n\n\t\t\t\t\t\t<div class=\"lasso--postsettings__option\">\n\t\t\t\t\t\t\t<label for=\"hide_tour\" class=\"checkbox-control checkbox\">\n\t\t\t\t\t        \t<input type=\"checkbox\" id=\"hide_tour\" name=\"hide_tour\" <?php checked( $tour_hidden, 1 ); ?>>\n\t\t\t\t\t        \t<span class=\"control-indicator\"></span>\n\t\t\t\t\t\t\t\t<?php _e('Don\\'t show this again','lasso');?>\n\t\t\t\t\t        </label>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<input id =\"editus_tour_submit\" type=\"submit\" value=\"<?php _e( 'Okay, got it!', 'lasso' );?>\" data-nonce=\"<?php echo $nonce;?>\" >\n\t\t\t\t\t</div>\n\n\t\t\t\t</div>\n\n\t\t\t</div>\n\t\t\t<div id=\"lasso--modal__overlay\"></div>\n\t\t\t<?php\n\n\t\t}\n\t}\n\n\t/**\n\t*\tDraw the inner slides for the welcome walkthrough\n\t*\t@since 0.6\n\t*/\n\tpublic function tour_slides() { ?>\n\n\t\t<div id=\"lasso--loading\" class=\"lasso--loading\"><div class=\"lasso--loader\"></div></div>\n\t\t<div id=\"lasso--tour__slides\">\n\n\t\t\t<?php\n\n\t\t\t$out = '<ul><li>';\n\t\t\t$out .= sprintf( '<img src=\"%s\">', LASSO_URL.'/public/assets/img/s-1.jpg' );\n\t\t\t$out .= '<p>'.__('Access posts by clicking the list icon. Create a new post by clicking the new post icon.','lasso').'</p>';\n\t\t\t$out .= '</li><li>';\n\t\t\t$out .= sprintf( '<img src=\"%s\">', LASSO_URL.'/public/assets/img/s-2.jpg' );\n\t\t\t$out .= '<p>'.__('While on a single post, edit by clicking the Pen icon. Access post settings with the settings icon. Press escape to exit any modal.','lasso').'</p>';\n\t\t\t$out .= '</li><li>';\n\t\t\t$out .= sprintf( '<img src=\"%s\">', LASSO_URL.'/public/assets/img/s-3.jpg' );\n\t\t\t$out .= '<p>'.__('Highlight a piece of text, and click on a formatting option to style it. Click the Disk icon or CMD-S to save. Click the orange \"X\" button to exit the editor.','lasso').'</p>';\n\t\t\t$out .= '</li><li>';\n\t\t\t$out .= sprintf( '<img src=\"%s\">', LASSO_URL.'/public/assets/img/s-4.jpg' );\n\t\t\t$out .= '<p>'.__('Story components can be added by clicking the plus icon, and dragging any component from the component tray into the story.','lasso').'</p>';\n\t\t\t$out .= '</li></ul>';\n\n\t\t\techo apply_filters( 'lasso_tour_slides', $out );\n\n\t\t?></div><?php\n\n\t}\n\n}\n"
  },
  {
    "path": "public/includes/underscore-templates.php",
    "content": "<?php\n\nif ( !function_exists( 'lasso_backbone_templates' ) ):\n\n\tadd_action('wp_footer', 'lasso_backbone_templates');\n\tfunction lasso_backbone_templates(){\n\n\t\t$can_delete = lasso_user_can('delete_posts');\n\t\t$can_delete_class = $can_delete ? false : 'no-delete';\n\n\t\t\n\t\t// only run on posts and pages if user is logged in\n\t\tif ( is_user_logged_in() && lasso_user_can('edit_posts') ) { \n\t\t    if ( !class_exists( 'WP_REST_Controller' ) ) {\n\t\t\t    // using rest api v1 \n\t\t\t\t?>\n\t\t\t\t<script type=\"text/html\" id=\"lasso-tmpl--post\">\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"<%= post.link %>\" class=\"lasso--post-list__item <?php echo $can_delete_class;?> <%= post.status %>\" data-postid=\"<%= post.ID %>\" >\n\t\t\t\t\t\t\t<%= post.title %>\n\n\t\t\t\t\t\t\t<div class=\"lasso--post-list__controls\">\n\t\t\t\t\t\t\t\t<span title=\"<?php echo esc_attr_e('Edit Post','lasso');?>\" id=\"lasso--post__edit\"></span>\n\t\t\t\t\t\t\t\t<?php if( $can_delete ): ?>\n\t\t\t\t\t\t\t\t<span title=\"<?php echo esc_attr_e('Delete Post','lasso');?>\" id=\"lasso--post__delete\"></span>\n\t\t\t\t\t\t\t\t<?php endif; ?>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</script>\n\t\t\t<?php\n\t\t\t} else {\n\t\t\t\t// using rest api v2 \n\t\t    ?>\n\t\t\t\t<script type=\"text/html\" id=\"lasso-tmpl--post\">\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"<%= post.link %>\" class=\"lasso--post-list__item <?php echo $can_delete_class;?> <%= post.status %>\" data-postid=\"<%= post.id %>\" >\n\t\t\t\t\t\t\t<%= post.title.rendered %>\n\n\t\t\t\t\t\t\t<div class=\"lasso--post-list__controls\">\n\t\t\t\t\t\t\t\t<span title=\"<?php echo esc_attr_e('Edit Post','lasso');?>\" id=\"lasso--post__edit\"></span>\n\t\t\t\t\t\t\t\t<?php if( $can_delete ): ?>\n\t\t\t\t\t\t\t\t<span title=\"<?php echo esc_attr_e('Delete Post','lasso');?>\" id=\"lasso--post__delete\"></span>\n\t\t\t\t\t\t\t\t<?php endif; ?>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</script>\n\t\t<?php \n\t\t    }\n\t\t}\n\n\t}\n\nendif;"
  },
  {
    "path": "public/includes/wrap-shortcodes.php",
    "content": "<?php\n/**\n * Wraps shortcodes of other Plugins in prep for later replacement on save to preserve the shortcodes\n */\n\n\n\n \nif ( lasso_user_can( 'edit_posts' ) && ! is_admin() ) {\n\tadd_filter( 'the_content', 'lasso_wrap_shortcodes', 1 );\n}\n\n/**\n * Parses the_content and wraps uses preg_replace_callback to wrap shortcodes in HTML Comments.\n * Mostly copied from do_shortcode function.\n *\n * @since 0.9.9\n *\n * @param string $content\n *\n * @return string\n */\nfunction lasso_wrap_shortcodes( $content ) {\n\tglobal $shortcode_tags;\n\n    $no_wrap_shortcode    = lasso_editor_get_option( 'no_wrap_shortcode', 'lasso_editor');\n\n    if ($no_wrap_shortcode == 'on') {\n        return $content;\n    }\n\n\tif ( false === strpos( $content, '[' ) ) {\n\t\treturn $content;\n\t}\n\n\tif ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) {\n\t\treturn $content;\n\t}\n\n\t$tagnames  = array_keys( $shortcode_tags );\n\t$tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) );\n\t$pattern   = \"/\\\\[($tagregexp)/s\";\n\n\tif ( 0 === preg_match( $pattern, $content ) ) {\n\t\t// Avoids parsing HTML when there are no shortcodes or embeds anyway.\n\t\treturn $content;\n\t}\n\n\t$content = do_shortcodes_in_html_tags( $content, true ,$tagnames);\n\n\t$pattern = get_shortcode_regex();\n\t$content = preg_replace_callback( \"/$pattern/s\", 'lasso_wrap_shortcode_tag', $content );\n\n\t// Always restore square braces so we don't break things like <!--[if IE ]>\n\t$content = unescape_invalid_shortcodes( $content );\n\n\treturn $content;\n}\n\n/**\n * Callback for preg_replace_callback in lasso_wrap_shortcodes. Returns shortcode wrapped in HTML Comments.\n *\n * @since 0.9.9\n *\n * @param array $m\n *\n * @return string\n */\nfunction lasso_wrap_shortcode_tag( $m ) {\n\t// allow [[foo]] syntax for escaping a tag\n\tif ( $m[1] == '[' && $m[6] == ']' ) {\n\t\treturn substr( $m[0], 1, - 1 );\n\t}\n\t$exception_arr1 = array('aesop_gallery_pop','aesop_character_carousel');\n\t$exception_arr2 = array('su_box', 'su_note', 'su_document', 'su_spoiler','av_textblock','av_toggle_container','av_toggle');\n\t$exception_arr2 = apply_filters('lasso_wrap_shortcode_exceptions',$exception_arr2);\n\n\tif ( strpos( $m[2],'aesop_'  ) === 0 ) {\n\t\t// check against the exceptions\n\t\tif (strpos_arr($m[2],$exception_arr1)===false) {\n\t\t    return $m[0];\n\t\t}\n\t}\n\tif (strpos_arr($m[2],$exception_arr2)!==false) {\n\t\treturn $m[0];\n\t}\n\n\treturn '<!--EDITUS_OTHER_SHORTCODE_START|[' . $m[0] . ']-->' . $m[0] . '<!--EDITUS_OTHER_SHORTCODE_END-->';\n}\n\n/* a helper function */\nfunction strpos_arr($haystack, $needle) {\n    if(!is_array($needle)) $needle = array($needle);\n    foreach($needle as $what) {\n        if(($pos = strpos($haystack, $what))!==false) return $pos;\n    }\n    return false;\n}"
  },
  {
    "path": "uninstall.php",
    "content": "<?php\n/**\n * Fired when the plugin is uninstalled.\n *\n * @package   Lasso\n * @author    Nick Haskins <nick@aesopinteractive.com>\n * @license   GPL-2.0+\n * @link      http://aesopinteractive.com\n * @copyright 2015 Aesopinteractive LLC\n */\n\n// If uninstall not called from WordPress, then exit\nif ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {\n\texit;\n}\n\ndelete_option('lasso_license_status');\ndelete_option('lasso_editor');\ndelete_option('lasso_updated_from');\ndelete_option('lasso_version');\n"
  }
]