[
  {
    "path": ".circleci/config.yml",
    "content": "# Ruby CircleCI 2.0 configuration file\n#\n# Check https://circleci.com/docs/2.0/language-ruby/ for more details\n#\nversion: 2\n\ngeneral:\n  artifacts:\n    - coverage/${CIRCLE_PROJECT_REPONAME}_test/index.html\n\njobs:\n  build:\n    docker:\n      # specify the version you desire here (ruby 2.6.x)\n      - image: circleci/ruby:2.6-browsers-legacy\n    steps:\n      - checkout\n  test:\n    docker:\n      # specify the version you desire here\n      - image: circleci/ruby:2.6-browsers-legacy\n        environment:\n          RAILS_ENV: test\n          DB_HOST: 127.0.0.1\n          DRIVER: headless\n          TZ: /usr/share/zoneinfo/Asia/Tokyo\n      - image: mysql:5.7\n        command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_bin --innodb-large-prefix=true --innodb-file-format=Barracuda --sql-mode=\"\"\n        environment:\n          MYSQL_USER: root\n          MYSQL_ALLOW_EMPTY_PASSWORD: yes\n\n    working_directory: ~/repo\n    steps:\n      - checkout\n      - run:\n          name: ready for redmine\n          command: |\n            REDMINE_BRANCH=master sh script/circleci-setup.sh\n      - run: perl -pi -e \"s/gem \\\"capybara\\\".*$/gem \\\"capybara\\\"/g\" Gemfile\n      - run: bundle install --path vendor/bundle --without postgresql rmagick && bundle update\n      - run: bundle exec rails g rspec:install\n      - run: bundle exec rake db:create RAILS_ENV=test\n      - run: bundle exec rake db:migrate RAILS_ENV=test\n      - run: bundle exec rake redmine:plugins:migrate RAILS_ENV=test\n      - run:\n          command: |\n            bundle exec rake ${CIRCLE_PROJECT_REPONAME}:test RAILS_ENV=test\n      - run:\n          command: |\n            bundle exec rspec -I plugins/redmine_issue_templates/spec --format documentation plugins/redmine_issue_templates/spec/models/\n      - run:\n          command: |\n            bundle exec rspec -I plugins/redmine_issue_templates/spec --format documentation plugins/redmine_issue_templates/spec/helpers/\n      - run:\n          command: |\n            bundle exec rspec -I plugins/redmine_issue_templates/spec --format documentation plugins/redmine_issue_templates/spec/controllers/\n      - run:\n          command: |\n            bundle exec rspec -I plugins/redmine_issue_templates/spec --format documentation plugins/redmine_issue_templates/spec/requests/\n      - run:\n          command: |\n            bundle exec rspec -I plugins/redmine_issue_templates/spec --format documentation plugins/redmine_issue_templates/spec/features/\n\n      - run:\n          command: |\n            bundle exec rake redmine:plugins:migrate NAME=${CIRCLE_PROJECT_REPONAME} \\\n                    VERSION=0 RAILS_ENV=test\n      - run:\n          command: |\n            mkdir -p /tmp/coverage\n            cp -r coverage/${CIRCLE_PROJECT_REPONAME}_test /tmp/coverage/\n            cp -r coverage/${CIRCLE_PROJECT_REPONAME}_spec /tmp/coverage/\n      - store_artifacts:\n          path: /tmp/coverage\n\nworkflows:\n  version: 2\n  build_and_test:\n    jobs:\n      - build\n      - test:\n          requires:\n            - build\n          filters:\n            branches:\n              ignore:\n                - /v0.2.x-support-Redmine3.*/\n\n"
  },
  {
    "path": ".gitattributes",
    "content": ".gitattributes export-ignore\n.gitignore export-ignore\nwercker.yml export-ignore\nscript/ export-ignore\n.rubocop* export-ignore\nGemfile.local export-ignore\n.circleci/ export-ignore\ndocker-compose.yml export-ignore\nDockerfile export-ignore\n_config.yml export-ignore\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\nko_fi: akikopusu\n\n"
  },
  {
    "path": ".github/workflows/greetings.yml",
    "content": "name: Greetings\n\non: [issues]\n\njobs:\n  greeting:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/first-interaction@v1\n      with:\n        repo-token: ${{ secrets.GITHUB_TOKEN }}\n        issue-message: 'Thank you for contributing to Redmine Issue Templates plugin!'' first issue'\n        pr-message: 'Thanks you for contributing to Redmine Issue Templates plugin!'' first pr'\n"
  },
  {
    "path": ".gitignore",
    "content": "coverage/\ndoc/\n.yardoc/\nGemfile.lock\nGemfile\n.history\n.wercker\n"
  },
  {
    "path": ".rubocop.yml",
    "content": "inherit_from: .rubocop_todo.yml\nrequire:\n  - rubocop-rails\nAllCops:\n  TargetRubyVersion: 2.4\n  Exclude:\n    - 'db/**/*'\n\n"
  },
  {
    "path": ".rubocop_todo.yml",
    "content": "# This configuration was generated by\n# `rubocop --auto-gen-config`\n# on 2016-06-01 07:37:41 +0900 using RuboCop version 0.40.0.\n# The point is for the user to remove these configuration records\n# one by one as the offenses are removed from the code base.\n# Note that changes in the inspected code, or installation of new\n# versions of RuboCop, may require this file to be generated again.\n\n# Offense count: 3\nMetrics/AbcSize:\n  Max: 55\n\n# Offense count: 1\n# Configuration parameters: CountComments.\nMetrics/ClassLength:\n  Max: 200\n  Exclude:\n    - 'spec/**/*'\n    - 'test/**/*'\n\n# \"Line is too long\"を無効\nLayout/LineLength:\n  Enabled: false\n\n# Offense count: 1\nMetrics/CyclomaticComplexity:\n  Max: 10\n\n# Offense count: 1\nMetrics/PerceivedComplexity:\n  Max: 10\n\nMetrics/BlockLength:\n  Max: 30\n  Exclude:\n    - 'spec/**/*'\n    - 'test/**/*'\n\n# Avoid methods longer than 10 lines of code\nMethodLength:\n  CountComments: true  # count full line comments?\n  Max: 45\n\n# Aboid Missing top-level module documentation comment.\nDocumentation:\n  Enabled: false\n\nEndOfLine:\n  Enabled: false\n\nMetrics/ModuleLength:\n  Max: 120\n\nRails/ApplicationRecord:\n  Enabled: false\n\nRails/UniqueValidationWithoutIndex:\n  Enabled: false\n\nRails/InverseOf:\n  Enabled: false\n\nRails/LexicallyScopedActionFilter:\n  Enabled: false\n\nRails/SkipsModelValidations:\n  Enabled: false\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM ruby:2.6\nLABEL maintainer=\"AKIKO TAKANO / (Twitter: @akiko_pusu)\" \\\n  description=\"Image to run Redmine simply with sqlite to try/review plugin.\"\n\n### get Redmine source\n### Replace shell with bash so we can source files ###\nRUN rm /bin/sh && ln -s /bin/bash /bin/sh\n\n### install default sys packeges ###\n\nRUN apt-get update\nRUN apt-get install -qq -y \\\n    git vim        \\\n    sqlite3 default-libmysqlclient-dev\nRUN apt-get install -qq -y build-essential libc6-dev\n\n# for e2e test env\nRUN sh -c 'echo \"deb http://dl.google.com/linux/chrome/deb/ stable main\" >> /etc/apt/sources.list.d/google.list'\nRUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -\nRUN apt-get update && apt-get install -y google-chrome-stable\nRUN google-chrome --version | perl -pe 's/([^0-9]+)([0-9]+)(\\.[0-9]+).+/$2/g' > chrome-version-major\nRUN curl https://chromedriver.storage.googleapis.com/LATEST_RELEASE_`cat chrome-version-major` > chrome-version\nRUN curl -O -L http://chromedriver.storage.googleapis.com/`cat chrome-version`/chromedriver_linux64.zip && rm chrome-version*\nRUN unzip chromedriver_linux64.zip && mv chromedriver /usr/local/bin\n\nRUN cd /tmp && svn co http://svn.redmine.org/redmine/trunk redmine\nWORKDIR /tmp/redmine\n\nCOPY . /tmp/redmine/plugins/redmine_issue_templates/\n\n\n# add database.yml (for development, development with mysql, test)\nRUN echo $'test:\\n\\\n  adapter: sqlite3\\n\\\n  database: /tmp/data/redmine_test.sqlite3\\n\\\n  encoding: utf8mb4\\n\\\ndevelopment:\\n\\\n  adapter: sqlite3\\n\\\n  database: /tmp/data/redmine_development.sqlite3\\n\\\n  encoding: utf8mb4\\n\\\ndevelopment_mysql:\\n\\\n  adapter: mysql2\\n\\\n  host: mysql\\n\\\n  password: pasword\\n\\\n  database: redemine_development\\n\\\n  username: root\\n'\\\n>> config/database.yml\n\nRUN gem update bundler\nRUN bundle install\nRUN bundle exec rake db:migrate\nEXPOSE  3000\nCMD [\"rails\", \"server\", \"-b\", \"0.0.0.0\"]\n"
  },
  {
    "path": "Gemfile.local",
    "content": "group :test do\n  gem 'simplecov-rcov', require: false\n  gem 'rspec-rails'\n  gem 'factory_bot_rails'\n  gem 'launchy'\n  gem 'database_cleaner'\nend\n\n# for Debug\ngroup :development, :test do\n  gem 'pry-rails'\n  gem 'pry-byebug'\nend\n"
  },
  {
    "path": "ISSUE_TEMPLATE.md",
    "content": "This is a template to report bug related to redmine issue templates plugin.\nYou can fill in any format, free style in case report features or questions.\n\n## Summary\n\n\n## Description\n\n\n## Environment\n\nThese informations are greatly helpful to support quickly.\nYou can get these informations from Redmine's information page.\n(E.g. http://example.com/admin/info)\n\n- Redmine version\n- Installed plugins\n- Ruby version\n- OS Platform\n- Database (MariaDB, MySQL, PostgreSQL) and its version\n- Rails Env\n\n\n## Visual Proof / Screenshot\n\nWhen reporting an application error, post the error stack trace that \nyou should find in the **log file** (eg. log/production.log). \n\nScreen shot would be also helpful.\n\n\n## Expected Results\n\n## Actual Results\n\n## Workaround\n\nPlease let me know if you have any workaround.\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "\t\t    GNU GENERAL PUBLIC LICENSE\n\t\t       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\t\t\t    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\t\t    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\t\t\t    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\t\t     END OF TERMS AND CONDITIONS\n\n\t    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.\n"
  },
  {
    "path": "README.md",
    "content": "# Redmine Issue Templates Plugin\n\n[![Plugin info at redmine.org](https://img.shields.io/badge/Redmine-plugin-green.svg?)](http://www.redmine.org/plugins/redmine_issue_templates)\n[![CircleCI](https://circleci.com/gh/akiko-pusu/redmine_issue_templates/tree/master.svg?style=shield)](https://circleci.com/gh/akiko-pusu/redmine_issue_templates/tree/master)\n[![Sider](https://img.shields.io/badge/Special%20Thanks!-Sider-blue.svg?)](https://sider.review/features)\n\nPlugin to generate and use issue templates for each project to assist issue\ncreation. The latest version 1.0.x **is not compatible with IE11**. (Related: #310)\nPlease use version 0.3.8 or **[0.3-stable](https://github.com/akiko-pusu/redmine_issue_templates/tree/0.3-stable) branch** (uing jQuery version) as a stable release for Redmine4.x.\n\n## Repository\n\n* <https://github.com/akiko-pusu/redmine_issue_templates>\n\n## Plugin installation\n\n1. Copy the plugin directory into the $REDMINE_ROOT/plugins directory. Please\n    note that plugin's folder name should be \"redmine_issue_templates\". If\n    changed, some migration task will be failed.\n2. Do migration task.\n\n    e.g. rails redmine:plugins:migrate RAILS_ENV=production\n\n3. (Re)Start Redmine.\n\n## Uninstall\n\nTry this:\n\n* rails redmine:plugins:migrate NAME=redmine_issue_templates VERSION=0\n    RAILS_ENV=production\n\n### When migration error\n\nIf the migration is cancelled with the error like following message for the first time you try to install this plugin:\n\n> Caused by: Mysql2::Error: Table 'DATABASE_FOR_REDMINE.issue_templates' doesn't exist\n\nYou can fix this error to remove migration records related to this plugin from shema_migrations table.\n\nIf you can access and select database for Redmine, try this command:\n\n```sql\nselect * from schema_migrations where version like '%redmine_issue_templates%';\n```\n\nIf there are any records shown like this and there is no table named 'issue_templates', your installation has been incomplete state.\n\n```sql\n1-redmine_issue_templates\n2-redmine_issue_templates\n```\n\nSo, you should better to uninstall task first, and retry the migration.\n\nIf you have not created any template records yet, and hope to uninstall and re-install this plugin, please see README.\n\n**Uninstall:**\n\n```ruby\nrails db:migrate_plugins NAME=redmine_issue_templates VERSION=0 RAILS_ENV=production\n```\n\nAfter that, records of migration are removed from schema_migrations table.\n\n**Re-install:**\n\n```ruby\nrails db:migrate_plugins NAME=redmine_issue_templates RAILS_ENV=production (for Redmine4.x)\n```\n\n**Related issue:**\n\n* <https://github.com/akiko-pusu/redmine_issue_templates/issues/285>\n* <https://github.com/akiko-pusu/redmine_issue_templates/issues/169>\n* <https://github.com/akiko-pusu/redmine_issue_templates/issues/82#issuecomment-302000185>\n\n## Required Settings\n\n1. Login to your Redmine install as an Administrator\n2. Enable the permissions for your Roles:\n\n    * Show issue templates: User can show issue templates and use templates when creating/updating issues.\n    * Edit issue templates: User can create/update/activate templates for each project.\n    * Manage issue templates: User can edit help message of templates for each project.\n\n3. Enable the module \"Issue Template\" on the project setting page.\n4. The link to the plugin should appear on that project's navigation.\n\n## Note\n\nThis plugin aims to assist contributor's feedback by using template if the\nproject has some format for issues.\n\n## Troubleshoot for bundle intall and startup problem\n\nThis plugin repository includes some test code and gem settings. If you have\nsome trouble related \"bundle install\", please try --without option.\n\n> Exp. bundle install --without test\n\n## WebPage\n\n* <https://www.redmine.org/plugins/redmine_issue_templates> (Redmine Plugin List)\n* <https://github.com/akiko-pusu/redmine_issue_templates> (Repository & Issues)\n\nIf you have any requests, bug reports, please use GitHub issues. <https://github.com/akiko-pusu/redmine_issue_templates>\n\n## Description and usage info\n\n* <https://github.com/akiko-pusu/redmine_issue_templates/wiki>\n\n## Changelog\n\n### 1.1.0\n\nDrop off the feature to integrate with Checklist plugin, for maintenance reason.\nPlease see for more details: <https://github.com/akiko-pusu/redmine_issue_templates/issues/363>\n\n### 1.0.5\n\nBugfix and final release to support Checklist integration.\nPlease see: <https://github.com/akiko-pusu/redmine_issue_templates/issues/363>\n\n* Bugfix: template_type is not defined error (GitHub: #364 / Thanks for reporting issue, @toku463ne)\n\n### 1.0.4\n\nRelease to implemented some additional built-in/custom fields support.\n\n* Feature: Add preselected watchers to templates. (GitHub: #302)\n* Feature: Enabled to define assignees and categories. (GitHub: #362)\n* Bugfix: Template duplicates when changing Status or Category fields. (GitHub: #354)\n* Bugfix: Template body not loaded into issue answer (v.1.0.3 only) (GitHub: #356)\n* Update JavaScript and Spec.\n\nThank you for the valuable information and feedback, @ChrisUHZ!\n\nRESTRICTION: This version **is still not compatible with IE11**. (Related: #310)\n\n### 1.0.3\n\nNOTE: Mainly, maintenance, bugfix and refactoring only. There is no additional feature.\n\n* Refactor JavaScript to work properly under jQuery 3.x (for Redmine trunk).\n* Add some feature specs to test Builtin-fields support.\n\nRESTRICTION: This version **is still not compatible with IE11**. (Related: #310)\n\n### 1.0.2\n\nRelease to implememted Global note templates feature.\n\nNOTE: **Migration is required** to use global note template.\n\n* Feature: Implement Global Note Template. (GitHub: #268, #336)\n* Feature: Improve the input form for built-In / custom fields setting. (GitHub: #345)\n* Bugfix: Selecting note template browser \"jumps\" to top of page. (GitHub: #338)\n* Bugfix: Change to make the selector more specific. Thanks, @sandratatarevicova (GitHub: #332, #333)\n* Apply Bulgarian translation. Thanks, @jwalkerbg (GitHub: #330)\n* Update README: `--without` argument for `bundle` is no longer necessary. (GitHub: #335 / by @vividtone)\n* Update German Translation (by Christian Friebel).\n\nRESTRICTION: This version **is still not compatible with IE11**. (Related: #310)\n\n### 1.0.1\n\nThis is bugfix release against v1.0.0.\nUpdating to 1.0.1 is highly recommended, if you're using 1.0.0.\nMigration is also required.\n\n* Bugfix: Can't create a new templates optional settings. (GitHub: #322)\n* Migration: Change the column type to text. (GitHub: #323)\n* Update JavaScript.\n\nThank you for the valuable information and feedback, @AlUser71!\n\n### 1.0.0\n\nRESTRICTION: This version **is not compatible with IE11**. (Related: #310)\nPlease use version **0.3.8** or **[0.3-stable](https://github.com/akiko-pusu/redmine_issue_templates/tree/0.3-stable) branch** (uing jQuery version) if you need to support IE11.\n\nNOTE: **Migration is required**.\nSince ``Support Built-In / Custom Fields`` is an experimental feature, please **be careful** if you hope to try it.\n\n* Feature: Add feature to show template usage / example (#303)\n  * Using Vue.js v2.6.11\n* Feature: Support Built-In / Custom Fields (#304)\n* Rewrite JavaSctipt code from jQuery into plain JavaScript.\n\nAnd some browsers may not work fine because Support Built-In / Custom Fields feature uses Vue.js for frontend.\nSo feedback, issue report, suggestion highly appreciate!\n\n### 0.3.8\n\nThis is bugfix release.\n\n* Bugfix: Fix that Issue Templates plugin changes the cursor icon for \"Information\" menu on Redmine's administration page (by vividtone, GitHub #316)\n* Bugfix: Orphaned template list is not displayed (GitHub #337)\n* Update Russian translation (GitHub #340)\n* Update Bulgarian translation (GitHub #329)\n* Update Korean translation (update Korean translation)\n* Bugfix: enabled to create a new issue template setting. (GitHub #322)\n\n### 0.3.7\n\nThis is bugfix release to prevent the conflict with other plugins.\n\n* Bugfix: Tooltip for template body preview is hidden. (GitHub PR #300)\n* Refactor: Change to use project menu to prevent the project setting tab's conflict. (GitHub PR #299)\n\nThank you for the valuable information and feedback, @ChrisUHZ!\n\n### 0.3.6\n\nThis is bugfix release against v0.3.5.\nUpdating to 0.3.6 is highly recommended!\n\n* Update zh-TW locale. #281 (by Vongola)\n* Refactor: Update test code / Change Validation check.\n* Add troubleshooting for migration error and uninstall.\n* Add workaround to prevent other plugin's conflict. (#282)\n* Add workaround to load right templates if the project has subproject and subproject selected. (#289)\n* Apply the patch by @dmakurin to prevent the error when the user can't edit tracker id. (#288)\n* Only wipe issue subject and description if replace flag. (#284,  Applied Pull Request by @mattgill)\n\n### 0.3.5\n\nNOTE: This version requires migration command to enhance note template's feature.\n``Note Template visibility per role`` feature is still a prototype, so feedback highly appreciate!\n\n* Design: PR / Mrliptontea theme compatibility #266 (by mrliptontea)\n* Bugfix: #270 / Apply polyfill code for IE11. (reported by yui-har)\n* Feature: Note Template visibility per role. #267\n* Bugfix: Fix the request URL for accessing note_templates/load #261 (by ishikawa999)\n* Bugfix: Note Template does not work on CKEDitor. #275\n* Update README for contribution #273\n\n### 0.3.4\n\nThis is bugfix release against v0.3.3.\n\n* Add navigation link between issue template and note template.\n* Refactor: Change to use let / const instead of var.\n* Update test environment, especially E2E. (Follow up Redmine4.1)\n* Bugfix #256 / Related to checklists.\n\n### 0.3.3\n\nThis is bugfix release against v0.3.2.\nUpdating to 0.3.3 is highly recommended!\n\n* Revert and Bugfix #230\n  * Merge pull request #252 from ishikawa999/fix/248 by @ishikawa999\n* Bugfix: #234 / Enable to save checklists when updating a template.\n\n### 0.3.2\n\n* Bugfix: Adding issue templates with checklists occurs internal error.(#243)\n* Merge PR commit: bca2fe481 by @two-pack, restored missing newline. (Related: #242)\n* Feature: Add clear subject/body option when tracker changed which has no template. (#230)\n* Code refactoring.\n\n### 0.3.1\n\n* Basic feature implemented of note template.\n* Enabled to use issue templates when updating issue.\n  * Go to global template admin setting, and turn on \"apply_template_when_edit_issue\" flag.\n* Bugfix: Prevent conflict against issue controller helper. (#217)\n* Update readme: Merged PR #219. Thanks Arnaud Venturi!\n\nNOTE: This version requires migration command to use note template feature.\n\n```bash\nrails redmine:plugins:migrate RAILS_ENV=production\n```\n\n### 0.3.0\n\n* Support Redmine 4.x.\n  * Now master branch unsupports Redmine 3.x.\n  * Please use ver **0.2.x** or ``v0.2.x-support-Redmine3`` branch\n    in case using Redmine3.x.\n* Follow Redmine's preview option to the wiki toolbar.\n* Show additional navigation message when plugin is applied to Redmine 3.x.\n\nNOTE: Mainly, maintenance, bugfix and refactoring only. There is no additional feature, translation in this release.\nThank you for creating patch, Mizuki Ishikawa!\n\n### 0.2.1\n\nMainly, bugfix and refactoring release.\nUpdating to 0.2.1 is highly recommended in case using CKEditor or MySQL replication.\nNOTE: Migration is required, especially using MySQL replication.\n\n* Bugfix: Fix \"Page not found\" error when try to create project template from project setting. (GitHub: #192, #199)\n* Bugfix: Add composite unique index to support MySQL group replication. (GitHub: #197)\n* Workaround: Wait fot 200 msec until CKE Editor's ajax callback done. (GitHub: #193)\n* Add feature to hide confirmation dialog when overwritten issue subject and description, with using user cookie. (GitHub: #190)\n* Refactoring: Minitest and so on.\n\nA cookie named \"issue_template_confirm_to_replace_hide_dialog\" is stored from this release. (Related: #190)\n\n### 0.2.0\n\nBugfix and refactoring release.\nUpdating from v0.1.9 to 0.2.0 is highly recommended.\nIn this release, some methods which implemented on Redmine v3.3 are ported\nfor plugin's compatibility. (To support Redmine 3.0 - 3.4)\n\n* Bugfix: Prevent to call unimplemened methods prior to Redmine3.2. (GitHub: #180)\n* Refactoring: Code format. (JS, CSS) / Update config for E2E test.\n* Updated Simplified Chinese translation, thanks Steven.W. (GitHub PR: #179)\n* Applied responsive layout against template list (index) page.\n\nThank you for reviewing, Tatsuya Saito!\n\nFor release notes before v0.2.0, please see: [RELEASE-NOTES.md](RELEASE-NOTES.md)\n\n### Contributing\n\nPull requests, reporting issues, stars are always welcome!\n\nI'm always thrilled to receive pull requests, and do my best to process them as fast as possible.\nNot sure if that typo is worth a pull request? Do it! I will appreciate it.\n\n* Fork it!\n* Create your feature branch: git checkout -b my-new-feature\n* Commit your changes: git commit -am 'Add some feature'\n* Push to the branch: git push origin my-new-feature\n* Submit a pull request :D\n\n### Language and I18n contributors\n\n* Brazilian: Adriano Ceccarelli / Pedro Moritz de Carvalho Neto\n* Korean: Jaebok Oh\n* Chinese: Steven Wong, vongola12324 (zh-TW)\n* Bulgarian: Ivan Cenov\n* Russian: Denny Brain, danaivehr\n* German: Terence Miller, Christian Friebel and anonymous contributor\n* French: Anonymous one\n* Serbian: Miodrag Milic\n* Polish: Paweł Budikom and Krzysztof Wosinski\n* Spanish: Andres Arias\n* Italian: Luca Lesinigo\n* Danish: AThomsen\n\n### Rake Tasks\n\nYou can see rake task, with (bundle exec) rake -T, related to this plugin.\n\nExp.\n\n```bash\n# Apply inhelit template setting to child projects\n$ rake redmine_issue_templates:apply_inhelit_template_to_child_projects[project_id]\n\n# Run test for redmine_issue_template plugin\n$ rake redmine_issue_templates:default\n\n# Run spec for redmine_issue_template plugin\n$ rake redmine_issue_templates:spec\n\n# Run tests\n$ rake redmine_issue_templates:test\n\n# Unapply inhelit template setting from child projects\n$ rake redmine_issue_templates:unapply_inhelit_template_from_child_projects[project_id]\n\n# Generate YARD Documentation for redmine_issue_template plugin\n$ rake redmine_issue_templates:yardoc\n```\n\nYou can apply/unapply inherit templates for all the hild projects.\n\n```bash\nrake redmine_issue_templates:apply_inhelit_template_to_child_projects[project_id]      # Apply inhelit template setting to child projects\nrake redmine_issue_templates:unapply_inhelit_template_from_child_projects[project_id]  # Unapply inhelit template setting from child projects\n```\n\nIf you want to apply inherit templates setting all the child project of project_id: 1 (as parent project), please run rake command like this:\n\nrake redmine_issue_templates:apply_inhelit_template_to_child_projects[1]\n\n### Run test\n\nPlease see .circleci/config.yml for more details.\n\n```bash\n% cd REDMINE_ROOT_DIR\n% cp plugins/redmine_issue_templates/Gemfile.local plugins/redmine_issue_templates/Gemfile\n% bundle install --with test\n% export RAILS_ENV=test\n% bundle exec ruby -I\"lib:test\" -I plugins/redmine_issue_templates/test plugins/redmine_issue_templates/test/functional/issue_templates_controller_test.rb\n```\n\nor\n\n```bash\n% bundle exec rails redmine_issue_templates:test\n```\n\n#### Run spec\n\nPlease see .circleci/config.yml for more details.\n\n```bash\n% cd REDMINE_ROOT_DIR\n% cp plugins/redmine_issue_templates/Gemfile.local plugins/redmine_issue_templates/Gemfile\n% bundle install --with test\n% export RAILS_ENV=test\n% bundle exec rspec -I plugins/redmine_issue_templates/spec --format documentation plugins/redmine_issue_templates/spec/\n```\n\nBy default, use chrome as a webdriver. If you set environment variable\n'DRIVER' to 'headless', headless_chrome is used.\n\n```bash\n% DRIVER='headless' bundle exec rspec -I plugins/redmine_issue_templates/spec --format documentation plugins/redmine_issue_templates/spec/\n```\n\n### License\n\nThis software is licensed under the GNU GPL v2.\n"
  },
  {
    "path": "RELEASE-NOTES.md",
    "content": "# Releas notes before v0.2.0\n\n### 0.1.9\n\nBugfix and refactoring release.\n\n* Bugfix: Fix wrong template sort ordering.  (GitHub: #174)\n* Change UI to reorder templates with using drag and drop.\n* Add feature to copy template (Now project scope template only.)\n* Code refactoring. Use Headless Chrome for feature spec. Change to use CircleCI for build and test.\n* PR: Update Bulgarian translation. Thank you so much, Ivan Cenov! (GitHub: #171)\n* PR: Update Update pt-BR.yml Thank you so much, Adriano Baptistella! (GitHub: #173)\n* Bugfix: Wrong column label in \"Preview Template Contents\" modal dialog. (GitHub: #154)\n* PR: Updates to German language file. Thank you so much, Tobias Fischer! (GitHub: #164)\n\n### 0.1.8\n\nBugfix release.\n\n* Bugfix: Prevent \"undefined local variable or method\" error when listing project orphaned templates. (GitHub: #150)\n* PR: Add Portuguese translation. Thank you so much, Adriano Baptistella! (GitHub: #149)\n* Change url of Redmine Plugin Directory. (Changed identifier from issue_templates to redmine_issue_templates.)\n\n\n### 0.1.7\n\nBugfix release, and some code refactorings.\n\n#### Bugfix\n\n* After related tracker is removed, index (list) templates failed with exception. (#139)\n* Checklist not loading from Template. (#141)\n\n#### Refactoring\n\n* Remove all unlodable statement.\n* Remove unused rake task.\n* Rename modules.\n\n### 0.1.6\n\nMaintenance release to follow Redmine's update, and some refactoring related to test, namespace.\nOther additional updates are following:\n\n* Change support Redmine version to 3.0 or higher.\n* Stop to use jbuilder for rendering json. (#124)\n  * Now any gemfile is not used.\n* PR: UI improvement / Correct CSS. Thanks taqueci! (#120, #123)\n* Bugfix: Add exception handler and not to work rake task if rake task name is not specified. (#130)\n* Logging if template is deleted. (#118)\n* Change Template UI related to delete action. (#117)\n  * Prevent unexpected deletion of template.\n* PR: Add to confirm before replacing description and subject. Thanks, Tatsuya Saito. (#111)\n* PR: Fix CSS setting. Thanks, Tatsuya Saito. (#110)\n* Updated Simplified Chinese translation, thanks Steven.W. (#105, #113)\n\n### 0.1.5\n\nNOTE: Please run \"rake redmine:plugins:migrate\" task because new column is added.\n\n#### Feature for Global issue templates\n\n* Add feature enabled to  mark global issue template as \"default\".\n* Add plugin setting option to apply global issue templates to all the project.\n  * This option is on the plugin configuration screen. Please read help content before activate this option!\n\n#### Other updates\n\n* Update Russian translation. Thanks danaivehr! (GitHub: #95)\n* Prevent to locate template pulldown above \"tracker\" field and soon after jump below \"tracker\" field. (GitHub: #96)\n* Unselect projects on global issue template edit screen does not work correctly. (GitHub: #99)\n* Feature: Add “Revert” Icon to revert applied template. (Github: #98)\n* Change the place of message to notice \"default template loaded\" now to bottom of the page.\n* Change the place of \"Check all | Uncheck all” link in global issue template create / edit screen, to above the project list. (GitHub: #90)\n  * In case the list of projects is very long and would be much more comfortable to have the option on top.\n* Project select checkbox area is collapsed by default.\n  * Also, in case the list of projects is very long, administrator has to scroll to submit \"Save\" button.\n\n### 0.1.4.1\n\nBugfix version for #83, #92. Correct some methods not to use named parameters,\nbecause ruby 1.9x does not support named parameters.\n\n* Bugfix: GitHub: #83, #92\n* Bug: Italian translation should be start with \"it\". (GitHub: #87)\n\n### 0.1.4\n\nMaintenance release to follow Redmine's update, and some refactoring related to test, namespace.\nOther additional updates are following:\n\n* Change css and default width setting for template filter modal dialog. (GitHub: #78)\n* Add Italian translation. Thank you so much, Luca Lesinigo! (GitHub: #75)\n* Add Danish translation. Thank you so much, AThomsen! (GitHub: #68)\n* Do not append template contents if the content hasn't been edited. (GitHub: #62)\n* Add rake task to apply/unapply inherit templates for all the hild projects. (GitHub: #61)\n\n### 0.1.3\n\nNOTE: Please run \"rake redmine:plugins:migrate\" task because new column is\nadded.\n\n* Code refactoring. (Thank you so much for SideCI!)\n* Enabled to use template in case no project parameter passed. (GitHub: #43)\n* Updated the German locale. Thanks, jwciss!\n* Template is loaded after the error when required fields are not filled.\n    (GitHub: #50)\n* First implement to integrate Checklist plugin. (GitHub: #39)\n\n\n### 0.1.2\n\n* Move repository from Bitbucket to Github.\n* Add Spanish translation. Thanks, Andres Arias (r-labs #1413)\n* Add popup to preview template description and filter template. (Featured:\n    r-labs 1410)\n* Bugfix: Prevent to load default template in case updated issue form\n    triggered by states change event. (Related: bitbucket#36, Template loads\n    every time Status is changed.)\n* Update Simplified Chinese Localization. Thanks,  Steven Wong.\n* Support REST API with json format. (prototype. r-labs #1324)\n* Code refactoring.\n\n### 0.1.1\n\nBugfix release.\n\n* Update Brazilian translation file. (Bitbucket Pull Request: #4)\n* Removed deprecation warnings and adjusted gemfile to redmine 3.1.x\n    (Bitbucket Pull Request: #5)\n* Bug fix, prevent load template and overwrite description when status\n    changed. (Bitbucket Issue: #36)\n* Hide templates Element on Trackers without Issue Template. (Bitbucket\n    Issue: #57)\n* Bug fix, when issue create issue from copy, template should not overwrite\n    description. (Bitbucket Issue: #70)\n\nSpecial thanks all contributors, and Mattani-san, to this release.\n\n### 0.1.0\n\nNOTE: Please run \"rake redmine:plugins:migrate\" task because new column is\nadded.\n\n* Support Redmine 3.0. (r-labs: #1366)\n* Add Sort to Global Templates. (r-labs: #1364)\n* Add Polish translation file. (r-labs: #1354)\n\n### 0.0.9\n\nBug fix release.\n\n* Fix bug on ruby 1.8. (#52)\n* Remove feature to use JQuery tooltip to preview description, because\n    useless. (#50)\n* Change css definition to avoide conflict with Redmine's base style. (#45)\n* Correct migration file to prevent uninstall error. (Related: #54)\n\n### 0.0.8\n\nNOTE: Please run \"rake redmine:plugins:migrate\" task because new column is\nadded.\n\n* Fix some bugs.\n* Support global issue templates.\n* Try to use JQueryUI's tooltip.\n* Add Chinese / zh-TW translation file. Thank you so much, Chinese Spporter!\n\nKnown issue:\n\n* Template loads every time Status is changed\n  * <https://bitbucket.org/akiko_pusu/redmine_issue_templates/issue/36>\n* Only happned in case using default template.\n\n### 0.0.7\n\nNOTE: Please run \"rake redmine:plugins:migrate\" task because new column is\nadded.\n\n* Fix some bugs.\n* Compatible with CKEditor.  (#1280)\n* Add feature to show warning message for orphaned templates. (#1278)\n* Inherited templates only should be listed which tracker is the same to\n    child project use. (#1278)\n* Add French translation file. (Bitbucket IssueID:33)\n* Add Serbian translation. Thank you so much, Miodrag Milic. (Bitbucket\n    IssueID:34)\n* Add option to change append or replace with template. (#1176)\n\n### 0.0.6\n\n* Inherited templates from parent project.  (#1267)\n* Add links to template list/edit at project setting tab. (#1269)\n* Add link to erase issue subject and description text.\n* Replace :rubygems in Gemfile with 'https://rubygems.org'. Thanks for\n    JohnArcher.\n* Fixed invalid encoding. Thank you so much, Christoph. (#1178)\n* Fixed append \"null\" string to issue title field. (IssueID: #1268)\n* Prevent to load template when update and redirect with validation error.\n    (#1151, #1254)\n\n### 0.0.5\n\n* Load default template.  (#1088)\n* Show warning message in case no project trackers are assigned.\n* Change CSS style when showing template. (#1141)\n\n### 0.0.4\n\n* Support Redmine 2.1.x (Now unsupport Redmine 2.0.x. Please use ver 0.0.3\n    for Redmine2.0.x) Thak you so much, Viktor Muth, that gave me some\n    feedback.\n\n* Now insert template text just after the text that is already in the\n    description field.  (#1115)\n"
  },
  {
    "path": "_config.yml",
    "content": "theme: jekyll-theme-slate"
  },
  {
    "path": "app/controllers/concerns/issue_templates_common.rb",
    "content": "# frozen_string_literal: true\n\nmodule Concerns\n  module IssueTemplatesCommon\n    extend ActiveSupport::Concern\n\n    class InvalidTemplateFormatError < StandardError; end\n\n    included do\n      before_action :log_action, only: [:destroy]\n\n      # logging action\n      def log_action\n        logger&.info \"[#{self.class}] #{action_name} called by #{User.current.name}\"\n      end\n\n      def plugin_setting\n        Setting.plugin_redmine_issue_templates\n      end\n\n      def apply_all_projects?\n        plugin_setting['apply_global_template_to_all_projects'].to_s == 'true'\n      end\n\n      def apply_template_when_edit_issue?\n        plugin_setting['apply_template_when_edit_issue'].to_s == 'true'\n      end\n\n      def builtin_fields_enabled?\n        plugin_setting['enable_builtin_fields'].to_s == 'true'\n      end\n    end\n\n    def load_selectable_fields\n      tracker_id = params[:tracker_id]\n      project_id = params[:project_id]\n      render plain: {} && return if tracker_id.blank?\n\n      custom_fields = core_fields_map_by_tracker_id(tracker_id: tracker_id, project_id: project_id).merge(custom_fields_map_by_tracker_id(tracker_id))\n      render plain: { custom_fields: custom_fields }.to_json\n    end\n\n    def orphaned_templates\n      render partial: 'common/orphaned', locals: { orphaned_templates: orphaned }\n    end\n\n    def apply_all_projects?\n      plugin_setting['apply_global_template_to_all_projects'].to_s == 'true'\n    end\n\n    def builtin_fields_json\n      value = template_params[:builtin_fields].blank? ? {} : JSON.parse(template_params[:builtin_fields])\n      return value if value.is_a?(Hash)\n\n      raise InvalidTemplateFormatError\n    end\n\n    def valid_params\n      attributes = template_params.except(:builtin_fields)\n      attributes[:builtin_fields_json] = builtin_fields_json if builtin_fields_enabled?\n      attributes\n    end\n\n    def destroy\n      raise NotImplementedError, \"You must implement #{self.class}##{__method__}\"\n    end\n\n    #\n    # TODO: Code should be refactored\n    #\n    def core_fields_map_by_tracker_id(tracker_id: nil, project_id: nil)\n      return {} unless builtin_fields_enabled?\n\n      fields = %w[status_id priority_id]\n      fields << 'watcher_user_ids' if project_id.present?\n\n      # exclude \"description\"\n      tracker = Tracker.find_by(id: tracker_id)\n      fields += tracker.core_fields.reject { |field| field == 'description' } if tracker.present?\n      fields.reject! { |field| %w[category_id fixed_version_id assigned_to_id].include?(field) } if project_id.blank?\n\n      map = {}\n\n      fields.each do |field|\n        id = \"issue_#{field}\"\n        name = I18n.t('field_' + field.gsub(/_id$/, ''))\n        value = { name: name, core_field_id: id }\n        if field == 'priority_id'\n          value[:possible_values] = IssuePriority.active.pluck(:name)\n          value[:field_format] = 'list'\n        end\n\n        if field == 'status_id' && tracker.present?\n          value[:possible_values] = tracker.issue_statuses.pluck(:name)\n          value[:field_format] = 'list'\n        end\n\n        if field == 'category_id' && project_id.present?\n          categories = IssueCategory.where(project_id: project_id)\n          value[:possible_values] = categories.pluck(:name)\n          value[:field_format] = 'list'\n        end\n\n        if field == 'assigned_to_id' && project_id.present?\n          project = Project.find(project_id)\n          assignable_users = (project.assignable_users(tracker).to_a + [project.default_assigned_to]).uniq.compact\n          value[:possible_values] = assignable_users.map { |user| user.name }\n          value[:field_format] = 'list'\n        end\n\n        if field == 'watcher_user_ids' && project_id.present?\n          issue = Issue.new(tracker_id: tracker_id, project_id: project_id)\n          watchers = helpers.users_for_new_issue_watchers(issue)\n          value[:field_format] = 'list'\n\n          value[:possible_values] = watchers.map { |user| \"#{user.name} :#{user.id}\" }\n          value[:name] = I18n.t('field_watcher')\n          value[:multiple] = true\n        end\n\n        value[:field_format] = 'date' if %(start_date due_date).include?(field)\n\n        value[:field_format] = 'ratio' if field == 'done_ratio'\n\n        map[id] = value\n      end\n      map\n    rescue StandardError => e\n      logger&.info \"core_fields_map_by_tracker_id failed due to this error: #{e.message}\"\n      {}\n    end\n\n    def custom_fields_map_by_tracker_id(tracker_id = nil)\n      return {} unless builtin_fields_enabled?\n      return {} if tracker_id.blank?\n\n      tracker = Tracker.find_by(id: tracker_id)\n      ids = tracker&.custom_field_ids || []\n      fields = IssueCustomField.where(id: ids)\n      map = {}\n      fields.each do |field|\n        id = \"issue_custom_field_values_#{field.id}\"\n        attributes = field.attributes\n\n        attributes = attributes.merge(possible_values: field.possible_values_options.map { |value| value[0] }) if field.format.name == 'bool'\n        map[id] = attributes\n      end\n      map\n    rescue StandardError => e\n      logger&.info \"core_fields_map_by_tracker_id failed due to this error: #{e.message}\"\n      {}\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/project_templates_common.rb",
    "content": "# frozen_string_literal: true\n\nmodule Concerns\n  module ProjectTemplatesCommon\n    extend ActiveSupport::Concern\n    included do\n      before_action :find_user, :find_project, :authorize, except: %i[preview load load_selectable_fields]\n      before_action :find_object, only: %i[show edit update destroy]\n      accept_api_auth :index, :list_templates, :load\n    end\n\n    def show\n      render render_form_params\n    end\n\n    def destroy\n      unless template.destroy\n        flash[:error] = l(:enabled_template_cannot_destroy)\n        redirect_to action: :show, project_id: @project, id: template\n        return\n      end\n\n      flash[:notice] = l(:notice_successful_delete)\n      redirect_to action: 'index', project_id: @project\n    end\n\n    def save_and_flash(message, action_on_failure)\n      unless template.save\n        render render_form_params.merge(action: action_on_failure)\n        return\n      end\n\n      respond_to do |format|\n        format.html do\n          flash[:notice] = l(message)\n          redirect_to action: 'show', id: template.id, project_id: @project\n        end\n        format.js { head 200 }\n      end\n    rescue NoteTemplate::NoteTemplateError => e\n      flash[:error] = e.message\n      render render_form_params.merge(action: action_on_failure)\n      nil\n    end\n\n    def plugin_setting\n      Setting.plugin_redmine_issue_templates\n    end\n\n    def apply_all_projects?\n      plugin_setting['apply_global_template_to_all_projects'].to_s == 'true'\n    end\n\n    private\n\n    def template\n      raise NotImplementedError, \"You must implement #{self.class}##{__method__}\"\n    end\n\n    def find_user\n      @user = User.current\n    end\n\n    def find_tracker\n      @tracker = Tracker.find(params[:issue_tracker_id])\n    end\n\n    def find_project\n      @project = Project.find(params[:project_id])\n    rescue ActiveRecord::RecordNotFound\n      render_404\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/global_issue_templates_controller.rb",
    "content": "# frozen_string_literal: true\n\n# noinspection RubocopInspection\nclass GlobalIssueTemplatesController < ApplicationController\n  layout 'base'\n  helper :issues\n  include IssueTemplatesHelper\n  include Concerns::IssueTemplatesCommon\n  menu_item :issues\n  before_action :find_object, only: %i[show edit update destroy]\n  before_action :find_project, only: %i[edit update]\n  before_action :require_admin, only: %i[index new show], excep: [:preview]\n\n  #\n  # Action for global template : Admin right is required.\n  #\n  def index\n    trackers = Tracker.all\n    template_map = {}\n    trackers.each do |tracker|\n      tracker_id = tracker.id\n      templates = GlobalIssueTemplate.search_by_tracker(tracker_id).sorted\n      template_map[Tracker.find(tracker_id)] = templates if templates.any?\n    end\n    render layout: !request.xhr?, locals: { template_map: template_map, trackers: trackers }\n  end\n\n  def new\n    # create empty instance\n    @global_issue_template = GlobalIssueTemplate.new\n    render render_form_params\n  end\n\n  def create\n    @global_issue_template = GlobalIssueTemplate.new\n    @global_issue_template.author = User.current\n\n    begin\n      @global_issue_template.safe_attributes = valid_params\n    rescue ActiveRecord::SerializationTypeMismatch, Concerns::IssueTemplatesCommon::InvalidTemplateFormatError\n      flash[:error] = I18n.t(:builtin_fields_should_be_valid_json, default: 'Please enter a valid JSON fotmat string.')\n      render render_form_params.merge(action: :new)\n      return\n    end\n    save_and_flash(:notice_successful_create, :new) && return\n  end\n\n  def show\n    render render_form_params\n  end\n\n  def update\n    begin\n      @global_issue_template.safe_attributes = valid_params\n    rescue ActiveRecord::SerializationTypeMismatch, Concerns::IssueTemplatesCommon::InvalidTemplateFormatError\n      flash[:error] = I18n.t(:builtin_fields_should_be_valid_json, default: 'Please enter a valid JSON fotmat string.')\n      render render_form_params.merge(action: :show)\n      return\n    end\n\n    save_and_flash(:notice_successful_update, :show)\n  end\n\n  def edit\n    # Change from request.post to request.patch for Rails4.\n    return unless request.patch? || request.put?\n\n    begin\n      @global_issue_template.safe_attributes = valid_params\n    rescue ActiveRecord::SerializationTypeMismatch\n      flash[:error] = I18n.t(:builtin_fields_should_be_valid_json, default: 'Please enter a valid JSON fotmat string.')\n      render render_form_params.merge(action: :show)\n      return\n    end\n\n    save_and_flash(:notice_successful_update, :show)\n  end\n\n  def destroy\n    unless @global_issue_template.destroy\n      flash[:error] = l(:enabled_template_cannot_destroy)\n      redirect_to action: :show, id: @global_issue_template\n      return\n    end\n\n    flash[:notice] = l(:notice_successful_delete)\n    redirect_to action: 'index'\n  end\n\n  # preview\n  def preview\n    global_issue_template = params[:global_issue_template]\n    id = params[:id]\n    @text = (global_issue_template ? global_issue_template[:description] : nil)\n    @global_issue_template = GlobalIssueTemplate.find(id) if id\n    render partial: 'common/preview'\n  end\n\n  private\n\n  def orphaned\n    GlobalIssueTemplate.orphaned\n  end\n\n  def find_project\n    @projects = Project.all\n  end\n\n  def find_object\n    @global_issue_template = GlobalIssueTemplate.find(params[:id])\n  rescue ActiveRecord::RecordNotFound\n    render_404\n  end\n\n  def save_and_flash(message, action_on_failure)\n    unless @global_issue_template.save\n      render render_form_params.merge(action: action_on_failure)\n      return\n    end\n\n    respond_to do |format|\n      format.html do\n        flash[:notice] = l(message)\n        redirect_to action: 'show', id: @global_issue_template.id\n      end\n      format.js { head 200 }\n    end\n  end\n\n  def template_params\n    params.require(:global_issue_template)\n          .permit(:title, :tracker_id, :issue_title, :description, :note, :is_default, :enabled,\n                  :author_id, :position, :related_link, :link_title, :builtin_fields,\n                  project_ids: [])\n  end\n\n  def render_form_params\n    trackers = Tracker.all\n    projects = Project.all\n    tracker_id = @global_issue_template.tracker_id\n    custom_fields = core_fields_map_by_tracker_id(tracker_id: tracker_id)\n                    .merge(custom_fields_map_by_tracker_id(tracker_id)).to_json\n\n    { layout: !request.xhr?,\n      locals: { trackers: trackers, apply_all_projects: apply_all_projects?,\n                issue_template: @global_issue_template, projects: projects, custom_fields: custom_fields.to_s,\n                builtin_fields_enable: builtin_fields_enabled? } }\n  end\nend\n"
  },
  {
    "path": "app/controllers/global_note_templates_controller.rb",
    "content": "# frozen_string_literal: true\n\n# noinspection RubocopInspection\nclass GlobalNoteTemplatesController < ApplicationController\n  layout 'base'\n  helper :issues\n  helper :issue_templates\n  menu_item :issues\n\n  before_action :find_object, only: %i[show update destroy]\n  before_action :find_project, only: %i[update]\n  before_action :require_admin, only: %i[index new show], excep: [:preview]\n\n  #\n  # Action for global template : Admin right is required.\n  #\n  def index\n    trackers = Tracker.all\n    template_map = {}\n    trackers.each do |tracker|\n      tracker_id = tracker.id\n      templates = GlobalNoteTemplate.search_by_tracker(tracker_id).sorted\n      template_map[Tracker.find(tracker_id)] = templates if templates.any?\n    end\n\n    render layout: !request.xhr?, locals: { template_map: template_map, trackers: trackers }\n  end\n\n  def new\n    # create empty instance\n    @global_note_template = GlobalNoteTemplate.new\n    render render_form_params\n  end\n\n  def create\n    @global_note_template = GlobalNoteTemplate.new(template_params)\n    @global_note_template.author = User.current\n\n    save_and_flash(:notice_successful_create, :new) && return\n  end\n\n  def show\n    render render_form_params\n  end\n\n  def update\n    # Workaround in case author id is null\n    @global_note_template.author = User.current if @global_note_template.author.blank?\n    @global_note_template.safe_attributes = template_params\n\n    save_and_flash(:notice_successful_update, :show)\n  end\n\n  def destroy\n    unless @global_note_template.destroy\n      flash[:error] = l(:enabled_template_cannot_destroy)\n      redirect_to action: :show, id: @global_note_template\n      return\n    end\n\n    flash[:notice] = l(:notice_successful_delete)\n    redirect_to action: 'index'\n  end\n\n  def find_project\n    @projects = Project.all\n  end\n\n  def find_object\n    @global_note_template = GlobalNoteTemplate.find(params[:id])\n  rescue ActiveRecord::RecordNotFound\n    render_404\n  end\n\n  def save_and_flash(message, action_on_failure)\n    unless @global_note_template.save\n      render render_form_params.merge(action: action_on_failure)\n      return\n    end\n\n    respond_to do |format|\n      format.html do\n        flash[:notice] = l(message)\n        redirect_to action: 'show', id: @global_note_template.id\n      end\n      format.js { head 200 }\n    end\n  end\n\n  def template_params\n    params.require(:global_note_template)\n          .permit(:global_note_template_id, :tracker_id, :name, :memo, :description,\n                  :enabled, :author_id, :position, :visibility, role_ids: [], project_ids: [])\n  end\n\n  def render_form_params\n    trackers = Tracker.all\n    projects = Project.all\n\n    { layout: !request.xhr?,\n      locals: { trackers: trackers, apply_all_projects: apply_all_projects?,\n                note_template: @global_note_template, projects: projects } }\n  end\n\n  def apply_all_projects?\n    plugin_setting['apply_global_template_to_all_projects'].to_s == 'true'\n  end\n\n  def plugin_setting\n    Setting.plugin_redmine_issue_templates\n  end\nend\n"
  },
  {
    "path": "app/controllers/issue_templates_controller.rb",
    "content": "# frozen_string_literal: true\n\n# noinspection ALL\nclass IssueTemplatesController < ApplicationController\n  layout 'base'\n  helper :issues\n  include Concerns::IssueTemplatesCommon\n  include Concerns::ProjectTemplatesCommon\n  menu_item :issues\n  before_action :find_tracker, :find_templates, only: %i[set_pulldown list_templates]\n\n  def index\n    project_id = @project.id\n    project_templates = IssueTemplate.search_by_project(project_id)\n\n    # pick up used tracker ids\n    tracker_ids = @project.trackers.pluck(:id)\n\n    @template_map = {}\n    tracker_ids.each do |tracker_id|\n      templates = project_templates.search_by_tracker(tracker_id).sorted\n      @template_map[Tracker.find(tracker_id)] = templates if templates.any?\n    end\n\n    setting = IssueTemplateSetting.find_or_create(project_id)\n    @inherit_templates = setting.get_inherit_templates\n\n    @global_issue_templates = global_templates(tracker_ids)\n\n    respond_to do |format|\n      format.html do\n        render layout: !request.xhr?,\n               locals: { apply_all_projects: apply_all_projects?, tracker_ids: tracker_ids }\n      end\n      format.api do\n        render formats: :json, locals: { project_templates: project_templates }\n      end\n    end\n  end\n\n  def new\n    if params[:copy_from].present?\n      @issue_template = IssueTemplate.find(params[:copy_from]).dup\n      @issue_template.title = @issue_template.copy_title\n    else\n      # create empty instance\n      @issue_template ||= IssueTemplate.new(author: @user, project: @project)\n    end\n    render render_form_params\n  end\n\n  def create\n    @issue_template = IssueTemplate.new\n    @issue_template.author = User.current\n    @issue_template.project = @project\n\n    begin\n      @issue_template.safe_attributes = valid_params\n    rescue ActiveRecord::SerializationTypeMismatch, Concerns::IssueTemplatesCommon::InvalidTemplateFormatError\n      flash[:error] = I18n.t(:builtin_fields_should_be_valid_json, default: 'Please enter a valid JSON fotmat string.')\n      render render_form_params.merge(action: :new)\n      return\n    end\n\n    # TODO: Should return validation error in case mandatory fields are blank.\n    save_and_flash(:notice_successful_create, :new) && return\n  end\n\n  def update\n    begin\n      @issue_template.safe_attributes = valid_params\n    rescue ActiveRecord::SerializationTypeMismatch, Concerns::IssueTemplatesCommon::InvalidTemplateFormatError\n      flash[:error] = I18n.t(:builtin_fields_should_be_valid_json, default: 'Please enter a valid JSON fotmat string.')\n      render render_form_params.merge(action: :show)\n      return\n    end\n    save_and_flash(:notice_successful_update, :show)\n  end\n\n  # load template description\n  def load\n    issue_template_id = params[:template_id]\n    template_type = params[:template_type]\n    issue_template = if template_type.present? && template_type == 'global'\n                       GlobalIssueTemplate.find(issue_template_id)\n                     else\n                       IssueTemplate.find(issue_template_id)\n                     end\n    rendered_json = builtin_fields_enabled? ? issue_template.template_json : issue_template.template_json(except: 'builtin_fields_json')\n\n    render plain: rendered_json\n  end\n\n  # update pulldown\n  def set_pulldown\n    @group = []\n    @default_template = nil\n\n    add_templates_to_group(@issue_templates)\n    add_templates_to_group(@inherit_templates, class: 'inherited')\n    add_templates_to_group(@global_templates, class: 'global')\n\n    if loadable_trigger?\n      @group[@default_template].selected = 'selected'\n    end\n\n    render action: '_template_pulldown', layout: false,\n           locals: { is_triggered_by: request.parameters[:is_triggered_by], grouped_options: @group,\n                     should_replaced: setting.should_replaced, default_template: @default_template }\n  end\n\n  #\n  # List templates associated with tracker and project.\n  # TODO: refactor here. Duplicate with set_pulldown....\n  #\n  def list_templates\n    (default_global, default_inherit, default_project) = default_templates\n\n    default_template = default_inherit.presence || default_global\n    default_template = default_project.presence || default_template\n\n    respond_to do |format|\n      format.html do\n        render action: '_list_templates',\n               layout: false,\n               locals: { default_template: default_template,\n                         issue_templates: @issue_templates,\n                         inherit_templates: @inherit_templates,\n                         global_issue_templates: @global_templates }\n      end\n      format.api do\n        render action: '_list_templates',\n               locals: { default_template: default_template,\n                         issue_templates: @issue_templates,\n                         inherit_templates: @inherit_templates,\n                         global_issue_templates: @global_templates }\n      end\n    end\n  end\n\n  def menu_items\n    { issue_templates: { default: :issue_templates, actions: {} } }\n  end\n\n  # preview\n  def preview\n    issue_template = params[:issue_template]\n    @text = (issue_template ? issue_template[:description] : nil)\n    render partial: 'common/preview'\n  end\n\n  private\n\n  def orphaned\n    IssueTemplate.orphaned(@project.id)\n  end\n\n  def find_object\n    @issue_template = IssueTemplate.find(params[:id])\n    @project = @issue_template.project\n  rescue ActiveRecord::RecordNotFound\n    render_404\n  end\n\n  def find_templates\n    @issue_templates = issue_templates\n    @inherit_templates = inherit_templates\n    @global_templates = global_templates(@tracker.id)\n  end\n\n  def template\n    @issue_template\n  end\n\n  def setting\n    IssueTemplateSetting.find_or_create(@project.id)\n  end\n\n  def global_templates(tracker_id)\n    return [] if apply_all_projects? && templates_exist?\n\n    project_id = apply_all_projects? ? nil : @project.id\n    GlobalIssueTemplate.get_templates_for_project_tracker(project_id, tracker_id)\n  end\n\n  def default_templates\n    [@global_templates, @inherit_templates, @issue_templates].map do |templates|\n      templates.try(:is_default).try(:first)\n    end\n  end\n\n  def default_template_index\n    @default_template.blank? ? @group.length - 1 : @default_template\n  end\n\n  def add_templates_to_group(templates, option = {})\n    templates.each do |template|\n      @group << template.template_struct(option)\n      next unless template.is_default == true\n\n      @default_template = default_template_index\n    end\n  end\n\n  def issue_templates\n    if params[:issue_project_id]\n      @project = Project.find(params[:issue_project_id])\n    end\n    IssueTemplate.get_templates_for_project_tracker(@project.id, @tracker.id)\n  end\n\n  def inherit_templates\n    setting.get_inherit_templates(@tracker)\n  end\n\n  def template_params\n    params.require(:issue_template).permit(:tracker_id, :title, :note, :issue_title, :description, :is_default,\n                                           :enabled, :author_id, :position, :enabled_sharing,\n                                           :related_link, :link_title, :builtin_fields)\n  end\n\n  def templates_exist?\n    @inherit_templates.present? || @issue_templates.present?\n  end\n\n  def render_form_params\n    child_project_used_count = template&.used_projects&.count\n    custom_fields = core_fields_map_by_tracker_id(tracker_id: template&.tracker_id, project_id: @project.id)\n                    .merge(custom_fields_map_by_tracker_id(template&.tracker_id)).to_json\n\n    { layout: !request.xhr?,\n      locals: { issue_template: template, project: @project, child_project_used_count: child_project_used_count,\n                custom_fields: custom_fields.to_s, builtin_fields_enable: builtin_fields_enabled? } }\n  end\n\n  def loadable_trigger?\n    is_triggered_by = request.parameters[:is_triggered_by]\n    is_update_issue = request.parameters[:is_update_issue]\n\n    return false if is_triggered_by.present? && is_triggered_by != 'is_update_issue'\n    return @default_template.present? && (is_update_issue.blank? || is_update_issue != 'true')\n  end\nend\n"
  },
  {
    "path": "app/controllers/issue_templates_settings_controller.rb",
    "content": "# frozen_string_literal: true\n\n# noinspection RubocopInspection\nclass IssueTemplatesSettingsController < ApplicationController\n  before_action :find_project, :find_user\n  before_action :authorize, :find_issue_templates_setting, except: %i[preview]\n\n  def index; end\n\n  def edit\n    return if params[:settings].blank?\n\n    update_template_setting\n    flash[:notice] = l(:notice_successful_update)\n    redirect_to action: 'index', project_id: @project\n  end\n\n  def preview\n    @text = params[:settings][:help_message]\n    render partial: 'common/preview'\n  end\n\n  def menu_items\n    { issue_templates_settings: { default: :issue_templates, actions: {} } }\n  end\n\n  private\n\n  def find_user\n    @user = User.current\n  end\n\n  def find_project\n    @project = Project.find(params[:project_id])\n  rescue ActiveRecord::RecordNotFound\n    render_404\n  end\n\n  def find_issue_templates_setting\n    @issue_templates_setting = IssueTemplateSetting.find_or_create(@project.id)\n  end\n\n  def update_template_setting\n    issue_templates_setting = IssueTemplateSetting.find_or_create(@project.id)\n    attribute = params[:settings]\n    issue_templates_setting.update(enabled: attribute[:enabled],\n                                   help_message: attribute[:help_message],\n                                   inherit_templates: attribute[:inherit_templates],\n                                   should_replaced: attribute[:should_replaced])\n  end\nend\n"
  },
  {
    "path": "app/controllers/note_templates_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass NoteTemplatesController < ApplicationController\n  include Concerns::ProjectTemplatesCommon\n  layout 'base'\n  helper :issue_templates\n  menu_item :issues\n\n  def index\n    project_id = @project.id\n    note_templates = NoteTemplate.search_by_project(project_id).sorted\n\n    # pick up used tracker ids\n    tracker_ids = @project.trackers.pluck(:id)\n\n    @template_map = {}\n    tracker_ids.each do |tracker_id|\n      templates = note_templates.search_by_tracker(tracker_id)\n      @template_map[Tracker.find(tracker_id)] = templates if templates.any?\n    end\n\n    @global_note_templates = global_templates(tracker_ids)\n\n    respond_to do |format|\n      format.html do\n        render layout: !request.xhr?,\n               locals: { apply_all_projects: apply_all_projects?, tracker_ids: tracker_ids }\n      end\n      format.api do\n        render formats: :json, locals: { note_templates: note_templates }\n      end\n    end\n  end\n\n  def new\n    @note_template ||= NoteTemplate.new(author: @user, project: @project)\n    render render_form_params\n  end\n\n  def create\n    @note_template = NoteTemplate.new(template_params)\n    @note_template.author = User.current\n    @note_template.project = @project\n    save_and_flash(:notice_successful_create, :new) && return\n  end\n\n  def update\n    # Workaround in case author id is null\n    @note_template.author = User.current if @note_template.author.blank?\n    @note_template.safe_attributes = template_params\n    @note_template.role_ids = template_params[:role_ids]\n\n    save_and_flash(:notice_successful_update, :show)\n  end\n\n  # load template description\n  def load\n    note_template_id = template_params[:note_template_id]\n    template_type = template_params[:template_type]\n\n    if template_type.present? && template_type == 'global'\n      project_id = template_params[:project_id]\n      note_template = GlobalNoteTemplate.find(note_template_id)\n\n      # prevent to load if the template visibility does not match.\n      raise ActiveRecord::RecordNotFound unless note_template.loadable?(user_id: User.current.id, project_id: project_id)\n    else\n      note_template = NoteTemplate.find(note_template_id)\n      # prevent to load if the template visibility does not match.\n      raise ActiveRecord::RecordNotFound unless note_template.loadable?(user_id: User.current.id)\n    end\n\n    render plain: note_template.template_json\n  rescue ActiveRecord::RecordNotFound\n    render_404\n  end\n\n  def list_templates\n    tracker_id = params[:tracker_id]\n    project_id = params[:project_id]\n\n    note_templates = NoteTemplate.visible_note_templates_condition(\n      user_id: User.current.id, project_id: project_id, tracker_id: tracker_id\n    )\n\n    global_note_templates = GlobalNoteTemplate.visible_note_templates_condition(\n      user_id: User.current.id, project_id: project_id, tracker_id: tracker_id\n    )\n\n    respond_to do |format|\n      format.html do\n        render action: '_list_note_templates',\n               layout: false,\n               locals: { note_templates: note_templates, global_note_templates: global_note_templates }\n      end\n    end\n  end\n\n  def destroy\n    unless @note_template.destroy\n      flash[:error] = l(:enabled_template_cannot_destroy)\n      redirect_to action: :show, project_id: @project, id: @note_template\n      return\n    end\n\n    flash[:notice] = l(:notice_successful_delete)\n    redirect_to action: 'index', project_id: @project\n  end\n\n  def menu_items\n    { note_templates: { default: :issue_templates, actions: {} } }\n  end\n\n  private\n\n  def find_object\n    @note_template = NoteTemplate.find(params[:id])\n    @project = @note_template.project\n  rescue ActiveRecord::RecordNotFound\n    render_404\n  end\n\n  def template_params\n    params.require(:note_template)\n          .permit(:note_template_id, :project_id, :template_type, :tracker_id, :name, :memo, :description,\n                  :enabled, :author_id, :position, :visibility, role_ids: [])\n  end\n\n  def template\n    @note_template\n  end\n\n  def render_form_params\n    { layout: !request.xhr?,\n      locals: { note_template: template, project: @project } }\n  end\n\n  def templates_exist?\n    @note_templates.present?\n  end\n\n  def global_templates(tracker_id)\n    return [] if apply_all_projects? && templates_exist?\n\n    project_id = apply_all_projects? ? nil : @project.id\n    GlobalNoteTemplate.get_templates_for_project_tracker(project_id, tracker_id)\n  end\nend\n"
  },
  {
    "path": "app/helpers/issue_templates_helper.rb",
    "content": "module IssueTemplatesHelper\n  def project_tracker?(tracker, project)\n    return false unless tracker.present?\n\n    project.trackers.exists?(tracker.id)\n  end\n\n  def non_project_tracker_msg(flag)\n    return '' if flag\n\n    \"<font class=\\\"non_project_tracker\\\">#{l(:unused_tracker_at_this_project)}</font>\".html_safe\n  end\n\n  def template_target_trackers(project, issue_template)\n    trackers = project.trackers\n    trackers |= [issue_template.tracker] unless issue_template.tracker.blank?\n    trackers.collect { |obj| [obj.name, obj.id] }\n  end\n\n  def options_for_template_pulldown(options)\n    options.map do |option|\n      text = option.try(:name).to_s\n      tag_builder.content_tag_string(:option, text, option, true)\n    end.join(\"\\n\").html_safe\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/issue_template/common.rb",
    "content": "# frozen_string_literal: true\n\nmodule Concerns\n  module IssueTemplate\n    module Common\n      extend ActiveSupport::Concern\n\n      #\n      # Common scope both global and project scope template.\n      #\n      included do\n        belongs_to :author, class_name: 'User', foreign_key: 'author_id'\n        belongs_to :tracker\n        before_save :check_default\n\n        before_destroy :confirm_disabled\n\n        validates :title, presence: true\n        validates :tracker, presence: true\n        validates :related_link, format: { with: URI::DEFAULT_PARSER.make_regexp }, allow_blank: true\n\n        scope :enabled, -> { where(enabled: true) }\n        scope :sorted, -> { order(:position) }\n        scope :search_by_tracker, lambda { |tracker_id|\n          where(tracker_id: tracker_id) if tracker_id.present?\n        }\n\n        scope :is_default, -> { where(is_default: true) }\n        scope :not_default, -> { where(is_default: false) }\n\n        scope :orphaned, lambda { |project_id = nil|\n          condition = all\n          if project_id.present? && try(:name) == 'IssueTemplate'\n            condition = condition.where(project_id: project_id)\n            ids = Tracker.joins(:projects).where(projects: { id: project_id }).pluck(:id)\n          else\n            ids = Tracker.pluck(:id)\n          end\n          condition.where.not(tracker_id: ids)\n        }\n\n        after_destroy do |template|\n          logger.info(\"[Destroy] #{self.class}: #{template.inspect}\")\n        end\n\n        # ActiveRecord::SerializationTypeMismatch may be thrown if non hash object is assigned.\n        serialize :builtin_fields_json, Hash\n      end\n\n      #\n      # Common methods both global and project scope template.\n      #\n      def enabled?\n        enabled\n      end\n\n      def <=>(other)\n        position <=> other.position\n      end\n\n      # Keep this method for a while, but this will be deprecated.\n      # Please see: https://github.com/akiko-pusu/redmine_issue_templates/issues/363\n      def checklist\n        return [] if checklist_json.blank?\n\n        begin\n          JSON.parse(checklist_json)\n        rescue StandardError\n          []\n        end\n      end\n\n      def template_json(except: nil)\n        template = {}\n        template[self.class::Config::JSON_OBJECT_NAME] = generate_json\n        return template.to_json(root: true) if except.blank?\n\n        template.to_json(root: true, except: [except])\n      end\n\n      def builtin_fields\n        builtin_fields_json.to_json\n      end\n\n      def generate_json\n        result = attributes\n        result[:link_title] = link_title.presence || I18n.t(:issue_template_related_link, default: 'Related Link')\n        result[:checklist] = checklist\n        result.except('checklist_json')\n      end\n\n      def template_struct(option = {})\n        Struct.new(:value, :name, :class, :selected).new(id, title, option[:class])\n      end\n\n      def log_destroy_action(template)\n        logger.info \"[Destroy] #{self.class}: #{template.inspect}\" if logger&.info\n      end\n\n      def confirm_disabled\n        return unless enabled?\n\n        errors.add :base, 'enabled_template_cannot_destroy'\n        throw :abort\n      end\n\n      def copy_title\n        \"copy_of_#{title}\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/global_issue_template.rb",
    "content": "# frozen_string_literal: true\n\nclass GlobalIssueTemplate < ActiveRecord::Base\n  include Redmine::SafeAttributes\n  include Concerns::IssueTemplate::Common\n  validates :title, uniqueness: { scope: :tracker_id }\n  has_and_belongs_to_many :projects\n\n  acts_as_positioned scope: [:tracker_id]\n\n  safe_attributes 'title',\n                  'description',\n                  'tracker_id',\n                  'note',\n                  'enabled',\n                  'is_default',\n                  'issue_title',\n                  'project_ids',\n                  'position',\n                  'author_id',\n                  'related_link',\n                  'link_title',\n                  'builtin_fields_json'\n\n  # for intermediate table assosciations\n  scope :search_by_project, lambda { |project_id|\n    joins(:projects).where(projects: { id: project_id }) if project_id.present?\n  }\n\n  module Config\n    JSON_OBJECT_NAME = 'global_issue_template'\n  end\n  Config.freeze\n\n  #\n  # In case set is_default and updated, others are also updated.\n  #\n  def check_default\n    return unless is_default? && is_default_changed?\n\n    self.class.search_by_tracker(tracker_id).update_all(is_default: false)\n  end\n\n  #\n  # Class method\n  #\n  class << self\n    def get_templates_for_project_tracker(project_id, tracker_id = nil)\n      GlobalIssueTemplate.search_by_tracker(tracker_id)\n                         .search_by_project(project_id)\n                         .enabled\n                         .sorted\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/global_note_template.rb",
    "content": "# frozen_string_literal: true\n\nclass GlobalNoteTemplate < ActiveRecord::Base\n  include Redmine::SafeAttributes\n  include ActiveModel::Validations\n\n  # author and project should be stable.\n  safe_attributes 'name',\n                  'description',\n                  'enabled',\n                  'memo',\n                  'tracker_id',\n                  'position',\n                  'visibility',\n                  'role_ids',\n                  'project_ids'\n\n  validates :role_ids, presence: true, if: :roles?\n\n  belongs_to :author, class_name: 'User', inverse_of: false, foreign_key: 'author_id'\n  belongs_to :tracker\n\n  has_many :global_note_template_projects, dependent: :nullify\n  has_many :projects, through: :global_note_template_projects\n\n  has_many :global_note_visible_roles, dependent: :nullify\n  has_many :roles, through: :global_note_visible_roles\n\n  validates :name, presence: true\n  acts_as_positioned scope: %i[tracker_id]\n\n  enum visibility: { roles: 1, open: 2 }\n\n  scope :mine_condition, lambda { |user_id|\n    where(author_id: user_id).mine if user_id.present?\n  }\n\n  scope :roles_condition, lambda { |role_ids|\n    joins(:global_note_visible_roles).where(global_note_visible_roles: { role_id: role_ids })\n  }\n\n  scope :enabled, -> { where(enabled: true) }\n  scope :sorted, -> { order(:position) }\n  scope :search_by_tracker, lambda { |tracker_id|\n    where(tracker_id: tracker_id) if tracker_id.present?\n  }\n\n  # for intermediate table assosciations\n  scope :search_by_project, lambda { |project_id|\n    joins(:projects).where(projects: { id: project_id }) if project_id.present?\n  }\n\n  before_save :check_visible_roles\n  after_save :note_visible_roles!\n  before_destroy :confirm_disabled\n\n  def <=>(other)\n    position <=> other.position\n  end\n\n  def template_json\n    template = {}\n    template['note_template'] = generate_json\n    template.to_json(root: true)\n  end\n\n  def generate_json\n    attributes\n  end\n\n  def note_visible_roles!\n    return unless roles?\n\n    if role_ids.blank?\n      raise NoteTemplateError, l(:please_select_at_least_one_role,\n                                 default: 'Please select at least one role.')\n    end\n\n    ActiveRecord::Base.transaction do\n      GlobalNoteVisibleRole.where(global_note_template_id: id).delete_all if global_note_visible_roles.present?\n      role_ids.each do |role_id|\n        GlobalNoteVisibleRole.create!(global_note_template_id: id, role_id: role_id)\n      end\n    end\n  end\n\n  def loadable?(user_id:, project_id:)\n    return true if open?\n\n    project = Project.find(project_id)\n    user_project_roles = User.find(user_id).roles_for_project(project).pluck(:id)\n    match_roles = user_project_roles & roles.ids\n\n    return true if roles? && match_roles.present?\n\n    false\n  end\n\n  private\n\n  def check_visible_roles\n    return if roles? || global_note_visible_roles.empty?\n\n    # Remove roles in case template visible scope is not \"roles\".\n    # This remove action is included the same transaction scope.\n    GlobalNoteVisibleRole.where(global_note_template_id: id).delete_all\n  end\n\n  def confirm_disabled\n    return unless enabled?\n\n    errors.add :base, 'enabled_template_cannot_destroy'\n    throw :abort\n  end\n\n  #\n  # Class method\n  #\n  class << self\n    def visible_note_templates_condition(user_id:, project_id:, tracker_id:)\n      user = User.find(user_id)\n      project = Project.find(project_id)\n      user_project_roles = user.roles_for_project(project).pluck(:id)\n\n      base_condition = GlobalNoteTemplate.search_by_tracker(tracker_id)\n      base_condition = base_condition.search_by_project(project_id) unless apply_all_projects?\n\n      open_ids = base_condition.open.pluck(:id)\n      role_ids = base_condition.roles_condition(user_project_roles).pluck(:id)\n\n      # return uniq ids\n      ids = open_ids | role_ids\n      GlobalNoteTemplate.where(id: ids).includes(:global_note_visible_roles)\n    end\n\n    def get_templates_for_project_tracker(project_id, tracker_id = nil)\n      GlobalNoteTemplate.search_by_tracker(tracker_id)\n                        .search_by_project(project_id)\n                        .enabled\n                        .sorted\n    end\n\n    def plugin_setting\n      Setting.plugin_redmine_issue_templates\n    end\n\n    def apply_all_projects?\n      plugin_setting['apply_global_template_to_all_projects'].to_s == 'true'\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/global_note_template_project.rb",
    "content": "# frozen_string_literal: true\n\nclass GlobalNoteTemplateProject < ActiveRecord::Base\n  belongs_to :project\n  belongs_to :global_note_template, optional: true\nend\n"
  },
  {
    "path": "app/models/global_note_visible_role.rb",
    "content": "# frozen_string_literal: true\n\nclass GlobalNoteVisibleRole < ActiveRecord::Base\n  include Redmine::SafeAttributes\n\n  safe_attributes 'global_note_template_id', 'role_id'\n  belongs_to :role\n  belongs_to :global_note_template, optional: true\n\n  validates :role_id, presence: true\n  validates :global_note_template_id, presence: true\n\n  scope :search_by_note_template, lambda { |note_template_id|\n    where(global_note_template_id: note_template_id)\n  }\nend\n"
  },
  {
    "path": "app/models/issue_template.rb",
    "content": "# frozen_string_literal: true\n\nclass IssueTemplate < ActiveRecord::Base\n  include Redmine::SafeAttributes\n  include Concerns::IssueTemplate::Common\n  belongs_to :project\n  validates :project_id, presence: true\n  validates :title, uniqueness: { scope: :project_id }\n  acts_as_positioned scope: %i[project_id tracker_id]\n\n  # author and project should be stable.\n  safe_attributes 'title',\n                  'description',\n                  'tracker_id',\n                  'note',\n                  'enabled',\n                  'issue_title',\n                  'is_default',\n                  'enabled_sharing',\n                  'visible_children',\n                  'position',\n                  'related_link',\n                  'link_title',\n                  'builtin_fields_json'\n\n  scope :enabled_sharing, -> { where(enabled_sharing: true) }\n  scope :search_by_project, lambda { |prolect_id|\n    where(project_id: prolect_id)\n  }\n\n  module Config\n    JSON_OBJECT_NAME = 'issue_template'\n  end\n  Config.freeze\n\n  #\n  # In case set is_default and updated, others are also updated.\n  #\n  def check_default\n    return unless is_default? && is_default_changed?\n\n    self.class.search_by_project(project_id).search_by_tracker(tracker_id).update_all(is_default: false)\n  end\n\n  # return projects that use this template\n  def used_projects\n    return [] unless enabled_sharing\n\n    projects = project.descendants\n                      .joins(:trackers, :enabled_modules).merge(Tracker.where(id: tracker_id)).merge(EnabledModule.where(name: 'issue_templates'))\n    IssueTemplateSetting.where(project_id: projects).inherit_templates.select(:project_id)\n  end\n\n  #\n  # Class method\n  #\n  class << self\n    def get_inherit_templates(project_ids, tracker_id)\n      # keep ordering of project tree\n      IssueTemplate.search_by_project(project_ids)\n                   .search_by_tracker(tracker_id)\n                   .enabled\n                   .enabled_sharing\n                   .sorted\n    end\n\n    def get_templates_for_project_tracker(project_id, tracker_id = nil)\n      IssueTemplate.search_by_project(project_id)\n                   .search_by_tracker(tracker_id)\n                   .enabled\n                   .sorted\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/issue_template_setting.rb",
    "content": "class IssueTemplateSetting < ActiveRecord::Base\n  include Redmine::SafeAttributes\n  belongs_to :project\n\n  validates_uniqueness_of :project_id\n  validates_presence_of :project_id\n\n  safe_attributes 'help_message', 'enabled', 'inherit_templates', 'should_replaced'\n\n  scope :inherit_templates, -> { where(inherit_templates: true) }\n\n  def self.find_or_create(project_id)\n    setting = IssueTemplateSetting.where(project_id: project_id).first\n    unless setting.present?\n      setting = IssueTemplateSetting.new\n      setting.project_id = project_id\n      setting.save!\n    end\n    setting\n  end\n\n  #\n  # Class method\n  #\n  class << self\n    def apply_template_to_child_projects(project_id)\n      setting = find_setting(project_id)\n      setting.apply_template_to_child_projects\n    end\n\n    def unapply_template_from_child_projects(project_id)\n      setting = find_setting(project_id)\n      setting.unapply_template_from_child_projects\n    end\n\n    private\n\n    def find_setting(project_id)\n      raise ArgumentError, 'Please specify valid project_id.' if project_id.blank?\n\n      setting = IssueTemplateSetting.where(project_id: project_id).first\n      raise ActiveRecord::RecordNotFound if setting.blank?\n\n      setting\n    end\n  end\n\n  def enable_help?\n    enabled == true && !help_message.blank?\n  end\n\n  def enabled_inherit_templates?\n    inherit_templates\n  end\n\n  def child_projects\n    project.descendants\n  end\n\n  def apply_template_to_child_projects\n    update_inherit_template_of_child_projects(true)\n  end\n\n  def unapply_template_from_child_projects\n    update_inherit_template_of_child_projects(false)\n  end\n\n  def get_inherit_templates(tracker = nil)\n    return [] unless enabled_inherit_templates?\n\n    project_ids = project.ancestors.collect(&:id)\n    tracker = project.trackers.pluck(:tracker_id) if tracker.blank?\n\n    # first: get inherit_templates\n    IssueTemplate.get_inherit_templates(project_ids, tracker)\n  end\n\n  private\n\n  def update_inherit_template_of_child_projects(value)\n    IssueTemplateSetting.where(project_id: child_projects).update_all(inherit_templates: value)\n  end\nend\n"
  },
  {
    "path": "app/models/note_template.rb",
    "content": "# frozen_string_literal: true\n\nclass NoteTemplate < ActiveRecord::Base\n  include Redmine::SafeAttributes\n  include ActiveModel::Validations\n\n  class NoteTemplateError < StandardError; end\n\n  # author and project should be stable.\n  safe_attributes 'name', 'description', 'enabled', 'memo', 'tracker_id',\n                  'project_id', 'position', 'visibility'\n\n  attr_accessor :role_ids\n  validates :role_ids, presence: true, if: :roles?\n\n  belongs_to :project\n  belongs_to :author, class_name: 'User', foreign_key: 'author_id'\n  belongs_to :tracker\n\n  has_many :note_visible_roles, dependent: :nullify\n  has_many :roles, through: :note_visible_roles\n\n  validates :project_id, presence: true\n  validates :name, uniqueness: { scope: :project_id }\n  validates :name, presence: true\n  acts_as_positioned scope: %i[project_id tracker_id]\n\n  enum visibility: { mine: 0, roles: 1, open: 2 }\n\n  scope :mine_condition, lambda { |user_id|\n    where(author_id: user_id).mine if user_id.present?\n  }\n  scope :roles_condition, lambda { |role_ids|\n    joins(:note_visible_roles).where(note_visible_roles: { role_id: role_ids })\n  }\n\n  scope :enabled, -> { where(enabled: true) }\n  scope :sorted, -> { order(:position) }\n  scope :search_by_tracker, lambda { |tracker_id|\n    where(tracker_id: tracker_id) if tracker_id.present?\n  }\n  scope :search_by_project, lambda { |prolect_id|\n    where(project_id: prolect_id) if prolect_id.present?\n  }\n\n  before_save :check_visible_roles\n  after_save :note_visible_roles!\n  before_destroy :confirm_disabled\n\n  def <=>(other)\n    position <=> other.position\n  end\n\n  def template_json\n    template = {}\n    template['note_template'] = generate_json\n    template.to_json(root: true)\n  end\n\n  def generate_json\n    attributes\n  end\n\n  def note_visible_roles!\n    return unless roles?\n\n    if role_ids.blank?\n      raise NoteTemplateError, l(:please_select_at_least_one_role,\n                                 default: 'Please select at least one role.')\n    end\n\n    ActiveRecord::Base.transaction do\n      NoteVisibleRole.where(note_template_id: id).delete_all if note_visible_roles.present?\n      role_ids.each do |role_id|\n        NoteVisibleRole.create!(note_template_id: id, role_id: role_id)\n      end\n    end\n  end\n\n  def loadable?(user_id:)\n    return true if open?\n    return true if mine? && user_id == author_id\n\n    user_project_roles = User.find(user_id).roles_for_project(project).pluck(:id)\n    match_roles = user_project_roles & roles.ids\n    return true if roles? && !match_roles.empty?\n\n    false\n  end\n\n  private\n\n  def check_visible_roles\n    return if roles? || note_visible_roles.empty?\n\n    # Remove roles in case template visible scope is not \"roles\".\n    # This remove action is included the same transaction scope.\n    NoteVisibleRole.where(note_template_id: id).delete_all\n  end\n\n  def confirm_disabled\n    return unless enabled?\n\n    errors.add :base, 'enabled_template_cannot_destroy'\n    throw :abort\n  end\n\n  #\n  # Class method\n  #\n  class << self\n    def visible_note_templates_condition(user_id:, project_id:, tracker_id:)\n      user = User.find(user_id)\n      project = Project.find(project_id)\n      user_project_roles = user.roles_for_project(project).pluck(:id)\n\n      base_condition = NoteTemplate.search_by_project(project_id).search_by_tracker(tracker_id)\n\n      open_ids = base_condition.open.pluck(:id)\n      mine_ids = base_condition.mine_condition(user_id).pluck(:id)\n      role_ids = base_condition.roles_condition(user_project_roles).pluck(:id)\n\n      # return uniq ids\n      ids = open_ids | mine_ids | role_ids\n      NoteTemplate.where(id: ids).includes(:note_visible_roles)\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/note_visible_role.rb",
    "content": "# frozen_string_literal: true\n\nclass NoteVisibleRole < ActiveRecord::Base\n  include Redmine::SafeAttributes\n\n  safe_attributes 'note_template_id', 'role_id'\n  belongs_to :role\n  belongs_to :note_template, optional: true\n\n  validates :role_id, presence: true\n  validates :note_template_id, presence: true\n\n  scope :search_by_note_template, lambda { |note_template_id|\n    where(note_template_id: note_template_id)\n  }\nend\n"
  },
  {
    "path": "app/views/common/_nodata.html.erb",
    "content": "<% if trackers.blank? %>\n    <div class='nodata'>\n      <%= simple_format(l(:text_no_tracker_enabled)) %>\n    </div>\n<% end %>"
  },
  {
    "path": "app/views/common/_orphaned.html.erb",
    "content": "<h3 class='template_tracker'><%= l(:orphaned_template) %></h3>\n<table class='list issues template_list'>\n  <thead>\n  <tr>\n    <th>#</th>\n    <th class='hideable'><%= l(:issue_template_name) %></th>\n    <th><%= l(:label_preview) %></th>\n    <th class='hideable'><%= l(:field_tracker) %></th>\n    <th><%= l(:field_author) %></th>\n    <th class='hideable'><%= l(:field_updated_on) %></th>\n  </tr>\n  </thead>\n  <tbody>\n  <% orphaned_templates.each do |issue_template| %>\n      <tr class='<%= cycle('odd', 'even') %> issue_template issue'>\n        <td>\n          <%= link_to h(issue_template.id),\n              { controller: controller.controller_name, action: 'show',\n                id: issue_template.id,\n              }.merge(issue_template.try(:project_id) ? { project_id: issue_template.project } : {}),\n              { title: issue_template.note } %>\n        </td>\n        <td class='hideable template_title'>\n          <%= link_to h(issue_template.title),\n                      { controller: controller.controller_name,\n                        id: issue_template.id, action: 'show' },\n                      { title: \"#{html_escape(issue_template.note) }\"} %>\n        </td>\n        <td>\n          <div class='template_tooltip_wrapper'>\n            <a class='icon template_tooltip' title='<%= l(:label_preview) %>'></a>\n            <div class='wiki template_tooltip_body'>\n              <span class='title'><%= issue_template.title %></span>\n              <%= textilizable(issue_template.description) %>\n            </div>\n          </div>\n        </td>\n        <td class='hideable'><%= \"ID: #{issue_template.tracker_id}\" %></td>\n        <td><%=h issue_template.author %></td>\n        <td class='hideable'><%= format_time(issue_template.updated_on) %> </td>\n      </tr>\n      <tr class='<%= current_cycle %>' style='display: none;' id='template_description-<%= issue_template.id %>'>\n        <td class='description' colspan='8'>\n          <div class='wiki'><%= textilizable(issue_template.description) %></div></td>\n      </tr>\n  <% end %>\n  </tbody>\n</table>\n"
  },
  {
    "path": "app/views/common/_template_links.html.erb",
    "content": "<div style='display: flex; float: right; padding-top: 40px;\n                    position: relative; bottom: 6px; right: 0;'>\n    <div class='template_link_area'>\n      <label><%= l(:issue_template) %>: </label>\n      <%= link_to(l(:label_list_templates),\n                { controller: 'issue_templates',\n                  action: 'index',\n                  project_id: @project}, class: 'icon icon-template') %>   |\n      <%= link_to_if_authorized(l(:label_new_templates),\n                              { controller: 'issue_templates', action: 'new', project_id: @project },\n                              class: 'icon icon-add') %>\n    </div>\n    <div class='template_link_area'>\n      <label><%= l(:note_template) %>: </label>\n      <%= link_to(l(:label_list_templates),\n                { controller: 'note_templates',\n                  action: 'index',\n                  project_id: @project}, class: 'icon icon-template') %>   |\n      <%= link_to_if_authorized(l(:label_new_templates),\n                              { controller: 'note_templates', action: 'new', project_id: @project },\n                              class: 'icon icon-add') %>\n    </div>\n\n    <div class='template_link_area'>\n      <label><%= l(:issue_templates_optional_settings, default: 'Templates Optional Settings') %>: </label>\n      <%= link_to_if_authorized(l(:label_settings, default: 'Settings'),\n                              { controller: 'issue_templates_settings', action: 'index', project_id: @project },\n                              class: 'icon icon-settings') %>\n    </div>\n</div>\n"
  },
  {
    "path": "app/views/global_issue_templates/_form.html.erb",
    "content": "<%= error_messages_for 'global_issue_template' %>\n<div class='box tabular box-white'>\n  <p><%= f.text_field :title, required: true, size: 80, label: l(:issue_template_name) %></p>\n\n  <fieldset class='issue'>\n    <legend class='issue'><%= l(:label_applied_for_issue) %></legend>\n    <p>\n      <% if issue_template.tracker.blank? %>\n          <%= f.select :tracker_id, trackers.collect { |t| [t.name, t.id] }, { required: true },\n                       required: true, label: l(:label_tracker) %>\n\n          <%= h issue_template.tracker.present? ? issue_template.tracker.name :\n                    l(:orphaned_template, default: 'Orphaned template from tracker') %>\n\n      <% else %>\n          <%= f.select :tracker_id, trackers.collect { |t| [t.name, t.id] }, { required: true },\n                       required: true, label: l(:label_tracker), selected: issue_template.tracker.id %>\n      <% end %>\n    </p>\n    <p><%= f.text_field :issue_title, required: false, size: 80, label: l(:issue_title) %>\n      <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n         data-tooltip-area='issue_title_help_area'\n         data-tooltip-content='issue_title_help_content'>\n        <%= l(:help_for_this_field) %>\n        <span class='tooltip-area' id='issue_title_help_area'></span>\n      </a>\n    </p>\n    <p>\n      <%= f.text_area :description, cols: 78, rows: 12,\n                      required: true,\n                      label: l(:issue_description), class: 'wiki-edit', style: 'overflow: auto;' %>\n    </p>\n\n    <!-- for Builtin Fields -->\n    <!-- buildin field Generator -->\n    <% if builtin_fields_enable %>\n    <div id=\"json_generator\">\n      <p>\n        <label><%= l(:label_select_field, default: 'Select a field') %></label>\n        <select v-model='newItemTitle'>\n          <option v-for='(value, key) in customFields' v-bind:value='key'>\n           {{ value.name }}\n          </option>\n        </select>\n        <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n         data-tooltip-area='builtin_fields_help_area'\n         data-tooltip-content='builtin_fields_help_content'>\n           <%= l(:help_for_this_field) %>\n          <span class='tooltip-area' id='builtin_fields_help_area'></span>\n        </a>\n      </p>\n      <p>\n          <label><%= l(:field_value) %></label>\n          <textarea id='issue_template_json_setting_field' v-if='fieldFormat() == \"text\"' rows=6\n              placeholder='<%= l(:enter_value, default: 'Please enter a value') %>' v-model='newItemValue'>\n          </textarea>\n\n          <input id='issue_template_json_setting_field' v-if='fieldFormat() == \"string\"'\n              type='text'\n              placeholder='<%= l(:enter_value, default: 'Please enter a value') %>' v-model='newItemValue'>\n\n          <input id='issue_template_json_setting_field' v-if='fieldFormat() == \"int\"'\n              :max='customFields[newItemTitle].max_length' :min='customFields[newItemTitle].min_length'\n              type=\"number\" placeholder='<%= l(:enter_value, default: 'Please enter a value') %>' v-model='newItemValue'>\n\n          <input type='date' id='issue_template_json_setting_field' v-if='fieldFormat() == \"date\"' v-model='newItemValue'>\n\n          <select v-model='newItemValue' v-if='fieldFormat() == \"ratio\"'>\n            <option v-for=\"ratio in [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]\">{{ ratio }} %</option>\n          </select>\n\n          <select v-model='newItemValue' :multiple='customFields[newItemTitle].multiple == true'\n            v-if='fieldFormat() == \"list\" || fieldFormat() == \"bool\"'>\n            <option v-for=\"value in possibleValues()\">{{ value }}</option>\n          </select>\n          <span style='margin-left: 4px;' class='icon icon-add' v-on:click='addField(newItemTitle, newItemValue)'>\n            <%= l(:button_add) %>\n          </span>\n      </p>\n      <div id='field_information' class='wiki' v-if='newItemTitle != \"\"'>\n        <b><%= l(:label_field_information, default: 'Field information') %></b>\n        <a v-if='customFieldUrl' v-bind:href=\"customFieldUrl\" target=\"_blank\" rel=\"noopener\" class=\"icon icon-custom-fields\">\n          <%= l(:label_custom_field, default: 'Custom field') %>:  {{ customFields[newItemTitle].name }}\n        </a>\n        <pre>{{ customFields[newItemTitle] }}</pre>\n      </div>\n      <div id='fields_setting_display_area'>\n        <ul class='json-list' v-if='items.length > 0'>\n          <li v-for='item in items'>\n            <span v-if='customFields[item.title]'>\n              <b>{{ customFields[item.title].name }}</b>: {{ item.value }} / {{ item.title }}\n            </span>\n            <span v-if='!customFields[item.title]'>\n              <i class='issue_template help_content'>\n                <%= l(:unavailable_fields_for_this_tracker, default: 'Unavailable field for this tarcker') %>\n              : {{ item.value }} / {{ item.title }}\n              </i>\n            </span>\n            <i class='icon icon-del' v-on:click='deleteField(item)'></i>\n          </li>\n        </ul>\n        <pre id='builtin_fields_data_via_vue' style='display: none;'>{{ items }}</pre>\n        <span class='icon icon-reload' id='reset-json' v-on:click='loadField()'><%= l(:button_reset) %></span>\n        <span class='icon icon-checked' id='paste-json'><%= l(:button_apply) %></span>\n      </div>\n      <!-- buildin field Generator -->\n      <p style='opacity: 0.6;'>\n        <%= f.text_area :builtin_fields,\n            required: false, cols: 60, rows: 4,\n            label: l(:label_builtin_fields_json, default: 'JSON for fields') %>\n      </p>\n      <div id='builtin_fields_help_content' class='wiki' style='display: none;'>\n        <%= l(:label_builtin_fields_help_message, default: 'Enter builtin filds or custom fields default values with JSON format. ') %>\n      </div>\n    </div>\n    <% end %>\n    <!-- for Builtin Fields -->\n\n  </fieldset>\n  <p>\n    <%= f.text_area :note, cols: 70, rows: 3,\n                    required: false,\n                    label: l(:issue_template_note), style: 'overflow:auto;' %>\n  </p>\n\n  <p><%= f.text_field :related_link, type: 'url',\n          size: 70, label: l(:issue_template_related_link, default: 'Related link') %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-template-help-target='related_link_help_content'\n       data-tooltip-area='related_link_help_area'\n       data-tooltip-content='related_link_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='related_link_help_area'></span>\n    </a>\n  </p>\n\n  <p id='link_title_paragraph'><%= f.text_field :link_title, size: 70, label: l(:issue_template_link_title, default: 'Link title') %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-template-help-target='link_title_help_content'\n       data-tooltip-area='link_title_help_area'\n       data-tooltip-content='link_title_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='link_title_help_area'></span>\n    </a>\n  </p>\n\n  <p><%= f.check_box :is_default, label: l(:field_is_default) %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-template-help-target='isdefault_help_content'\n       data-tooltip-area='isdefault_help_area'\n       data-tooltip-content='isdefault_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='isdefault_help_area'></span>\n    </a>\n  </p>\n\n  <p><%= f.check_box :enabled, label: l(:label_enabled) %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-template-help-target='enabled_help_content'\n       data-tooltip-area='enabled_help_area'\n       data-tooltip-content='enabled_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='enabled_help_area'></span>\n    </a>\n  </p>\n</div>\n\n<%= wikitoolbar_for 'global_issue_template_description' %>\n\n\n<!-- tooltip content -->\n<div id='issue_title_help_content' class='wiki' style='display: none;'>\n  <%= l(:help_for_issue_title) %>\n</div>\n<div id='isdefault_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_isdefault_help_message) %>\n</div>\n<div id='related_link_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_related_link_help_message, default: 'If there are some example pages or sample issues which using issue template, please specify the link. So operator can see them as an usage or example for template.') %>\n</div>\n<div id='link_title_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_link_title_help_message, default: 'If there are some example pages or sample issues which using issue template, please specify the link. So operator can see them as an usage or example for template.') %>\n</div>\n<div id='enabled_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_enabled_help_message) %>\n</div>\n<!-- tooltip content -->\n\n<div class='box'>\n  <% if apply_all_projects %>\n      <p>\n        <i class='issue_template icon settings'></i>\n        <span class='issue_template help_content'>\n          <%= l(:note_apply_global_template_to_all_projects_setting_enabled) %>\n        </span>\n        (\n        <%= link_to(l(:label_settings),\n                    { controller: 'settings', action: 'plugin', id: 'redmine_issue_templates' },\n                    class: 'issue_template icon plugins') %> )\n      </p>\n  <% end %>\n  <% if projects.any? %>\n      <fieldset class='box box-white' id='global_issue_template_project_ids'\n                style='<%= apply_all_projects ? 'opacity: 0.6' : '' %>'>\n        <a class='collapsible collapsed template-help' data-template-help-target='all_projects'>\n          <%= l(:project_list_associated_this_template, { applied: issue_template.projects.length, all: projects.length }) %>\n        </a>\n        <div id='all_projects' style='display: none;'>\n        <p><%= check_all_links 'global_issue_template_project_ids' %></p>\n        <legend><%= l(:label_project_plural) %></legend>\n        <%= render_project_nested_lists(projects) do |p|\n          content_tag('label', check_box_tag('global_issue_template[project_ids][]',\n                                             p.id, issue_template.projects.to_a.include?(p),\n                                             id: nil, disabled: apply_all_projects,\n                                             checked: issue_template.projects.to_a.include?(p) ) + ' ' + h(p))\n        end %>\n        </div>\n      </fieldset>\n  <% end %>\n  <%= hidden_field_tag 'global_issue_template[project_ids][]', '' %>\n</div>\n\n<%= submit_tag l(issue_template.new_record? ? :button_create : :button_save) %>\n<%= link_to l(:button_cancel), { action: 'index' }, data: { confirm: l(:text_are_you_sure) } %>\n\n<script>\n  const baseUrl = \"<%= url_for(controller: 'issue_templates', action: 'load_selectable_fields') %>\"\n  const templateId = \"<%= issue_template&.id || '' %>\"\n  const templateType = 'global_issue_template'\n  const trackerPulldownId = templateType + '_tracker_id'\n  const base_builtin_fields = <%= issue_template.builtin_fields.html_safe %>\n  const base_custom_fields = <%= custom_fields.html_safe %>\n  const relativeUrlRoot = \"<%= Redmine::Utils.relative_url_root %>\"\n</script>\n\n<% if builtin_fields_enable %>\n<%= javascript_include_tag('vue.min', plugin: 'redmine_issue_templates') %>\n<%= javascript_include_tag('template_fields', plugin: 'redmine_issue_templates') %>\n<% end %>\n\n"
  },
  {
    "path": "app/views/global_issue_templates/index.html.erb",
    "content": "<h2 class='global_issue_template'><%=h \"#{l(:global_issue_templates)}\" %></h2>\n<%= render partial: 'common/nodata', locals: { trackers: trackers } %>\n<div class='contextual issue_templates'>\n  <%= link_to(l(:label_new_templates),\n              { controller: 'global_issue_templates', action: 'new' }, class: 'icon icon-add') %>\n  <%= link_to(l(:global_note_templates, default: 'Global Note Templates'),\n              { controller: 'global_note_templates', action: 'index' },\n              class: 'icon icon-template') %>\n  <%= link_to(l(:label_settings),\n              { controller: 'settings', action: 'plugin', id: 'redmine_issue_templates' },\n              class: 'issue_template icon plugins') %>\n</div>\n<div style='clear: both;'></div>\n\n<% if template_map.blank? %>\n    <div class='template_box'>\n      <%= l(:no_issue_templates_for_this_redmine) %>\n    </div>\n<% end %>\n<% template_map.each_key do |tracker| %>\n    <div class='template_box'>\n      <h3 class='template_tracker'><%= tracker.name %></h3>\n\n      <table class='list issues template_list ui-sortable table-sortable'>\n        <thead>\n        <tr>\n          <th>#</th>\n          <th class='hideable'><%= l(:issue_template_name) %></th>\n          <th><%= l(:label_preview) %></th>\n          <th class='hideable'><%= l(:field_tracker) %></th>\n          <th class='hideable'><%= l(:field_author) %></th>\n          <th class='hideable'><%= l(:field_updated_on) %></th>\n          <th><%= l(:field_is_default) %></th>\n          <th><%= l(:label_enabled) %></th>\n          <th><%=l(:button_sort)%></th>\n        </tr>\n        </thead>\n        <tbody>\n        <% template_map[tracker].sorted.each do |issue_template| %>\n            <tr class='<%= cycle('odd', 'even') %> issue_template issue'>\n              <td><%= link_to h(issue_template.id), { controller: 'global_issue_templates',\n                                                      id: issue_template.id, action: 'show' },\n                              { title: issue_template.title } %>\n              </td>\n              <td class='hideable template_title'>\n                <%= link_to h(issue_template.title), { controller: 'global_issue_templates',\n                                                         id: issue_template.id, action: 'show' },\n                              { title: \"#{html_escape(issue_template.note)}\" } %>\n              </td>\n              <td>\n                <div class='template_tooltip_wrapper'>\n                  <a class='icon template_tooltip' title='<%= l(:label_preview) %>'></a>\n                  <div class='wiki template_tooltip_body'>\n                    <span class='title'><%= issue_template.title %></span>\n                    <%= textilizable(issue_template.description) %>\n                    <% if issue_template.related_link.present? %>\n                      <hr/>\n                      <%= link_to issue_template.link_title.present? ? issue_template.link_title : l(:issue_template_related_link, default: 'Related link'),\n                          issue_template.related_link, target: '_blank', rel: 'nofollow noopener', class: 'external' %>\n                    <% end %>\n                  </div>\n                </div>\n                </a>\n              </td>\n              <td class='hideable'><%=h issue_template.tracker.name %></td>\n              <td class='hideable'><%=h issue_template.author %></td>\n              <td class='hideable'><%= format_time(issue_template.updated_on)%> </td>\n              <td class='center'><%= checked_image issue_template.is_default? %></td>\n              <td class='center'><%= checked_image issue_template.enabled? %></td>\n\n              <td class='buttons'>\n                <%= reorder_handle(issue_template, :url => url_for({ controller: 'global_issue_templates',\n                                                             id: issue_template.id, action: 'update' })) %>\n              </td>\n            </tr>\n        <% end %>\n        </tbody>\n      </table>\n    </div>\n\n    <%= javascript_tag do %>\n      // NOTE: Sortable feature depends on Redmine's sorting jQuery plugin.\n      $(function() { $('table.table-sortable tbody').positionedItems() })\n    <% end %>\n<% end %>\n\n<a id='orphaned_template_link' class='icon template_tooltip orphaned_template_link template-help collapsible collapsed'\n  title='<%= l(:orphaned_templates) %>'\n  data-template-help-target='orphaned_templates'\n  data-url='<%= orphaned_templates_global_issue_templates_path %>'>\n  <%= l(:orphaned_templates, default: 'Orphaned Templates') %>\n</a>\n\n<div id='orphaned_templates' style='display: none'></div>\n\n"
  },
  {
    "path": "app/views/global_issue_templates/new.html.erb",
    "content": "<div class='contextual'>\n  <%= link_to(l(:label_list_templates),\n              { controller: 'global_issue_templates', action: 'index' }, class: 'icon icon-template') %>\n</div>\n<h2 class='global_issue_template'><%=h \"#{l(:issue_templates)} / #{l(:button_add)}\" %></h2>\n\n<%= labelled_form_for :global_issue_template,  issue_template,\n                      url: { controller: 'global_issue_templates', action: 'create' },\n                      html: { id: 'global_issue_template-form',\n                                  class: nil, multipart: false } do |f| %>\n\n  <%= render 'form', { f: f, trackers: trackers, projects: projects,\n                        issue_template: issue_template, apply_all_projects: apply_all_projects,\n                        custom_fields: custom_fields, builtin_fields_enable: builtin_fields_enable } %>\n<% end %>\n"
  },
  {
    "path": "app/views/global_issue_templates/show.html.erb",
    "content": "<div class='contextual'>\n<%= link_to l(:button_delete),\n  { controller: 'global_issue_templates', action: 'destroy', id: issue_template },\n    data: { confirm: l(:text_are_you_sure) },\n    title: l(:enabled_template_cannot_destroy, default: 'Only disabled template can be destroyed.'),\n    disabled: issue_template.enabled?, method: 'delete', class: 'icon icon-del template-disabled-link' %>\n<%= link_to(l(:label_list_templates),\n              { controller: 'global_issue_templates', action: 'index' }, class: 'icon icon-template') %>\n</div>\n\n<h2 class='global_issue_template'>\n  <%= l(:global_issue_templates, default: 'Global Template for note') %>: #<%= issue_template.id %> <%= issue_template.title %>\n  <%= avatar(issue_template.author, size: '24') %>\n</h2>\n\n<%= labelled_form_for :global_issue_template,\n                      issue_template,\n                      url: { controller: 'global_issue_templates', action: 'update', id: issue_template },\n                      html: { id: 'global_issue_template-form', class: nil,\n                              multipart: false } do |f| %>\n  <%= render 'form', { f: f, trackers: trackers,\n                        issue_template: issue_template, projects: projects, apply_all_projects: apply_all_projects,\n                        custom_fields: custom_fields, builtin_fields_enable: builtin_fields_enable } %>\n<% end %>\n"
  },
  {
    "path": "app/views/global_note_templates/_form.html.erb",
    "content": "<%= error_messages_for 'global_note_template' %>\n<div class='box tabular box-white'>\n  <p><%= f.text_field :name, required: true, size: 80, label: l(:issue_template_name) %></p>\n\n  <fieldset class='issue'>\n    <legend class='issue'><%= l(:label_applied_for_issue) %></legend>\n    <p>\n      <% if note_template.tracker.blank? %>\n          <%= f.select :tracker_id, trackers.collect { |t| [t.name, t.id] }, { required: true },\n                       required: true, label: l(:label_tracker) %>\n\n          <%= h note_template.tracker.present? ? note_template.tracker.name :\n                    l(:orphaned_template, default: 'Orphaned template from tracker') %>\n      <% else %>\n          <%= f.select :tracker_id, trackers.collect { |t| [t.name, t.id] }, { required: true },\n                       required: true, label: l(:label_tracker), selected: note_template.tracker.id %>\n      <% end %>\n    </p>\n    <p>\n      <%= f.text_area :description, cols: 78, rows: 12,\n                      required: true,\n                      label: l(:label_comment), class: 'wiki-edit' %>\n    </p>\n\n    <p>\n      <%= f.select :visibility, GlobalNoteTemplate.visibilities.map { |k, v| [t(\"note_templates.visibility.#{k}\"), k] },\n            selected: note_template.visibility,\n            required: true, label: l(:field_template_visibility) %>\n    </p>\n    <p id='visible_roles_checkbox'\n      style='display: <%= note_template.visibility == 'roles' ? 'block;' : 'none;' %>'>\n      <label for='global_note_visible_roles[role_ids]'><%= l(:label_role) %></label>\n         <% Role.givable.each do |role| %>\n          <%= check_box_tag('global_note_template[role_ids][]',\n                        role.id,\n                        note_template.global_note_visible_roles.pluck(:role_id).to_a.include?(role.id)) %>\n          <%= role.name %>\n        <% end %>\n    </p>\n  </fieldset>\n  <p>\n    <%= f.text_area :memo, cols: 70, rows: 3,\n                    required: false,\n                    label: l(:issue_template_note) %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-tooltip-area='memo_help_area'\n       data-tooltip-content='memo_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='memo_help_area'></span>\n    </a>\n  </p>\n\n  <p>\n    <%= f.check_box :enabled, label: l(:label_enabled) %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-tooltip-area='enabled_help_area'\n       data-tooltip-content='enabled_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='enabled_help_area'></span>\n    </a>\n  </p>\n</div>\n\n<%= wikitoolbar_for 'global_note_template_description' %>\n\n<!-- help content -->\n<div id='issue_title_help_content' class='wiki' style='display: none;'>\n  <%= l(:help_for_issue_title) %>\n</div>\n\n<div id='enabled_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_enabled_help_message) %>\n</div>\n\n<div id='memo_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_memo_help_message, default: 'Please set up a note explaining when applying this template.') %>\n</div>\n<!-- help content -->\n\n<div class='box'>\n  <% if apply_all_projects %>\n      <p>\n        <i class='issue_template icon settings'></i>\n        <span class='issue_template help_content'>\n          <%= l(:note_apply_global_template_to_all_projects_setting_enabled) %>\n        </span>\n        (\n        <%= link_to(l(:label_settings),\n                    { controller: 'settings', action: 'plugin', id: 'redmine_issue_templates' },\n                    class: 'issue_template icon plugins') %> )\n      </p>\n  <% end %>\n  <% if projects.any? %>\n      <fieldset class='box box-white' id='global_note_template_project_ids'\n                style='<%= apply_all_projects ? 'opacity: 0.6' : '' %>'>\n        <a class='collapsible collapsed template-help' data-template-help-target='all_projects'>\n          <%= l(:project_list_associated_this_template, { applied: note_template.projects.length, all: projects.length }) %>\n        </a>\n        <div id='all_projects' style='display: none;'>\n        <p><%= check_all_links 'global_note_template_project_ids' %></p>\n        <legend><%= l(:label_project_plural) %></legend>\n        <%= render_project_nested_lists(projects) do |p|\n          content_tag('label', check_box_tag('global_note_template[project_ids][]',\n                                             p.id, note_template.projects.to_a.include?(p),\n                                             id: nil, disabled: apply_all_projects,\n                                             checked: note_template.projects.to_a.include?(p) ) + ' ' + h(p))\n        end %>\n        </div>\n      </fieldset>\n  <% end %>\n  <%= hidden_field_tag 'global_note_template[project_ids][]', '' %>\n</div>\n\n\n<script type='text/javascript'>\n  const visibility_select = document.getElementById('global_note_template_visibility')\n  const roles_checkbox = document.getElementById('visible_roles_checkbox')\n\n  visibility_select.addEventListener('change', (e) => {\n    if (e.target.value == 'roles') {\n      roles_checkbox.style.display = 'block'\n    } else {\n      roles_checkbox.style.display = 'none'\n    }\n  })\n</script>\n"
  },
  {
    "path": "app/views/global_note_templates/index.html.erb",
    "content": "<h2 class='global_note_template'><%=h \"#{l(:global_note_templates, default: 'Global Note Templates')}\" %></h2>\n<%= render partial: 'common/nodata', locals: { trackers: trackers } %>\n<div class='contextual issue_templates'>\n  <%= link_to(l(:label_new_templates),\n              { controller: 'global_note_templates', action: 'new' }, class: 'icon icon-add') %>\n  <%= link_to(l(:global_issue_templates),\n              { controller: 'global_issue_templates', action: 'index' },\n              class: 'icon icon-template') %>\n  <%= link_to(l(:label_settings),\n              { controller: 'settings', action: 'plugin', id: 'redmine_issue_templates' },\n              class: 'issue_template icon plugins') %>\n</div>\n<div style='clear: both;'></div>\n\n<% if template_map.blank? %>\n    <div class='template_box'>\n      <%= l(:no_note_templates_for_this_redmine, default: 'No global note templates are defined for this Redmine site.') %>\n    </div>\n<% end %>\n\n<% template_map.each_key do |tracker| %>\n    <div class='template_box'>\n      <h3 class='template_tracker'><%= tracker.name %></h3>\n\n      <table class='list template_list issues ui-sortable table-sortable'>\n        <thead>\n        <tr>\n          <th>#</th>\n          <th class='hideable'><%= l(:issue_template_name) %></th>\n          <th><%= l(:label_preview) %></th>\n          <th class='hideable'><%= l(:field_tracker) %></th>\n          <th class='hideable'><%= l(:field_author) %></th>\n          <th class='hideable'><%= l(:field_updated_at) %></th>\n          <th><%= l(:label_enabled) %></th>\n          <th><%=l(:button_sort)%></th>\n        </tr>\n        </thead>\n        <tbody>\n        <% template_map[tracker].sorted.each do |note_template| %>\n            <tr class='<%= cycle('odd', 'even') %> issue_template issue'>\n              <td><%= link_to h(note_template.id), { controller: 'global_note_templates',\n                                                      id: note_template.id, action: 'show' },\n                              { title: note_template.name } %>\n              </td>\n              <td class='hideable template_title'>\n                <%= link_to h(note_template.name), { controller: 'global_note_templates',\n                                                         id: note_template.id, action: 'show' },\n                              { title: \"#{html_escape(note_template.memo)}\" } %>\n              </td>\n              <td>\n                <div class='template_tooltip_wrapper'>\n                  <a class='icon template_tooltip' title='<%= l(:label_preview) %>'></a>\n                  <div class='wiki template_tooltip_body'>\n                    <span class='title'><%= note_template.name %></span>\n                    <%= textilizable(note_template.description) %>\n                  </div>\n                </div>\n                </a>\n              </td>\n              <td class='hideable'><%=h note_template.tracker.name %></td>\n              <td class='hideable'><%=h note_template.author %></td>\n              <td class='hideable'><%= format_time(note_template.updated_at)%> </td>\n              <td class='center'><%= checked_image note_template.enabled? %></td>\n\n              <td class='buttons'>\n                <%= reorder_handle(note_template, :url => url_for({ controller: 'global_note_templates',\n                                                             id: note_template.id, action: 'update' })) %>\n              </td>\n            </tr>\n        <% end %>\n        </tbody>\n      </table>\n    </div>\n\n    <%= javascript_tag do %>\n      // NOTE: Sortable feature depends on Redmine's sorting jQuery plugin.\n      $(function() { $('table.table-sortable tbody').positionedItems() })\n    <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/global_note_templates/new.html.erb",
    "content": "<div class='contextual'>\n  <%= link_to(l(:label_list_templates),\n              { controller: 'global_note_templates', action: 'index' }, class: 'icon icon-template') %>\n</div>\n<h2 class='global_note_template'><%=h \"#{l(:global_note_templates, default: 'Global Template for note') } / #{l(:button_add)}\" %></h2>\n\n<%= labelled_form_for :global_note_template,  note_template,\n                      url: { controller: 'global_note_templates', action: 'create' },\n                      html: { id: 'global_note_template-form', class: nil, multipart: false } do |f| %>\n\n  <%= render 'form', { f: f, trackers: trackers,\n                       note_template: note_template, projects: projects, apply_all_projects: apply_all_projects } %>\n    <div id='preview' class='wiki'></div>\n    <%= submit_tag l(:button_create) %>\n    <%= link_to l(:button_cancel), { action: 'index'}, data: { confirm: l(:text_are_you_sure) } %>\n<% end %>\n"
  },
  {
    "path": "app/views/global_note_templates/show.html.erb",
    "content": "<div class='contextual'>\n<%= link_to l(:button_delete),\n  { controller: 'global_note_templates', action: 'destroy', id: note_template },\n    data: { confirm: l(:text_are_you_sure) },\n    name: l(:enabled_template_cannot_destroy, default: 'Only disabled template can be destroyed.'),\n    disabled: note_template.enabled?, method: 'delete', class: 'icon icon-del template-disabled-link' %>\n<%= link_to(l(:label_list_templates),\n              { controller: 'global_note_templates', action: 'index' }, class: 'icon icon-template') %>\n</div>\n\n<h2 class='global_note_template'>\n  <%= l(:global_note_templates) %>: #<%= note_template.id %> <%= note_template.name %>\n  <%= avatar(note_template.author, size: '24') %>\n</h2>\n\n<%= labelled_form_for :global_note_template,\n                      note_template,\n                      url: { controller: 'global_note_templates', action: 'update', id: note_template },\n                      html: { id: 'global_note_template-form', class: nil,\n                              multipart: false } do |f| %>\n  <%= render 'form', { f: f, trackers: trackers,\n                        note_template: note_template, projects: projects, apply_all_projects: apply_all_projects } %>\n  <div id='preview' class='wiki'></div>\n  <%= submit_tag l(:button_save) %>\n  <%= link_to l(:button_cancel), { action: 'index' },\n      onclick: 'Element.hide(\"edit-note_template\"); return false' %>\n<% end %>\n"
  },
  {
    "path": "app/views/issue_templates/_form.html.erb",
    "content": "<%= error_messages_for 'issue_template' %>\n<div class='box tabular box-white'>\n  <p><%= f.text_field :title, required: true, size: 80, label: l(:issue_template_name) %></p>\n\n  <fieldset class='issue'>\n    <legend class='issue'><%= l(:label_applied_for_issue) %></legend>\n    <p>\n      <% if issue_template.tracker.blank? %>\n          <%= f.select :tracker_id, template_target_trackers(project, issue_template),\n                       required: true, label: l(:label_tracker), include_blank: true  %>\n\n          <%= h issue_template.tracker.present? ? issue_template.tracker.name :\n                    l(:orphaned_template, default: 'Orphaned template from tracker') %>\n\n      <% else %>\n          <%= f.select :tracker_id, template_target_trackers(project, issue_template),\n                       required: true, label: l(:label_tracker), selected: issue_template.tracker.id %>\n          <% unless project_tracker?(issue_template.tracker, project) %><br/>\n              <%= non_project_tracker_msg(project_tracker?(issue_template.tracker, project)) %>\n          <% end %>\n      <% end %>\n    </p>\n    <p><%= f.text_field :issue_title, required: false, size: 80, label: l(:issue_title) %>\n      <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n         data-tooltip-area='issue_title_help_area'\n         data-tooltip-content='issue_title_help_content'>\n        <%= l(:help_for_this_field) %>\n        <span class='tooltip-area' id='issue_title_help_area'></span>\n      </a>\n    </p>\n    <p>\n      <%= f.text_area :description, cols: 78, rows: 12,\n                      required: true,\n                      label: l(:issue_description), class: 'wiki-edit', style: 'overflow: auto;' %>\n    </p>\n\n    <!-- for Builtin Fields -->\n    <!-- buildin field Generator -->\n    <% if builtin_fields_enable %>\n    <div id=\"json_generator\">\n      <p>\n        <label><%= l(:label_select_field, default: 'Select a field') %></label>\n        <select v-model='newItemTitle' id='field_selector'>\n          <option v-for='(value, key) in customFields' v-bind:value='key'>\n           {{ value.name }}\n          </option>\n        </select>\n        <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n         data-tooltip-area='builtin_fields_help_area'\n         data-tooltip-content='builtin_fields_help_content'>\n           <%= l(:help_for_this_field) %>\n          <span class='tooltip-area' id='builtin_fields_help_area'></span>\n        </a>\n      </p>\n      <p>\n          <label for='value_selector'><%= l(:field_value) %></label>\n          <textarea id='issue_template_json_setting_field' v-if='fieldFormat() == \"text\"' rows=6\n              placeholder='<%= l(:enter_value, default: 'Please enter a value') %>' v-model='newItemValue'>\n          </textarea>\n\n          <input id='issue_template_json_setting_field' v-if='fieldFormat() == \"string\"'\n              type='text'\n              placeholder='<%= l(:enter_value, default: 'Please enter a value') %>' v-model='newItemValue'>\n\n          <input id='issue_template_json_setting_field' v-if='fieldFormat() == \"int\"'\n              :max='customFields[newItemTitle].max_length' :min='customFields[newItemTitle].min_length'\n              type=\"number\" placeholder='<%= l(:enter_value, default: 'Please enter a value') %>' v-model='newItemValue'>\n\n          <input type='date' id='issue_template_json_setting_field' v-if='fieldFormat() == \"date\"' v-model='newItemValue'>\n\n          <select v-model='newItemValue' v-if='fieldFormat() == \"ratio\"'>\n            <option v-for=\"ratio in [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]\">{{ ratio }} %</option>\n          </select>\n\n          <select v-model='newItemValue' :multiple='customFields[newItemTitle].multiple == true'\n            v-if='fieldFormat() == \"list\" || fieldFormat() == \"bool\"' id='value_selector'>\n            <option v-for=\"value in possibleValues()\">{{ value }}</option>\n          </select>\n          <span style='margin-left: 4px;' class='icon icon-add' v-on:click='addField(newItemTitle, newItemValue)'>\n            <%= l(:button_add) %>\n          </span>\n      </p>\n      <div id='field_information' class='wiki' v-if='newItemTitle != \"\"'>\n        <b><%= l(:label_field_information, default: 'Field information') %></b>\n        <pre>{{ customFields[newItemTitle] }}</pre>\n      </div>\n      <div id='fields_setting_display_area'>\n        <ul class='json-list' v-if='items.length > 0'>\n          <li v-for='item in items'>\n            <span v-if='customFields[item.title]'>\n              <b>{{ customFields[item.title].name }}</b>: {{ item.value }} / {{ item.title }}\n            </span>\n            <span v-if='!customFields[item.title]'>\n              <i class='issue_template help_content'>\n                <%= l(:unavailable_fields_for_this_tracker, default: 'Unavailable field for this tarcker') %>\n              : {{ item.value }} / {{ item.title }}\n              </i>\n            </span>\n            <i class='icon icon-del' v-on:click='deleteField(item)'></i>\n          </li>\n        </ul>\n        <pre id='builtin_fields_data_via_vue' style='display: none;'>{{ items }}</pre>\n        <span class='icon icon-reload' id='reset-json' v-on:click='loadField()'><%= l(:button_reset) %></span>\n        <span class='icon icon-checked' id='paste-json'><%= l(:button_apply) %></span>\n      </div>\n      <!-- buildin field Generator -->\n      <p style='opacity: 0.6;'>\n        <%= f.text_area :builtin_fields,\n            required: false, cols: 60, rows: 4,\n            label: l(:label_builtin_fields_json, default: 'JSON for fields') %>\n      </p>\n      <div id='builtin_fields_help_content' class='wiki' style='display: none;'>\n        <%= l(:label_builtin_fields_help_message, default: 'Enter builtin filds or custom fields default values with JSON format. ') %>\n      </div>\n    </div>\n    <% end %>\n    <!-- for Builtin Fields -->\n\n  </fieldset>\n  <p>\n    <%= f.text_area :note, cols: 70, rows: 3,\n                    required: false,\n                    label: l(:issue_template_note), style: 'overflow:auto;' %>\n  </p>\n\n  <p><%= f.text_field :related_link, type: 'url',\n          size: 70, label: l(:issue_template_related_link, default: 'Related link') %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-template-help-target='related_link_help_content'\n       data-tooltip-area='related_link_help_area'\n       data-tooltip-content='related_link_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='related_link_help_area'></span>\n    </a>\n  </p>\n\n  <p id='link_title_paragraph'><%= f.text_field :link_title, size: 70, label: l(:issue_template_link_title, default: 'Link title') %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-template-help-target='link_title_help_content'\n       data-tooltip-area='link_title_help_area'\n       data-tooltip-content='link_title_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='link_title_help_area'></span>\n    </a>\n  </p>\n\n  <p><%= f.check_box :is_default, label: l(:field_is_default) %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-template-help-target='isdefault_help_content'\n       data-tooltip-area='isdefault_help_area'\n       data-tooltip-content='isdefault_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='isdefault_help_area'></span>\n    </a>\n  </p>\n\n  <p><%= f.check_box :enabled, label: l(:label_enabled) %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-template-help-target='enabled_help_content'\n       data-tooltip-area='enabled_help_area'\n       data-tooltip-content='enabled_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='enabled_help_area'></span>\n    </a>\n  </p>\n  <p>\n    <%= f.check_box :enabled_sharing, label: l(:label_enabled_sharing) %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-tooltip-area='enabledsharing_help_area'\n       data-tooltip-content='enabledsharing_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='enabledsharing_help_area'></span>\n    </a>\n  </p>\n\n</div>\n\n<%= wikitoolbar_for 'issue_template_description' %>\n\n\n<!-- tooltip content -->\n<div id='issue_title_help_content' class='wiki' style='display: none;'>\n  <%= l(:help_for_issue_title) %>\n</div>\n<div id='isdefault_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_isdefault_help_message) %>\n</div>\n<div id='related_link_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_related_link_help_message, default: 'If there are some example pages or sample issues which using issue template, please specify the link. So operator can see them as an usage or example for template.') %>\n</div>\n<div id='link_title_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_link_title_help_message, default: 'If there are some example pages or sample issues which using issue template, please specify the link. So operator can see them as an usage or example for template.') %>\n</div>\n<div id='enabled_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_enabled_help_message) %>\n</div>\n<div id='enabledsharing_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_enabledshaing_help_message) %>\n</div>\n<!-- tooltip content -->\n<script>\n  const baseUrl = \"<%= url_for(controller: 'issue_templates', action: 'load_selectable_fields') %>\"\n  const templateId = \"<%= issue_template&.id || '' %>\"\n  const templateType = 'issue_template'\n  const trackerPulldownId = templateType + '_tracker_id'\n  const base_builtin_fields = <%= issue_template.builtin_fields.html_safe %>\n  const base_custom_fields = <%= custom_fields.html_safe %>\n  const projectId = \"<%= project.id %>\"\n</script>\n\n<% if builtin_fields_enable %>\n<%= javascript_include_tag('vue.min', plugin: 'redmine_issue_templates') %>\n<%= javascript_include_tag('template_fields', plugin: 'redmine_issue_templates') %>\n<% end %>\n\n"
  },
  {
    "path": "app/views/issue_templates/_issue_select_form.html.erb",
    "content": "<% return '' unless @issue.project.module_enabled? :issue_templates %>\n<% return '' unless User.current.allowed_to?(:show_issue_templates, @issue.project)  %>\n<div id='template_area' style='display: none;'>\n  <p>\n    <label for='issue_template'><%=h l(:issue_template)%></label>\n    <select id='issue_template' name='issue_template'>\n      <option value=\"\">---</option>\n    </select>\n\n    <a class='icon icon-hint' id='issue_template_related_link' style='display: none;' target='_blank' rel='noopener'></a>\n    <a class='icon template_tooltip' id='link_template_dialog' href='#issue_template_dialog'>\n      <%=h l(:display_and_filter_issue_templates_in_dialog, default: 'Filter Templates') %>\n    </a>\n    <% if setting.enable_help? %>\n        <a class='icon icon-help template-help' title='<%= l(:about_template_help_message) %>'\n           data-tooltip-area='template-help-message-area'\n           data-tooltip-content='template_help_content'>\n          <%= l(:label_help_message) %>\n          <span class='tooltip-area' id='template-help-message-area'></span>\n        </a>\n    <% end %>\n    <a class='icon icon-erase' title='<%= l(:erase_issue_subject_and_description, default: 'Erase') %>' id='erase_template'>\n      <%= l(:erase_issue_subject_and_description, default: 'Erase') %>\n    </a>\n    <a class='icon icon-reload disabled' title='<%= l(:revert_before_applying_template, default: 'Revert') %>'\n       id='revert_template' disabled='disabled'>\n      <%= l(:revert_before_applying_template, default: 'Revert') %>\n    </a>\n    <span id='original_subject' style='display: none;'></span>\n    <span id='original_description' style='display: none;'></span>\n    <span id='template_status-area'></span>\n  </p>\n\n  <!-- dialog box -->\n  <div id='issue_template_dialog' class='overlay'>\n    <div class='popup'>\n      <div class='header_wrapper'>\n        <div class='popup_header'>\n          <h2><span id='issue_template_dialog_title'></span><a class=\"close\" href=\"#\">&times;</a></h2>\n        </div>\n      </div>\n      <div class='template_search_filter_wrapper'>\n        <label for='template_search_filter'>\n          <%=h l(:label_filter_template, default: 'Filter template:') %>\n        </label>\n        <input type='text' name='template_search_filter' id='template_search_filter' class='autocomplete'>\n      </div>\n      <div id='filtered_templates_list'></div>\n    </div>\n  </div>\n\n  <div id='issue_template_confirm_to_replace_dialog' class='overlay'>\n    <a id='issue_template_confirm_to_replace_dialog_cancel' class='cancel' target='#'></a>\n    <div class='popup small'>\n      <p><b><%=h l(:label_msg_confirm_to_replace) %></b></p>\n      <p><input type='checkbox' id='issue_template_confirm_to_replace_hide_dialog'>\n        <%= h l(:label_hide_confirm_dialog_in_the_future,\n              default: 'Hide this confirmation in the future, just overwrite.') %>\n      </p>\n      <div class='footer_wrapper'>\n        <div class='popup_footer' style='text-align: center;'>\n          <i id='overwrite_yes' class='overwrite_confirm_btn'><%=h l(:general_text_Yes) %></i>\n          <i id='overwrite_no' class='overwrite_confirm_btn'><%=h l(:general_text_No) %></i>\n        </div>\n      </div>\n    </div>\n  </div>\n  <!-- dialog box -->\n\n  <div class='wiki' id='template_help_content' style='display: none;'>\n    <%= textilizable(setting.help_message) %>\n  </div>\n</div>\n<script type='text/javascript'>\n  //<![CDATA[\n  var templateConfig = {\n    pulldownUrl: '<%= pulldown_url %>',\n    isTriggeredBy: '<%= is_triggered_by %>',\n    loadUrl: '<%= url_for(controller: 'issue_templates', action: 'load', project_id: project_id, is_triggered_by: is_triggered_by) %>',\n    shouldReplaced: '<%= setting.should_replaced %>',\n    generalTextYes: '<%=h l(:general_text_Yes) %>',\n    generalTextNo : '<%=h l(:general_text_No) %>',\n    confirmMessage: '<%=h l(:label_template_applied, default: \"Issue template is applied. You can revert with click 'Revert' link.\") %>'\n  }\n\n  var templateNS = templateNS || new ISSUE_TEMPLATE(templateConfig)\n  templateNS.isTriggeredBy = '<%= is_triggered_by %>'\n  templateNS.setPulldown('<%= @issue.tracker.id %>')\n\n  document.getElementById('issue_template').addEventListener('change', (event) => {\n    templateNS.changeTemplatePlace()\n    templateNS.loadTemplate()\n  })\n\n  // Show dialog\n  document.getElementById('link_template_dialog').addEventListener('click', (event) => {\n    let templateListUrl = '<%= url_for(controller: 'issue_templates',\n      action:'list_templates', project_id: project_id, issue_tracker_id: @issue.tracker.id) %>'\n    let templateListTitle = '<%= \"#{l(:issue_template)}: #{@issue.tracker.name}\".html_safe %>'\n\n    templateNS.openDialog(templateListUrl, templateListTitle)\n  })\n\n  // revert template\n  document.getElementById('revert_template').addEventListener('click', (event) => {\n    templateNS.revertAppliedTemplate()\n  })\n\n  document.getElementById('erase_template').addEventListener('click', (event) => {\n    templateNS.eraseSubjectAndDescription()\n  })\n\n  // keydown keyup\n  document.querySelector(\"input[name='template_search_filter']\").addEventListener('keydown', (event) => {\n    templateNS.filterTemplate(event)\n  })\n\n  document.querySelector(\"input[name='template_search_filter']\").addEventListener('keyup', (event) => {\n    templateNS.filterTemplate(event)\n  })\n\n  // NOTE: Workaround for GitHub issue: 193\n  // Start observing the target node for configured mutations\n  try {\n    if (CKEDITOR.instances) {\n      // Create an observer instance linked to the callback function\n      let observer = new MutationObserver(callback)\n\n      // Select the node that will be observed for mutations\n      let targetNode = document.querySelector('#issue_description_and_toolbar')\n\n      // Options for the observer (which mutations to observe)\n      let config = { attributes: true, childList: true, characterData: true, subtree: true }\n\n      // Callback function to execute when mutations are observed\n      let callback = function (mutationsList) {\n        for (let i = 0, len = mutationsList.length; i < len; ++i) {\n          let mutation = mutationsList[i]\n          if (mutation.type === 'attributes') {\n            console.log('The ' + mutation.attributeName + ' attribute was modified.')\n            if (mutation.target.className == 'cke_contents cke_reset') {\n              // Wait for a while til CKE Editor's textarea is rendered, and after that\n              // apply template text.\n              setTimeout('templateNS.replaceCkeContent()', 200)\n              observer.disconnect()\n            }\n          }\n        }\n      }\n      observer.observe(targetNode, config)\n    }\n  } catch (e) {\n    // do nothing.\n  }\n</script>\n"
  },
  {
    "path": "app/views/issue_templates/_issue_template_link.html.erb",
    "content": "<% if authorize_for('issue_templates', 'show') %>\n<h3><%= l(:issue_template) %></h3>\n<ul>\n  <li>\n    <%= link_to(l(:label_list_templates),\n    controller: 'issue_templates',\n    action: 'index',\n    project_id: @project) %>\n  </li>\n  <li>\n    <%= link_to_if_authorized(l(:label_new_templates),\n    { controller: 'issue_templates', action: 'new', project_id: @project }) %>\n  </li>\n</ul>\n<%- end -%>\n<% if authorize_for('note_templates', 'show') %>\n<h3><%= l(:note_template) %></h3>\n<ul>\n  <li>\n    <%= link_to(l(:label_list_templates),\n    controller: 'note_templates',\n    action: 'index',\n    project_id: @project) %>\n  </li>\n  <li>\n    <%= link_to_if_authorized(l(:label_new_templates),\n    { controller: 'note_templates', action: 'new', project_id: @project }) %>\n  </li>\n</ul>\n<%- end -%>"
  },
  {
    "path": "app/views/issue_templates/_list_templates.api.rsb",
    "content": "api.array :global_issue_templates do\n  global_issue_templates.each do |template|\n    api.template do\n      api.id template.id\n      api.tracker_id template.tracker_id\n      api.tracker_name template.tracker.id\n      api.title template.title\n      api.issue_title template.issue_title\n      api.description template.description\n      api.note template.note\n      api.enabled template.enabled\n      api.updated_on template.updated_on\n      api.created_on template.created_on\n      api.updated_on template.updated_on\n    end\n  end\nend\napi.array :inherit_templates do\n  inherit_templates.each do |template|\n    api.template do\n      api.id template.id\n      api.tracker_id template.tracker_id\n      api.tracker_name template.tracker.name\n      api.title template.title\n      api.issue_title template.issue_title\n      api.description template.description\n      api.note template.note\n      api.enabled template.enabled\n      api.is_default template.id == default_template\n      api.enabled_sharing template.enabled_sharing\n      api.position template.position\n      api.updated_on template.updated_on\n      api.created_on template.created_on\n      api.updated_on template.updated_on\n    end\n  end\nend\napi.array :issue_templates do\n  issue_templates.each do |template|\n    api.template do\n      api.id template.id\n      api.tracker_id template.tracker_id\n      api.tracker_name template.tracker.name\n      api.title template.title\n      api.issue_title template.issue_title\n      api.description template.description\n      api.note template.note\n      api.enabled template.enabled\n      api.is_default template.is_default\n      api.enabled_sharing template.enabled_sharing\n      api.position template.position\n      api.updated_on template.updated_on\n      api.created_on template.created_on\n      api.updated_on template.updated_on\n    end\n  end\nend\n"
  },
  {
    "path": "app/views/issue_templates/_list_templates.html.erb",
    "content": "<table class='list template_list'>\n  <thead>\n  <tr>\n    <th><%=h l(:issue_template_name) %></th>\n    <th><%=h l(:issue_title) %></th>\n    <th><%=h l(:issue_description) %></th>\n    <th><%= l(:field_is_default) %></th>\n    <th><%=h l(:button_apply, default: 'Apply') %></th>\n  </tr>\n  </thead>\n<% issue_templates.each do |template| %>\n      <tr class='<%= cycle('odd', 'even') %> template_data'>\n        <td>\n          <%= template.title %>\n        </td>\n        <td>\n          <%= template.issue_title %>\n        </td>\n        <td>\n          <div class='template_tooltip_wrapper'>\n            <a class='icon template_tooltip' href='#' title='<%= l(:label_preview) %>'></a>\n            <div class='wiki template_tooltip_body'>\n              <span class='title'><%= template.title %></span>\n              <%= textilizable(template.description) %>\n              <% if template.related_link.present? %>\n                <hr/>\n                <%= link_to template.link_title.present? ? template.link_title : l(:issue_template_related_link, default: 'Related link'),\n                    template.related_link, target: '_blank', rel: 'nofollow noopener', class: 'external' %>\n              <% end %>\n            </div>\n          </div>\n        </td>\n        <td class='center'><%= checked_image template.is_default? %></td>\n        <td>\n          <i data-issue-template-id='<%= template.id %>'\n             class='icon icon-test template-update-link'></i>\n        </td>\n      </tr>\n<% end %>\n<% inherit_templates.each do |template| %>\n      <tr class=\"<%= cycle('odd', 'even') %> template_data\">\n        <td>\n          <%= template.title %>\n        </td>\n        <td>\n          <%= template.issue_title %>\n        </td>\n        <td>\n          <div class='template_tooltip_wrapper'>\n            <a class='icon template_tooltip' href='#' title='<%= l(:label_preview) %>'></a>\n            <div class='wiki template_tooltip_body'>\n              <span class=\"title\"><%= template.title %></span>\n              <%= textilizable(template.description) %>\n              <% if template.related_link.present? %>\n                <hr/>\n                <%= link_to template.link_title.present? ? template.link_title : l(:issue_template_related_link, default: 'Related link'),\n                    template.related_link, target: '_blank', rel: 'nofollow noopener', class: 'external' %>\n              <% end %>\n            </div>\n          </div>\n        </td>\n        <td class='center'><%= checked_image template == default_template %></td>\n        <td>\n          <i data-issue-template-id='<%= template.id %>'\n             class='icon icon-test template-update-link'></i>\n        </td>\n      </tr>\n<% end %>\n<% global_issue_templates.each do |template| %>\n      <tr class='<%= cycle('odd', 'even') %> template_data'>\n        <td>\n          <%= template.title %>\n        </td>\n        <td>\n          <%= template.issue_title %>\n        </td>\n        <td>\n          <div class='template_tooltip_wrapper'>\n            <a class='icon template_tooltip' href='#' title='<%= l(:label_preview) %>'></a>\n            <div class='wiki template_tooltip_body'>\n              <span class='title'><%= template.issue_title %></span>\n              <%= textilizable(template.description) %>\n              <% if template.related_link.present? %>\n                <hr/>\n                <%= link_to template.link_title.present? ? template.link_title : l(:issue_template_related_link, default: 'Related link'),\n                    template.related_link, target: '_blank', rel: 'nofollow noopener', class: 'external' %>\n              <% end %>\n            </div>\n          </div>\n        </td>\n        <td class='center'><%= checked_image template == default_template %></td>\n        <td>\n          <i data-issue-template-id='<%= template.id %>'\n             class='icon icon-test template-update-link template-global cursor: pointer;'></i>\n        </td>\n      </tr>\n<% end %>\n</table>\n\n<script type=\"text/javascript\">\nconst templateElements = document.querySelectorAll('i.template-update-link')\nconst templateNS = new ISSUE_TEMPLATE()\nArray.from(templateElements).forEach(el => {\n  el.addEventListener('click',  (event) => {\n    templateNS.updateTemplateSelect(event)\n  })\n})\n</script>\n"
  },
  {
    "path": "app/views/issue_templates/_note_form.html.erb",
    "content": "<%\n  element_id = type\n  if type == 'template_edit_journal'\n    element_id = \"template_journal_#{@journal.id}_notes\"\n  end\n  project_id = issue&.project_id\n  tracker_id = issue&.tracker_id\n%>\n<div id='<%= element_id %>'>\n  <label for='select_note_template' style='font-weight: bold;'>\n    <%=h l(:label_template_for_note, default: 'Template for note') %>\n  </label>\n  <a class='icon template_tooltip' id='link_<%= element_id %>_dialog' href='#<%= element_id %>_dialog' onclick='noteTemplateNS.changeNoteTemplateList(\"<%= element_id %>\")'>\n    <%=h l(:display_and_filter_issue_templates_in_dialog, default: 'Filter Templates') %>\n  </a>\n  <!-- dialog box -->\n  <div id='<%= element_id %>_dialog' class='overlay'>\n    <div class='popup'>\n     <div class='header_wrapper'>\n       <div class='popup_header'>\n         <h2><%=h l(:label_template_for_note, default: 'Select template for note') %>  <a class=\"close\" href=\"#\">&times;</a></h2>\n       </div>\n     </div>\n      <div class='filtered_templates_list'>\n        <!-- Replaced contemts -->\n      </div>\n    </div>\n  </div>\n</div>\n\n\n<script type='text/javascript'>\n  var noteTemplateConfig = {\n    baseElementId: '<%= element_id %>',\n    baseTemplateListUrl: '<%= url_for(controller: 'note_templates', action:'list_templates') %>',\n    baseTrackerId: <%= tracker_id %>,\n    baseProjectId: <%= project_id %>,\n    loadNoteTemplateUrl: '<%= load_note_templates_path %>'\n  }\n\n  // let baseElementId = '<%= element_id %>'\n  let content = document.querySelectorAll('#' + noteTemplateConfig.baseElementId)\n\n  if (content.length === 1) {\n    let element = content[0].closest('form')\n    if (noteTemplateConfig.baseElementId === 'template_issue_notes') {\n      element = content[0].closest('fieldset')\n    }\n    element.insertBefore(content[0], element.firstChild)\n  }\n\n  var noteTemplateNS = noteTemplateNS || new NOTE_TEMPLATE(noteTemplateConfig)\n</script>\n"
  },
  {
    "path": "app/views/issue_templates/_template_pulldown.html.erb",
    "content": "<option value=''>---</option>\n<optgroup label='<%=h @tracker.name %>'>\n  <%= options_for_template_pulldown(grouped_options) %>\n</optgroup>\n"
  },
  {
    "path": "app/views/issue_templates/index.api.rsb",
    "content": "api.array :global_issue_templates do\n  @global_issue_templates.each do |template|\n    api.template do\n      api.id template.id\n      api.tracker_id template.tracker_id\n      api.tracker_name template.tracker.try(:name) || nil\n      api.title template.title\n      api.issue_title template.issue_title\n      api.description template.description\n      api.note template.note\n      api.enabled template.enabled\n      api.updated_on template.updated_on\n      api.created_on template.created_on\n      api.updated_on template.updated_on\n    end\n  end\nend\napi.array :inherit_templates do\n  @inherit_templates.each do |template|\n    api.template do\n      api.id template.id\n      api.tracker_id template.tracker_id\n      api.tracker_name template.tracker.tracker.try(:name) || nil\n      api.title template.title\n      api.issue_title template.issue_title\n      api.description template.description\n      api.note template.note\n      api.enabled template.enabled\n      api.is_default template.is_default\n      api.enabled_sharing template.enabled_sharing\n      api.position template.position\n      api.updated_on template.updated_on\n      api.created_on template.created_on\n      api.updated_on template.updated_on\n    end\n  end\nend\napi.array :issue_templates do\n  project_templates.each do |template|\n    api.template do\n      api.id template.id\n      api.tracker_id template.tracker_id\n      api.tracker_name template.tracker.try(:name) || nil\n      api.title template.title\n      api.issue_title template.issue_title\n      api.description template.description\n      api.note template.note\n      api.enabled template.enabled\n      api.is_default template.is_default\n      api.enabled_sharing template.enabled_sharing\n      api.position template.position\n      api.updated_on template.updated_on\n      api.created_on template.created_on\n      api.updated_on template.updated_on\n    end\n  end\nend\n"
  },
  {
    "path": "app/views/issue_templates/index.html.erb",
    "content": "<h2 class='issue_template'><%=h \"#{l(:issue_template)}\" %></h2>\n<%= render partial: 'common/nodata', locals: { trackers: tracker_ids } %>\n<div class='contextual issue_templates'>\n  <%= link_to_if_authorized(l(:label_new_templates),\n                            { controller: 'issue_templates', action: 'new', project_id: @project },\n                              class: 'icon icon-add') %>\n</div>\n<div style='clear: both;'></div>\n\n<% if @notice -%>\n  <div class='flash notice'><%= @notice -%></div>\n<% end -%>\n\n\n<% if @template_map.empty? %>\n    <div class='template_box'>\n      <%= l(:no_issue_templates_for_this_project) %>\n    </div>\n<% end %>\n\n<% @template_map.each_key do |tracker| %>\n    <div class='template_box'>\n      <h3 class='template_tracker'><%= tracker.name %></h3>\n      <%= non_project_tracker_msg(project_tracker?(tracker, @project)) %>\n\n      <table class='list issues table-sortable template_list'>\n        <thead>\n        <tr>\n          <th>#</th>\n          <th class='hideable'><%= l(:issue_template_name) %></th>\n          <th><%= l(:label_preview) %></th>\n          <th class='hideable'><%= l(:field_tracker) %></th>\n          <th class='hideable'><%= l(:field_author) %></th>\n          <th class='hideable'><%= l(:field_updated_on) %></th>\n          <th><%= l(:field_is_default) %></th>\n          <th><%= l(:label_enabled) %></th>\n          <% if authorize_for('issue_templates', 'edit') %>\n              <th><%=l(:button_sort)%></th>\n          <% end %>\n        </tr>\n        </thead>\n        <tbody>\n        <% @template_map[tracker].each do |issue_template| %>\n            <tr class='<%= cycle('odd', 'even') %> issue_template issue'>\n              <td>\n                <%= link_to h(issue_template.id),\n                            { controller: :issue_templates, action: 'show',\n                              id: issue_template.id, project_id: issue_template.project\n                            },\n                            { title: issue_template.note } %>\n              </td>\n              <td class='hideable template_title'>\n                <%= link_to h(issue_template.title),\n                            { controller: 'issue_templates',\n                              id: issue_template.id, action: 'show' },\n                            { title: \"#{html_escape(issue_template.note) }\"} %>\n              </td>\n              <td>\n                <div class='template_tooltip_wrapper'>\n                  <a class='icon template_tooltip' title='<%= l(:label_preview) %>'></a>\n                  <div class='wiki template_tooltip_body'>\n                    <span class=\"title\"><%= issue_template.title %></span>\n                    <%= textilizable(issue_template.description) %>\n                    <% if issue_template.related_link.present? %>\n                      <hr/>\n                      <%= link_to issue_template.link_title.present? ? issue_template.link_title : l(:issue_template_related_link, default: 'Related link'),\n                          issue_template.related_link, target: '_blank', rel: 'nofollow noopener', class: 'external' %>\n                    <% end %>\n                  </div>\n                </div>\n              </td>\n              <td class='hideable'><%=h issue_template.tracker.name %></td>\n              <td class='hideable'><%=h issue_template.author %></td>\n              <td class='hideable'><%= format_time(issue_template.updated_on)%> </td>\n              <td class='center'><%= checked_image issue_template.is_default? %></td>\n              <td class='center'><%= checked_image issue_template.enabled? %></td>\n\n              <% if authorize_for('issue_templates', 'edit') %>\n                <td class='buttons'>\n                  <%= reorder_handle(issue_template,\n                                      url: url_for(:controller => 'issue_templates',\n                                                  :action => 'update', :id => issue_template.id,\n                                                  :project_id => issue_template.project)) %>\n                </td>\n              <% end %>\n            </tr>\n        <% end %>\n        </tbody>\n      </table>\n    </div>\n    <%= javascript_tag do %>\n      // NOTE: Sortable feature depends on Redmine's sorting jQuery plugin.\n      $(function() { $('table.table-sortable tbody').positionedItems() })\n    <% end %>\n<% end %>\n\n\n<% unless @inherit_templates.blank? %>\n<h2 class='issue_template'><%=h \"#{l(:label_inherited_templates)}\" %></h2>\n  <div class='template_box'>\n\n        <table class='list issues template_list'>\n          <thead>\n          <tr>\n            <th>#</th>\n            <th class='hideable'><%= l(:issue_template_name) %></th>\n            <th><%= l(:label_preview) %></th>\n            <th class='hideable'><%= l(:field_tracker) %></th>\n            <th class='hideable'><%= l(:field_author) %></th>\n            <th class='hideable'><%= l(:field_updated_on) %></th>\n            <th><%= l(:field_is_default) %></th>\n            <th><%= l(:label_enabled) %></th>\n          </tr>\n          </thead>\n          <tbody>\n          <% @inherit_templates.each do |issue_template| %>\n              <tr class='<%= cycle('odd', 'even') %> issue_template issue'>\n                <td>\n                  <%= link_to h(issue_template.id),\n                              { controller: 'issue_templates',\n                                action: 'show', id: issue_template.id,\n                                project_id: issue_template.project_id },\n                              { title: issue_template.note } %>\n                </td>\n                <td class='hideable template_title'>\n                  <%= link_to h(issue_template.title),\n                              { controller: 'issue_templates',\n                                project_id: issue_template.project_id,\n                                id: issue_template.id, action: 'show' },\n                              { title: \"#{html_escape(issue_template.note)}\" } %>\n                </td>\n                <td>\n                  <div class='template_tooltip_wrapper'>\n                    <a class='icon template_tooltip' title='<%= l(:label_preview) %>'></a>\n                    <div class='wiki template_tooltip_body'>\n                      <span class='title'><%=h issue_template.title %></span>\n                      <%=h textilizable(issue_template.description) %>\n                      <% if issue_template.related_link.present? %>\n                        <hr/>\n                        <%= link_to issue_template.link_title.present? ? issue_template.link_title : l(:issue_template_related_link, default: 'Related link'),\n                            issue_template.related_link, target: '_blank', rel: 'nofollow noopener', class: 'external' %>\n                      <% end %>\n                    </div>\n                  </div>\n                </td>\n                <td class='hideable'><%=h issue_template.tracker.name %></td>\n                <td class='hideable'><%=h issue_template.author %></td>\n                <td class='hideable'><%=h format_time(issue_template.updated_on)%> </td>\n                <td class='center'><%= checked_image issue_template.is_default? %></td>\n                <td class='center'><%= checked_image issue_template.enabled? %></td>\n              </tr>\n              <tr class='<%= current_cycle %>' style='display: none;' id='template_description-<%= issue_template.id %>'>\n                <td class=\"description\" colspan=\"8\">\n                  <div class=\"wiki\"><%=h textilizable(issue_template.description) %>\n                  <hr/>\n                  <%= link_to_if issue_template.related_link.present?,\n                    issue_template.link_title.present? ? issue_template.link_title : l(:issue_template_related_link, default: 'Related link'),\n                    issue_template.related_link, target: '_blank', rel: 'nofollow noopener', class: 'external' %>\n                  </div>\n                </td>\n              </tr>\n          <% end %>\n          </tbody>\n        </table>\n    </div>\n <% end %>\n\n<% unless  @global_issue_templates.blank? %>\n    <h2 class='issue_template'><%=h \"#{l(:global_issue_templates)}\" %></h2>\n    <div class='template_box'>\n\n      <% if apply_all_projects %>\n          <p>\n            <i class='issue_template icon settings'></i>\n            <span class=\"issue_template help_content\">\n              <%= l(:note_apply_global_template_to_all_projects_setting_enabled) %><br/>\n              <%= l(:note_project_local_template_override_global_template) %>\n            </span>\n          </p>\n      <% end %>\n\n      <%= l(:only_admin_can_associate_global_template) %>\n      <table class='list issues template_list'>\n        <thead>\n        <tr>\n          <th>#</th>\n          <th class='hideable'><%= l(:issue_template_name) %></th>\n          <th><%= l(:label_preview) %></th>\n          <th class='hideable'><%= l(:field_tracker) %></th>\n          <th class='hideable'><%= l(:field_author) %></th>\n          <th class='hideable'><%= l(:field_updated_on) %></th>\n          <th><%= l(:field_is_default) %></th>\n        </tr>\n        </thead>\n        <tbody>\n        <% @global_issue_templates.each do |issue_template| %>\n            <tr class='<%= cycle('odd', 'even') %> issue_template issue'>\n              <td>\n                <% if User.current.admin? %>\n                    <%= link_to h(issue_template.id),\n                                { controller: 'global_issue_templates',\n                                  action: 'show', id: issue_template.id, },\n                                { title: issue_template.note } %>\n                <% else %>\n                    <%=h issue_template.id %>\n                <% end %>\n               </td>\n\n              <td class='hideable template_title'>\n                <%= link_to h(issue_template.title),\n                            { controller: 'global_issue_templates',\n                              id: issue_template.id, action: 'show' },\n                            { title: \"#{html_escape(issue_template.note)}\" } %>\n              </td>\n              <td>\n                <div class='template_tooltip_wrapper'>\n                  <a class='icon template_tooltip' title='<%= l(:label_preview) %>'></a>\n                  <div class='wiki template_tooltip_body'>\n                    <span class='title'><%=h issue_template.title %></span>\n                    <%=h textilizable(issue_template.description) %>\n                    <% if issue_template.related_link.present? %>\n                      <hr/>\n                      <%= link_to issue_template.link_title.present? ? issue_template.link_title : l(:issue_template_related_link, default: 'Related link'),\n                          issue_template.related_link, target: '_blank', rel: 'nofollow noopener', class: 'external' %>\n                    <% end %>\n                  </div>\n                </div>\n              </td>\n              <td class='hideable'>\n                <% if issue_template.tracker.present? %>\n                  <%= h issue_template.tracker.try(:name) || \"ID: #{issue_template.tracker_id}\" %>\n                <% else %>\n                  <span title=\"<%= l(:orphaned_template, default: 'Orphaned template from tracker') %>\">\n                    <%= \"ID: #{issue_template.tracker_id}\" %>\n                  </span>\n                <% end %>\n              </td>\n              <td class='hideable'><%=h issue_template.author %></td>\n              <td class='hideable'><%=h format_time(issue_template.updated_on)%> </td>\n              <td class='center'><%= checked_image issue_template.is_default? %></td>\n            </tr>\n            <tr class='<%= current_cycle %>' style='display: none;' id='global_template_description-<%= issue_template.id %>'>\n              <td class='description' colspan='8'>\n                <div class=\"wiki\"><%=h textilizable(issue_template.description) %>\n                <% if issue_template.related_link.present? %>\n                  <hr/>\n                  <%= link_to issue_template.link_title.present? ? issue_template.link_title : l(:issue_template_related_link, default: 'Related link'),\n                      issue_template.related_link, target: '_blank', rel: 'nofollow noopener', class: 'external' %>\n                <% end %>\n                </div>\n              </td>\n            </tr>\n        <% end %>\n        </tbody>\n      </table>\n\n    </div>\n<% end %>\n\n<a id='orphaned_template_link' class='icon template_tooltip orphaned_template_link template-help collapsible collapsed'\n  title='<%= l(:orphaned_templates) %>'\n  data-template-help-target='orphaned_templates'\n  data-url='<%= orphaned_templates_project_issue_templates_path %>'>\n  <%= l(:orphaned_templates, default: 'Orphaned Templates') %>\n</a>\n\n<div id='orphaned_templates' style='display: none'></div>\n\n<%= render partial: 'common/template_links' %>\n"
  },
  {
    "path": "app/views/issue_templates/new.html.erb",
    "content": "<div class='contextual'>\n  <%= link_to(l(:label_list_templates),\n              { controller: 'issue_templates',\n                action: 'index', project_id: project }, class: 'icon icon-template') %>\n</div>\n<h2 class='issue_template'><%=h \"#{l(:issue_templates)} / #{l(:button_add)}\" %></h2>\n<%= render partial: 'common/nodata', locals: { trackers: project.trackers } %>\n<% if project.trackers.any? %>\n  <%= labelled_form_for :issue_template,  @issue_template,\n                        url: { controller: 'issue_templates', action: 'create', project_id: project },\n                        html: { id: 'issue_template-form', class: nil, multipart: false } do |f| %>\n\n      <%= render 'form', { f: f, issue_template: issue_template, project: project, custom_fields: custom_fields,\n                            builtin_fields_enable: builtin_fields_enable } %>\n      <div id='preview' class='wiki'></div>\n      <%= submit_tag l(:button_create) %>\n      <%= link_to l(:button_cancel), { action: 'index'}, data: { confirm: l(:text_are_you_sure) } %>\n  <% end %>\n<% end %>\n\n<div style='float: right;'><%= render partial: 'common/template_links' %></div>"
  },
  {
    "path": "app/views/issue_templates/show.html.erb",
    "content": "<div class='contextual'>\n  <%= link_to_if_authorized l(:button_edit),\n                            { controller: 'issue_templates', action: 'update', id: issue_template,\n                              project_id: project },\n                            title: l(:button_edit),\n                            class: 'icon icon-edit', accesskey: accesskey(:edit),\n                            onclick: \"document.getElementById('edit-issue_template').style.display = 'block'; return false;\" %>\n  <%= link_to l(:button_copy),\n              { controller: 'issue_templates',\n                action: 'new', project_id: project, copy_from: issue_template.id },\n                class: 'icon icon-copy', title: 'copy!' %>\n  <%= link_to_if_authorized l(:button_delete),\n                            { controller: 'issue_templates', action: 'destroy',\n                              id: issue_template, project_id: project },\n                              title: l(:enabled_template_cannot_destroy, default: 'Only disabled template can be destroyed.'),\n                              data: { confirm: l(:template_remove_confirm,\n                              { count: child_project_used_count, default: 'Are you sure to remove this template? %{count} subprojects use this template.' }) },\n                            method: 'delete', class: 'icon icon-del template-disabled-link',\n                            disabled: issue_template.enabled?\n                            %>\n  <%= link_to(l(:label_list_templates),\n              { controller: 'issue_templates',\n                action: 'index',\n                project_id: project }, class: 'icon icon-template') %>\n</div>\n\n<h2 class='issue_template'>\n  <%= l(:issue_templates) %>: #<%= issue_template.id %> <%= issue_template.title %>\n  <%= avatar(issue_template.author, size: '24') %>\n</h2>\n\n<%= render partial: 'common/nodata', locals: { trackers: project.trackers } %>\n<% if authorize_for('issue_templates', 'update') %>\n  <div id='edit-issue_template'>\n    <%= labelled_form_for :issue_template, issue_template,\n                          url: { controller: 'issue_templates', action: 'update',\n                                  project_id: project, id: issue_template },\n                          html: { id: 'issue_template-form', class: nil, multipart: false } do |f| %>\n\n        <%= render 'form', { f: f, issue_template: issue_template, project: project,\n                              custom_fields: custom_fields, builtin_fields_enable: builtin_fields_enable } %>\n        <div id='preview' class='wiki'></div>\n        <%= submit_tag l(:button_save) %>\n        <%= link_to l(:button_cancel), { action: 'index' },\n                      onclick: 'Element.hide(\"edit-issue_template\"); return false;' %>\n    <% end %>\n    <hr/>\n  </div>\n<% else %>\n\n\n<div class='box tabular box-white'>\n  <p>\n    <label><%= l(:issue_template_name) %></label>\n    <%= h issue_template.title %>\n  </p>\n  <fieldset class='issue'>\n    <legend class='issue'><%= l(:label_applied_for_issue) %></legend>\n    <p><label><%= l(:label_tracker) %></label>\n      <%= h issue_template.tracker.present? ? issue_template.tracker.name :\n                l(:orphaned_template, default: 'Orphaned template from tracker') %>\n      <br/>\n      <%= non_project_tracker_msg(project_tracker?(issue_template.tracker, project)) %>\n    </p>\n\n    <p>\n      <label><%= l(:issue_title) %></label>\n      <%= h issue_template.issue_title %>\n    </p>\n\n    <p>\n      <strong style='margin-left: -100px;'><%= l(:issue_description) %></strong>\n    </p>\n\n    <div class='wiki issue_template'><%= textilizable(issue_template.description) %></div>\n\n  </fieldset>\n\n  <p><label><%= l(:issue_template_note) %></label>\n    <%= issue_template.note.blank? ? l(:label_none) : issue_template.note %>\n  </p>\n\n  <p><label><%= l(:issue_template_related_link, default: 'Related Link') %></label>\n    <%= issue_template.related_link.blank? ? l(:label_none) : issue_template.related_link %>\n  </p>\n\n  <p><label><%= l(:field_is_default) %></label>\n    <%= checked_image issue_template.is_default? %>\n  </p>\n\n  <p><label><%= l(:label_enabled) %></label>\n    <%= checked_image issue_template.enabled? %>\n  </p>\n\n  <p><label><%= l(:label_enabled_sharing) %></label>\n    <%= checked_image issue_template.enabled_sharing? %>\n    <%= l(:label_number_of_subprojects_use_this_template, {\n      count: child_project_used_count, default:  '%{count} subprojects use this template.....' }) %>\n  </p>\n\n  <p><label><%= l(:field_author) %></label>\n    <%= authoring issue_template.created_on, issue_template.author %>\n    <% if issue_template.created_on != issue_template.updated_on %>\n        (<%= l(:label_updated_time, time_tag(issue_template.updated_on)).html_safe %>)\n    <% end %>\n  </p>\n\n</div>\n<% end %>\n<%= render partial: 'common/template_links' %>\n"
  },
  {
    "path": "app/views/issue_templates_settings/index.html.erb",
    "content": "<div id='issue_templates_settings'>\n  <%= render partial: 'common/nodata', locals: { trackers: @project.trackers } %>\n\n  <h2 class='issue_template_setting'><%= l(:issue_templates_settings, default: 'Issue Templates Setting') %></h2>\n  <p></p>\n  <div class='template_box'>\n    <h2><%= l(:issue_templates_optional_settings, default: 'Templates Optional Settings') %></h2>\n    <p><%= l(:about_help_message) %></p>\n    <%= labelled_form_for :settings, @issue_templates_setting,\n                          url: { controller: 'issue_templates_settings',\n                                 action: 'edit', project_id: @project,\n                                 setting_id: @issue_templates_setting.id },\n                          html: { id: 'issue_templates_settings' } do |f| %>\n        <%= error_messages_for 'issue_templates_setting' %>\n        <div class='box tabular'>\n\n          <p><%= f.check_box :inherit_templates, label: l(:label_inherit_templates) %>\n            <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n               data-tooltip-area='inherit_templates_help_area'\n               data-tooltip-content='inherit_templates_help_content'>\n              <%= l(:help_for_this_field) %>\n              <span class='tooltip-area' id='inherit_templates_help_area'></span>\n            </a>\n          </p>\n\n          <p>\n            <%= f.check_box :should_replaced, label: l(:label_should_replaced) %>\n            <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n               data-template-help-target='should_replaced_help_content'\n               data-tooltip-area='should_replaced_help_area'\n               data-tooltip-content='should_replaced_help_content'>\n              <%= l(:help_for_this_field) %>\n              <span class='tooltip-area' id='should_replaced_help_area'></span>\n            </a>\n          </p>\n\n          <p><%= f.check_box :enabled, label: l(:label_show_help_message) %></p>\n          <p>\n            <label><%=l(:label_help_message)%></label>\n            <%=content_tag(:label, l(:label_help_message)) %>\n            <%=text_area_tag 'settings[help_message]',  @issue_templates_setting['help_message'], size: '50x5',\n                             class: 'wiki-edit'  %>\n            <br/>\n          </p>\n          <%= wikitoolbar_for 'settings_help_message' %>\n\n        </div>\n\n        <%= submit_tag l(:button_save) %>\n    <% end %>\n  </div>\n\n  <!--- help content -->\n  <div id='inherit_templates_help_content' class='wiki' style='display: none;'>\n    <%= l(:label_inherit_templates_help_message) %>\n  </div>\n  <div id='should_replaced_help_content' class='wiki' style='display: none;'>\n    <%= l(:label_should_replaced_help_message) %>\n  </div>\n  <!--- help content -->\n</div>\n\n<div style='float: right;'><%= render partial: 'common/template_links' %></div>\n"
  },
  {
    "path": "app/views/note_templates/_form.html.erb",
    "content": "<%= error_messages_for 'note_template' %>\n<div class='box tabular box-white'>\n  <p><%= f.text_field :name, required: true, size: 80, label: l(:issue_template_name) %></p>\n\n  <fieldset class='issue'>\n    <legend class='issue'><%= l(:label_applied_for_issue) %></legend>\n    <p>\n      <% if note_template.tracker.blank? %>\n          <%= f.select :tracker_id, template_target_trackers(project, note_template),\n                       required: true, label: l(:label_tracker), include_blank: true  %>\n\n          <%= h note_template.tracker.present? ? note_template.tracker.name :\n                    l(:orphaned_template, default: 'Orphaned template from tracker') %>\n      <% else %>\n          <%= f.select :tracker_id, template_target_trackers(project, note_template),\n                       required: true, label: l(:label_tracker), selected: note_template.tracker.id %>\n          <% unless project_tracker?(note_template.tracker, project) %><br/>\n              <%= non_project_tracker_msg(project_tracker?(note_template.tracker, project)) %>\n          <% end %>\n      <% end %>\n    </p>\n    <p>\n      <%= f.text_area :description, cols: 78, rows: 12,\n                      required: true,\n                      label: l(:label_comment), class: 'wiki-edit' %>\n    </p>\n\n    <p>\n      <%= f.select :visibility, NoteTemplate.visibilities.map { |k, v| [t(\"note_templates.visibility.#{k}\"), k] },\n            selected: note_template.visibility,\n            required: true, label: l(:field_template_visibility) %>\n    </p>\n    <p id='visible_roles_checkbox'\n      style='display: <%= note_template.visibility == 'roles' ? 'block;' : 'none;' %>'>\n      <label for='note_visible_roles[role_ids]'><%= l(:label_role) %></label>\n         <% Role.givable.each do |role| %>\n          <%= check_box_tag('note_template[role_ids][]',\n                        role.id,\n                        note_template.note_visible_roles.pluck(:role_id).to_a.include?(role.id)) %>\n          <%= role.name %>\n        <% end %>\n    </p>\n  </fieldset>\n  <p>\n    <%= f.text_area :memo, cols: 70, rows: 3,\n                    required: false,\n                    label: l(:issue_template_note) %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-tooltip-area='memo_help_area'\n       data-tooltip-content='memo_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='memo_help_area'></span>\n    </a>\n  </p>\n\n  <p>\n    <%= f.check_box :enabled, label: l(:label_enabled) %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-tooltip-area='enabled_help_area'\n       data-tooltip-content='enabled_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='enabled_help_area'></span>\n    </a>\n  </p>\n</div>\n\n<%= wikitoolbar_for 'note_template_description' %>\n\n<!-- help content -->\n<div id='issue_title_help_content' class='wiki' style='display: none;'>\n  <%= l(:help_for_issue_title) %>\n</div>\n\n<div id='enabled_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_enabled_help_message) %>\n</div>\n\n<div id='memo_help_content' class='wiki' style='display: none;'>\n  <%= l(:label_memo_help_message, default: 'Please set up a note explaining when applying this template.') %>\n</div>\n<!-- help content -->\n\n<script type='text/javascript'>\n  const visibility_select = document.getElementById('note_template_visibility')\n  const roles_checkbox = document.getElementById('visible_roles_checkbox')\n\n  visibility_select.addEventListener('change', (e) => {\n    if (e.target.value == 'roles') {\n      roles_checkbox.style.display = 'block'\n    } else {\n      roles_checkbox.style.display = 'none'\n    }\n  })\n</script>\n"
  },
  {
    "path": "app/views/note_templates/_list_note_templates.html.erb",
    "content": "<table class='list template_list'>\n  <thead>\n  <tr>\n    <th><%=h l(:note_template_name, default: \"Name\") %></th>\n    <th><%=h l(:note_description, default: \"Comment Body\") %></th>\n    <th><%=h l(:button_apply, default: 'Apply') %></th>\n  </tr>\n  </thead>\n<% note_templates.each do |template| %>\n      <tr class=\"<%= cycle('odd', 'even') %> template_data\">\n        <td>\n          <%= template.name %>\n        </td>\n        <td>\n          <div class='template_tooltip_wrapper'>\n            <a class='icon template_tooltip' href='#' title='<%= l(:label_preview) %>'></a>\n            <div class='wiki template_tooltip_body'>\n              <span class='title'><%= template.name %></span>\n              <%= textilizable(template.description) %>\n              <hr/>\n              <span class='title'><%= l(:issue_template_note) %></span>\n              <%= textilizable(template.try(:memo)) %>\n            </div>\n          </div>\n        </td>\n        <td>\n          <a data-note-template-id='<%= template.id %>'\n             onclick='noteTemplateNS.applyNoteTemplate(this)'\n             class='icon icon-test template-update-link'></a>\n        </td>\n      </tr>\n<% end %>\n<% global_note_templates.each do |template| %>\n      <tr class=\"<%= cycle('odd', 'even') %> template_data\">\n        <td>\n          <%= template.name %>\n        </td>\n        <td>\n          <div class='template_tooltip_wrapper'>\n            <a class='icon template_tooltip' href='#' title='<%= l(:label_preview) %>'></a>\n            <div class='wiki template_tooltip_body'>\n              <span class='title'><%= template.name %></span>\n              <%= textilizable(template.description) %>\n              <hr/>\n              <span class='title'><%= l(:issue_template_note) %></span>\n              <%= textilizable(template.try(:memo)) %>\n            </div>\n          </div>\n        </td>\n        <td>\n          <a data-note-template-id='<%= template.id %>'\n             onclick='noteTemplateNS.applyNoteTemplate(this)'\n             class='icon icon-test template-global template-update-link'></a>\n        </td>\n      </tr>\n<% end %>\n</table>\n"
  },
  {
    "path": "app/views/note_templates/index.api.rsb",
    "content": "api.array :note_templates do\n  note_templates.each do |template|\n    api.template do\n      api.id template.id\n      api.tracker_id template.tracker_id\n      api.tracker_name template.tracker.name\n      api.title template.title\n      api.description template.description\n      api.enabled template.enabled\n      api.created_on template.created_on\n      api.updated_on template.updated_on\n    end\n  end\nend\n"
  },
  {
    "path": "app/views/note_templates/index.html.erb",
    "content": "<h2 class='note_template'><%=h \"#{l(:note_template)}\" %></h2>\n<%= render partial: 'common/nodata', locals: { trackers: tracker_ids } %>\n<div class='contextual note_templates'>\n  <%= link_to_if_authorized(l(:label_new_templates),\n                            { controller: 'note_templates', action: 'new', project_id: @project },\n                              class: 'icon icon-add') %>\n</div>\n<div style='clear: both;'></div>\n\n<% if @notice -%>\n  <div class='flash notice'><%= @notice -%></div>\n<% end -%>\n\n\n<% if @template_map.empty? %>\n    <div class='template_box'>\n      <%= l(:no_note_templates_for_this_project) %>\n    </div>\n<% end %>\n\n<% @template_map.each_key do |tracker| %>\n    <div class='template_box'>\n      <h3 class='template_tracker'><%= tracker.name %></h3>\n\n      <table class='list issues table-sortable template_list'>\n        <thead>\n        <tr>\n          <th>#</th>\n          <th class='hideable'><%= l(:issue_template_name) %></th>\n          <th><%= l(:label_preview) %></th>\n          <th class='hideable'><%= l(:field_tracker) %></th>\n          <th class='hideable'><%= l(:field_author) %></th>\n          <th class='hideable'><%= l(:field_updated_on) %></th>\n          <th><%= l(:label_enabled) %></th>\n          <% if authorize_for('note_templates', 'edit') %>\n              <th><%=l(:button_sort)%></th>\n          <% end %>\n        </tr>\n        </thead>\n        <tbody>\n        <% @template_map[tracker].each do |note_template| %>\n            <tr class='<%= cycle('odd', 'even') %> note_template issue'>\n              <td>\n                <%= link_to h(note_template.id),\n                            { controller: :note_templates, action: 'show',\n                              id: note_template.id, project_id: note_template.project\n                            },\n                            { title: note_template.memo } %>\n              </td>\n              <td class='hideable template_title'>\n                <%= link_to h(note_template.name),\n                            { controller: 'note_templates',\n                              id: note_template.id, action: 'show' },\n                            { title: \"#{html_escape(note_template.memo)}\" } %>\n              </td>\n              <td>\n                <div class='template_tooltip_wrapper'>\n                  <a class='icon template_tooltip' title='<%= l(:label_preview) %>'></a>\n                  <div class='wiki template_tooltip_body'>\n                    <span class='title'><%= note_template.name %></span>\n                    <%= textilizable(note_template.description) %>\n                  </div>\n                </div>\n              </td>\n              <td class='hideable'><%=h note_template.tracker.name %></td>\n              <td class='hideable'><%=h note_template.author %></td>\n              <td class='hideable'><%= format_time(note_template.updated_at)%> </td>\n              <td class='center'><%= checked_image note_template.enabled? %></td>\n\n              <% if authorize_for('note_templates', 'edit') %>\n                <td class='buttons'>\n                  <%= reorder_handle(note_template,\n                                      url: url_for(:controller => 'note_templates',\n                                                  :action => 'update', :id => note_template.id,\n                                                  :project_id => note_template.project)) %>\n                </td>\n              <% end %>\n            </tr>\n        <% end %>\n        </tbody>\n      </table>\n    </div>\n    <%= javascript_tag do %>\n      // NOTE: Sortable feature depends on Redmine's sorting jQuery plugin.\n      $(function() { $('table.table-sortable tbody').positionedItems() })\n    <% end %>\n<% end %>\n\n<% if @global_note_templates.present? %>\n    <h2 class='issue_template'><%=h \"#{l(:global_note_templates)}\" %></h2>\n    <div class='template_box'>\n\n      <% if apply_all_projects %>\n          <p>\n            <i class='issue_template icon settings'></i>\n            <span class=\"issue_template help_content\">\n              <%= l(:note_apply_global_template_to_all_projects_setting_enabled) %><br/>\n              <%= l(:note_project_local_template_override_global_template) %>\n            </span>\n          </p>\n      <% end %>\n\n      <%= l(:only_admin_can_associate_global_template) %>\n      <table class='list template_list issues'>\n        <thead>\n        <tr>\n          <th>#</th>\n          <th class='hideable'><%= l(:issue_template_name) %></th>\n          <th><%= l(:label_preview) %></th>\n          <th class='hideable'><%= l(:field_tracker) %></th>\n          <th class='hideable'><%= l(:field_author) %></th>\n          <th class='hideable'><%= l(:field_updated_on) %></th>\n          <th><%= l(:label_enabled) %></th>\n        </tr>\n        </thead>\n        <tbody>\n        <% @global_note_templates.each do |note_template| %>\n            <tr class='<%= cycle('odd', 'even') %> issue_template issue'>\n              <td>\n                <% if User.current.admin? %>\n                    <%= link_to h(note_template.id),\n                                { controller: 'global_note_templates',\n                                  action: 'show', id: note_template.id, },\n                                { title: note_template.memo } %>\n                <% else %>\n                    <%=h note_template.id %>\n                <% end %>\n               </td>\n\n              <td class='hideable template_title'>\n                <%= link_to h(note_template.name),\n                            { controller: 'global_note_templates',\n                              id: note_template.id, action: 'show' },\n                            { title: \"#{html_escape(note_template.memo)}\" } %>\n              </td>\n              <td>\n                <div class='template_tooltip_wrapper'>\n                  <a class='icon template_tooltip' title='<%= l(:label_preview) %>'></a>\n                  <div class='wiki template_tooltip_body'>\n                    <span class='title'><%= note_template.name %></span>\n                    <%= textilizable(note_template.description) %>\n                  </div>\n                </div>\n              </td>\n              <td class='hideable'><%=h note_template.tracker.name %></td>\n              <td class='hideable'><%=h note_template.author %></td>\n              <td class='hideable'><%= format_time(note_template.updated_at)%> </td>\n              <td class='center'><%= checked_image note_template.enabled? %></td>\n            </tr>\n        <% end %>\n        </tbody>\n      </table>\n\n    </div>\n<% end %>\n\n<%= render partial: 'common/template_links' %>\n\n"
  },
  {
    "path": "app/views/note_templates/new.html.erb",
    "content": "<div class='contextual'>\n  <%= link_to(l(:label_list_templates),\n              { controller: 'note_templates',\n                action: 'index', project_id: project }, class: 'icon icon-template') %>\n</div>\n<h2 class='note_template'><%=h \"#{l(:note_template)} / #{l(:button_add)}\" %></h2>\n<% if project.trackers.any? %>\n  <%= labelled_form_for :note_template,  @note_template,\n                        url: { controller: 'note_templates', action: 'create', project_id: project },\n                        html: { id: 'issue_template-form', class: nil, multipart: false } do |f| %>\n\n      <%= render 'form', { f: f, note_template: note_template, project: project } %>\n      <div id='preview' class='wiki'></div>\n      <%= submit_tag l(:button_create) %>\n      <%= link_to l(:button_cancel), { action: 'index'}, data: { confirm: l(:text_are_you_sure) } %>\n  <% end %>\n<% end %>\n\n<%= render partial: 'common/template_links' %>"
  },
  {
    "path": "app/views/note_templates/show.html.erb",
    "content": "<div class='contextual'>\n  <%= link_to_if_authorized l(:button_edit),\n                            { controller: 'note_templates', action: 'update', id: note_template,\n                              project_id: project },\n                            class: 'icon icon-edit', accesskey: accesskey(:edit),\n                            onclick: \"document.getElementById('edit-note_template').style.display = 'inline'; return false;\" %>\n  <%= link_to_if_authorized l(:button_delete),\n                            { controller: 'note_templates', action: 'destroy',\n                              id: note_template, project_id: project },\n                              data: { confirm: l(:template_remove_confirm,\n                              default: \"Are you sure to remove this template? %{count} subprojects use this template.\") },\n                              title: l(:enabled_template_cannot_destroy, default: 'Only disabled template can be destroyed.'),\n                            method: 'delete', class: 'icon icon-del template-disabled-link', disabled: note_template.enabled? %>\n  <%= link_to(l(:label_list_templates),\n              { controller: 'note_templates',\n                action: 'index',\n                project_id: project }, class: 'icon icon-template') %>\n  <%= link_to_if_authorized(l(:label_new_templates),\n                            { controller: 'note_templates', action: 'new', project_id: @project },\n                              class: 'icon icon-add') %>\n</div>\n\n<h2 class='note_template'>\n  <%= l(:note_template) %>: #<%= note_template.id %> <%= note_template.name %>\n  <%= avatar(note_template.author, size: '24') %>\n</h2>\n\n<%= render partial: 'common/nodata', locals: { trackers: project.trackers } %>\n<% if authorize_for('note_templates', 'update') %>\n  <div id='edit-note_template'>\n    <%= labelled_form_for :note_template, note_template,\n                          url: { controller: 'note_templates', action: 'update',\n                                  project_id: project, id: note_template },\n                          html: { id: 'note_template-form', class: nil, multipart: false } do |f| %>\n\n        <%= render 'form', { f: f, note_template: note_template, project: project } %>\n        <div id='preview' class='wiki'></div>\n        <%= submit_tag l(:button_save) %>\n        <%= link_to l(:button_cancel), { action: 'index' },\n                      onclick: 'Element.hide(\"edit-note_template\"); return false' %>\n    <% end %>\n    <hr/>\n  </div>\n<% end %>\n\n\n<div class='box tabular box-white'>\n  <p>\n    <label><%= l(:issue_template_name) %></label>\n    <%= h note_template.name %>\n  </p>\n  <fieldset class='issue'>\n    <legend class='issue'><%= l(:label_applied_for_issue) %></legend>\n    <p>\n      <label><%= l(:label_tracker) %></label>\n      <%= h note_template.tracker.name %>\n    </p>\n\n    <p>\n      <label><%= l(:issue_title) %></label>\n      <%= h note_template.name %>\n    </p>\n\n    <p>\n      <strong style='margin-left: -100px;'><%= l(:issue_description) %></strong>\n    </p>\n\n    <div class='wiki note_template'><%= textilizable(note_template.description) %></div>\n\n  </fieldset>\n\n  <p><label><%= l(:issue_template_note) %></label>\n    <%= note_template.memo.blank? ? l(:label_none) : note_template.memo %>\n  </p>\n\n  <p><label><%= l(:label_enabled) %></label>\n    <%= checked_image note_template.enabled? %>\n  </p>\n\n  <p><label><%= l(:field_author) %></label>\n    <%= authoring note_template.created_at, note_template.author %>\n    <% if note_template.created_at != note_template.updated_at %>\n        (<%= l(:label_updated_time, time_tag(note_template.updated_at)).html_safe %>)\n    <% end %>\n  </p>\n\n</div>\n\n<%= render partial: 'common/template_links' %>\n\n"
  },
  {
    "path": "app/views/settings/_redmine_issue_templates.html.erb",
    "content": "<div class='form-inline issue_templates'>\n  <p>\n    <label for='settings_apply_global_template_to_all_projects'><%= l(:label_apply_global_template_to_all_projects) %></label>\n    <%= hidden_field_tag(\"settings[apply_global_template_to_all_projects]\", 0, :id => nil).html_safe %>\n    <%= check_box_tag 'settings[apply_global_template_to_all_projects]', true, @settings['apply_global_template_to_all_projects'] == \"true\" %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-tooltip-area='enabled_help_area'\n       data-tooltip-content='enabled_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='enabled_help_area'></span>\n    </a>\n  </p>\n  <p>\n    <label for='settings_apply_template_when_edit_issue'><%= l(:label_use_template_when_edit) %></label>\n    <%= hidden_field_tag('settings[apply_template_when_edit_issue]', 0, :id => nil).html_safe %>\n    <%= check_box_tag 'settings[apply_template_when_edit_issue]', true, @settings['apply_template_when_edit_issue'] == 'true' %>\n  </p>\n  <p>\n    <%= link_to(l(:link_to_index_edit_template),\n              { controller: 'global_issue_templates', action: 'index' },\n              class: 'icon icon-template pull-right') %>\n  </p>\n  <p>\n    <%= link_to(l(:link_to_index_edit_note_template, default: 'Note templates list / edit templates'),\n              { controller: 'global_note_templates', action: 'index' },\n              class: 'icon icon-template pull-right') %>\n  </p>\n\n  <p>\n    <label for='settings_enable_builtin_fields'>\n      <%= l(:label_enable_builtin_fields, default: 'Enable Builtin Field support') %>\n    </label>\n    <%= hidden_field_tag('settings[enable_builtin_fields]', 0, :id => nil).html_safe %>\n    <%= check_box_tag 'settings[enable_builtin_fields]', true, @settings['enable_builtin_fields'] == 'true' %>\n    <a class='icon icon-help template-help' title='<%= l(:help_for_this_field) %>'\n       data-tooltip-area='enable_builtin_fields_help_area'\n       data-tooltip-content='enable_builtin_fields_help_content'>\n      <%= l(:help_for_this_field) %>\n      <span class='tooltip-area' id='enable_builtin_fields_help_area'></span>\n    </a>\n  </p>\n</div>\n\n<div id='enabled_help_content' class='wiki' style='display: none;'>\n  <%= l(:help_project_local_template_override_global_template) %>\n  <br>\n  <span class='icon icon-warning'></span>\n  <%= l(:warning_project_local_template_override_global_template) %>\n</div>\n\n<div id='enable_builtin_fields_help_content' class='wiki' style='display: none;'>\n  <%= l(:help_enable_builtin_fields) %>\n  <br>\n  <span class='icon icon-warning'></span>\n  <%= l(:warning_enable_builtin_fields) %>\n</div>"
  },
  {
    "path": "assets/javascripts/issue_templates.js",
    "content": "/*\n * To change this template, choose Tools | Templates\n * and open the template in the editor.\n *\n * Use '==' operator to evaluate null or undefined.\n */\n/* global CKEDITOR, Element, Event */\n'use strict'\n\nfunction ISSUE_TEMPLATE (config) {\n  this.pulldownUrl = config.pulldownUrl\n  this.loadUrl = config.loadUrl\n  this.confirmMsg = config.confirmMessage\n  this.shouldReplaced = config.shouldReplaced\n  this.generalTextYes = config.generalTextYes\n  this.generalTextNo = config.generalTextNo\n  this.isTriggeredBy = config.isTriggeredBy\n}\n\nISSUE_TEMPLATE.prototype = {\n  clearValue: (id) => {\n    let target = document.getElementById(id)\n    if (target == null) {\n      return\n    }\n    target.value = ''\n  },\n  eraseSubjectAndDescription: function () {\n    this.clearValue('issue_description')\n    this.clearValue('issue_subject')\n\n    try {\n      if (CKEDITOR.instances.issue_description) {\n        CKEDITOR.instances.issue_description.setData('')\n      }\n    } catch (e) {\n      // do nothing.\n    }\n  },\n  openDialog: function (url, title) {\n    // Open dialog (modal window) to display selectable templates list.\n    window.fetch(url)\n      .then((response) => {\n        return response.text()\n      })\n      .then((data) => {\n        document.getElementById('filtered_templates_list').innerHTML = data\n        let titleElement = document.getElementById('issue_template_dialog_title')\n        titleElement.textContent = title\n\n        const templateElements = document.querySelectorAll('i.template-update-link')\n        Array.from(templateElements).forEach(el => {\n          el.addEventListener('click', (event) => {\n            this.updateTemplateSelect(event)\n          })\n        })\n      })\n  },\n  revertAppliedTemplate: function () {\n    let issueSubject = document.getElementById('issue_subject')\n    let oldSubject = document.getElementById('original_subject')\n\n    let issueDescription = document.getElementById('issue_description')\n    let oldDescription = document.getElementById('original_description')\n    let ns = this\n\n    issueSubject.value = ns.escapeHTML(oldSubject.textContent)\n\n    if (issueDescription != null) {\n      issueDescription.value = ns.escapeHTML(oldDescription.textContent)\n    }\n\n    try {\n      if (CKEDITOR.instances.issue_description) {\n        CKEDITOR.instances.issue_description.setData(ns.escapeHTML(oldDescription.text()))\n      }\n    } catch (e) {\n      // do nothing.\n    }\n    oldDescription.textContent = ''\n    oldDescription.textContent = ''\n    document.getElementById('revert_template').classList.add('disabled')\n  },\n  loadTemplate: function () {\n    let selectedTemplate = document.getElementById('issue_template')\n    let ns = this\n\n    if (selectedTemplate.value === '') return\n\n    let templateType = ''\n    let selectedOption = selectedTemplate.options[selectedTemplate.selectedIndex]\n    if (selectedOption.classList.contains('global')) {\n      templateType = 'global'\n    }\n\n    window.fetch(ns.loadUrl,\n      {\n        method: 'POST',\n        credentials: 'same-origin',\n        headers: {\n          'Content-Type': 'application/json',\n          'X-CSRF-Token': ns.getCsrfToken()\n        },\n        body: JSON.stringify({\n          template_id: selectedTemplate.value,\n          template_type: templateType\n        })\n      })\n      .then((response) => {\n        return response.text()\n      })\n      .then((data) => {\n        // NOTE: Workaround for GiHub Issue, to prevent overwrite with default template\n        // when operator submits new issue form without required field and returns\n        // with error message. If flash message #errorExplanation exists, not overwrited.\n        // (https://github.com/akiko-pusu/redmine_issue_templates/issues/50)\n        if (document.querySelector('#errorExplanation') && document.querySelector('#errorExplanation')[0]) {\n          document.querySelector('#errorExplanation')\n          return\n        }\n\n        // Returned JSON may have the key named 'global_template' or 'issue_template'\n        let parsedData = JSON.parse(data)\n        let templateKey = Object.keys(parsedData)[0]\n        let obj = parsedData[templateKey]\n\n        obj.description = (obj.description == null) ? '' : obj.description\n        obj.issue_title = (obj.issue_title == null) ? '' : obj.issue_title\n\n        let issueSubject = document.getElementById('issue_subject')\n        let issueDescription = document.getElementById('issue_description')\n\n        this.loadedTemplate = obj\n\n        if (ns.shouldReplaced === 'true' && (issueDescription.value !== '' || issueSubject.value !== '')) {\n          if (obj.description !== '' || obj.issue_title !== '') {\n            let hideConfirmFlag = ns.hideOverwiteConfirm()\n            if (hideConfirmFlag === false) {\n              return ns.confirmToReplaceContent(obj)\n            }\n          }\n        }\n        ns.replaceTemplateValue(obj)\n      })\n  },\n  replaceTemplateValue: function (obj) {\n    let ns = this\n\n    let oldSubj = ''\n    let oldVal = ''\n    let issueSubject = document.getElementById('issue_subject')\n    let issueDescription = document.getElementById('issue_description')\n\n    if (issueDescription != null) {\n      let originalDescription = document.getElementById('original_description')\n      if (issueDescription.value !== '' && ns.shouldReplaced === 'false') {\n        oldVal = issueDescription.value + '\\n\\n'\n      }\n\n      originalDescription.textContent = issueDescription.value\n\n      issueDescription.getAttribute('original_description', issueDescription.value)\n      if (oldVal.replace(/(?:\\r\\n|\\r|\\n)/g, '').trim() !== obj.description.replace(/(?:\\r\\n|\\r|\\n)/g, '').trim()) {\n        issueDescription.value = oldVal + obj.description\n      }\n    }\n\n    let originalSubject = document.getElementById('original_subject')\n    if (issueSubject.value !== '' && ns.shouldReplaced === 'false') {\n      oldSubj = issueSubject.value + ' '\n    }\n    originalSubject.textContent = issueSubject.value\n\n    issueSubject.setAttribute('original_title', issueSubject.value)\n    if (oldSubj.trim() !== obj.issue_title.trim()) {\n      issueSubject.value = oldSubj + obj.issue_title\n    }\n\n    try {\n      if (CKEDITOR.instances.issue_description) {\n        CKEDITOR.instances.issue_description.setData(oldVal + obj.description)\n      }\n    } catch (e) {\n      // do nothing.\n    }\n    // show message just after default template loaded.\n    if (ns.confirmMsg && ns.shouldReplaced) {\n      ns.showLoadedMessage(issueDescription)\n    }\n\n    if (originalSubject.textContent.length > 0) {\n      document.getElementById('revert_template').classList.remove('disabled')\n    }\n\n    ns.setRelatedLink(obj)\n    ns.builtinFields(obj)\n    ns.confirmToReplace = true\n  },\n  confirmToReplaceContent: function (obj) {\n    let ns = this\n    let dialog = document.getElementById('issue_template_confirm_to_replace_dialog')\n    dialog.style.visibility = 'visible'\n    dialog.classList.add('active')\n\n    document.getElementById('overwrite_yes').addEventListener('click', () => {\n      if (document.getElementById('issue_template_confirm_to_replace_hide_dialog').checked) {\n        // NOTE: Use document.cookie because Redmine itself does not use jquery.cookie.js.\n        document.cookie = 'issue_template_confirm_to_replace_hide_dialog=1'\n      } else {\n        document.cookie = 'issue_template_confirm_to_replace_hide_dialog=0'\n      }\n      dialog.classList.remove('active')\n      ns.replaceTemplateValue(obj)\n    })\n\n    document.getElementById('overwrite_no').addEventListener('click', () => {\n      if (document.getElementById('issue_template_confirm_to_replace_hide_dialog').checked) {\n        // NOTE: Use document.cookie because Redmine itself does not use jquery.cookie.js.\n        document.cookie = 'issue_template_confirm_to_replace_hide_dialog=1'\n      } else {\n        document.cookie = 'issue_template_confirm_to_replace_hide_dialog=0'\n      }\n      dialog.classList.remove('active')\n    })\n\n    document.getElementById('issue_template_confirm_to_replace_dialog_cancel')\n      .addEventListener('click', () => {\n        dialog.classList.remove('active')\n      })\n  },\n  showLoadedMessage: function (target) {\n    let ns = this\n    // in app/views/issue_templates/_issue_select_form.html.erb\n    let templateStatusArea = document.getElementById('template_status-area')\n    if (templateStatusArea == null) return false\n    if (document.querySelector('div.flash_message')) {\n      document.querySelector('div.flash_message').remove()\n    }\n\n    let messageElement = document.createElement('div')\n    messageElement.innerHTML = ns.confirmMsg\n    messageElement.classList.add('flash_message')\n    messageElement.classList.add('fadeout')\n\n    templateStatusArea.appendChild(messageElement)\n  },\n  getCsrfToken: function () {\n    const metas = document.getElementsByTagName('meta')\n    for (let meta of metas) {\n      if (meta.getAttribute('name') === 'csrf-token') {\n        return meta.getAttribute('content')\n      }\n    }\n    return ''\n  },\n  setPulldown: function (tracker) {\n    let ns = this\n    let params = { issue_tracker_id: tracker, is_triggered_by: ns.isTriggeredBy }\n    let pullDownProject = document.getElementById('issue_project_id')\n    if (pullDownProject) {\n      params.issue_project_id = pullDownProject.value\n    }\n\n    window.fetch(ns.pulldownUrl,\n      {\n        method: 'POST',\n        credentials: 'same-origin',\n        headers: {\n          'Content-Type': 'application/json',\n          'X-CSRF-Token': ns.getCsrfToken()\n        },\n        body: JSON.stringify(params)\n      })\n      .then((response) => {\n        return response.text()\n      })\n      .then((data) => {\n        document.getElementById('issue_template').innerHTML = data\n        let length = document.querySelectorAll('#issue_template > optgroup > option').length\n        if (length < 1) {\n          document.getElementById('template_area').style.display = 'none'\n          if (ns.isTriggeredBy != null && this.isTriggeredBy === 'issue_tracker_id') {\n            if (document.querySelectorAll('#issue-form.new_issue').length > 0 && ns.should_replaced === true) {\n              if (typeof ns !== 'undefined') {\n                ns.eraseSubjectAndDescription()\n              }\n            }\n          }\n        } else {\n          document.getElementById('template_area').style.display = 'inline'\n        }\n        let changeEvent = new Event('change')\n        document.getElementById('issue_template').dispatchEvent(changeEvent)\n      })\n  },\n  setRelatedLink: function (obj) {\n    let relatedLink = document.getElementById('issue_template_related_link')\n    if (obj.related_link != null && obj.related_link !== '') {\n      relatedLink.setAttribute('href', obj.related_link)\n      relatedLink.style.display = 'inline'\n      relatedLink.textContent = obj.link_title\n    } else {\n      relatedLink.style.display = 'none'\n    }\n  },\n  escapeHTML: function (val) {\n    const div = document.createElement('div')\n    div.textContent = val\n    return div.textContent\n  },\n  unescapeHTML: function (val) {\n    const div = document.createElement('div')\n    div.innerHTML = val\n    return div.innerHTML\n  },\n  replaceCkeContent: function () {\n    let element = document.getElementById('issue_description')\n    return CKEDITOR.instances.issue_description.setData(element.value)\n  },\n  hideOverwiteConfirm: function () {\n    let cookieArray = []\n    if (document.cookie !== '') {\n      let tmp = document.cookie.split('; ')\n      for (let i = 0; i < tmp.length; i++) {\n        let data = tmp[i].split('=')\n        cookieArray[data[0]] = decodeURIComponent(data[1])\n      }\n    }\n    let confirmationCookie = cookieArray['issue_template_confirm_to_replace_hide_dialog']\n    if (confirmationCookie == null || parseInt(confirmationCookie) === 0) {\n      return false\n    }\n    return true\n  },\n  // support built-in field update\n  builtinFields: function (template) {\n    let ns = this\n    let builtinFieldsJson = template.builtin_fields_json\n    if (builtinFieldsJson == null) return false\n\n    try {\n      Object.keys(builtinFieldsJson).forEach(function (key) {\n        let value = builtinFieldsJson[key]\n        let element = document.getElementById(key)\n\n        if (/issue_custom_field_values/.test(key)) {\n          let name = key.replace(/(issue)_(\\w+)_(\\d+)/, '$1[$2][$3]')\n          let elements = document.querySelectorAll('[name^=\"' + name + '\"]')\n          if (elements.length === 1) {\n            element = elements[0]\n          } else {\n            return ns.updateFieldValues(elements, value)\n          }\n        }\n\n        if (/issue_watcher_user_ids/.test(key)) {\n          return ns.checkSelectedWatchers(value)\n        }\n\n        if (element == null) {\n          return\n        }\n        ns.updateFieldValue(element, value)\n      })\n    } catch (e) {\n      console.log(`NOTE: Builtin / custom fields could not be applied due to this error. ${e.message} : ${e.message}`)\n    }\n  },\n  updateFieldValue: function (element, value) {\n    // In case field is a select element, scans its option values and marked 'selected'.\n    if (element.tagName.toLowerCase() === 'select') {\n      let values = []\n      if (Array.isArray(value) === false) {\n        values[0] = value\n      } else {\n        values = value\n      }\n\n      for (let i = 0; i < values.length; i++) {\n        let options = document.querySelectorAll('#' + element.id + ' option')\n        let filteredOptions = Array.from(options).filter(option => option.text === values[i])\n        if (filteredOptions.length > 0) {\n          filteredOptions[0].selected = true\n        }\n      }\n    } else {\n      element.value = value\n    }\n  },\n  updateFieldValues: function (elements, value) {\n    let ns = this\n    for (let i = 0; i < elements.length; i++) {\n      let element = elements[i]\n      if (element.tagName.toLowerCase() === 'select') {\n        return ns.updateFieldValue(element, value)\n      }\n      if (element.value === value) {\n        if (element.tagName.toLowerCase() === 'input') {\n          element.checked = true\n        } else {\n          element.selected = true\n        }\n      }\n      // in case multiple value\n      if (Array.isArray(value)) {\n        if (element.tagName.toLowerCase() === 'input' && value.includes(element.value)) {\n          element.checked = true\n        }\n      }\n    }\n  },\n  updateTemplateSelect: function (event) {\n    let link = event.target\n    let optionId = link.getAttribute('data-issue-template-id')\n    let optionSelector = '#issue_template > optgroup > option[value=\"' + optionId + '\"]'\n    if (link.classList.contains('template-global')) {\n      optionSelector = optionSelector + '[class=\"global\"]'\n    }\n    let targetOption = document.querySelector(optionSelector)\n    targetOption['selected'] = true\n\n    let changeEvent = new Event('change')\n    document.getElementById('issue_template').dispatchEvent(changeEvent)\n  },\n  checkSelectedWatchers: function (values) {\n    let targets = document.querySelectorAll('input[name=\"issue[watcher_user_ids][]\"]')\n    for (let i = 0; i < targets.length; i++) {\n      let target = targets[i]\n      if (values.includes(target.value)) {\n        target.checked = true\n      }\n    }\n  },\n  filterTemplate: function (event) {\n    let cols = document.getElementsByClassName('template_data')\n    let searchWord = event.target.value\n    let reg = new RegExp(searchWord, 'gi')\n    for (let i = 0; i < cols.length; i++) {\n      let val = cols[i]\n      if (val.textContent.match(reg)) {\n        val.style.display = 'table-row'\n      } else {\n        val.style.display = 'none'\n      }\n    }\n  },\n  changeTemplatePlace: function () {\n    if (document.querySelector('div.flash_message')) {\n      document.querySelector('div.flash_message').remove()\n    }\n    const subjectParentNode = document.getElementById('issue_subject').parentNode\n    subjectParentNode.parentNode.insertBefore(document.getElementById('template_area'), subjectParentNode)\n  }\n}\n\n// for IE11 compatibility (IE11 does not support native Element.closest)\n// Ref. https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill\n// Ref. https://github.com/akiko-pusu/redmine_issue_templates/issues/270\nif (!Element.prototype.matches) {\n  Element.prototype.matches = Element.prototype.msMatchesSelector ||\n    Element.prototype.webkitMatchesSelector\n}\n\nif (!Element.prototype.closest) {\n  Element.prototype.closest = function (s) {\n    let el = this\n\n    do {\n      if (el.matches(s)) return el\n      el = el.parentElement || el.parentNode\n    } while (el != null && el.nodeType === 1)\n    return null\n  }\n}\n\n// --------- Add event listeners -------------- //\ndocument.onreadystatechange = () => {\n  if (document.readyState === 'complete') {\n    let templateDisabledLink = document.querySelector('a.template-disabled-link')\n    if (templateDisabledLink) {\n      templateDisabledLink.addEventListener('click', (event) => {\n        let title = event.target.title\n        if (title.length && event.target.hasAttribute('disabled')) {\n          event.preventDefault()\n          window.alert(title)\n          event.stopPropagation()\n          return false\n        }\n      })\n    }\n\n    let templateHelps = document.querySelectorAll('a.template-help')\n    for (let i = 0; i < templateHelps.length; i++) {\n      let element = templateHelps[i]\n      element.addEventListener('mouseenter', (event) => {\n        let contentId = event.target.getAttribute('data-tooltip-content')\n        if (contentId == null) return\n\n        let target = event.target.getAttribute('data-tooltip-area')\n        let obj = document.getElementById(target)\n        if (obj) {\n          obj.innerHTML = document.getElementById(contentId).innerHTML\n          obj.style.display = 'inline'\n        }\n      })\n      element.addEventListener('mouseleave', (event) => {\n        let contentId = event.target.getAttribute('data-tooltip-content')\n        if (contentId == null) return\n\n        let target = event.target.getAttribute('data-tooltip-area')\n        let obj = document.getElementById(target)\n        if (obj) {\n          obj.style.display = 'none'\n        }\n      })\n    }\n\n    let orphanedTemplateLink = document.getElementById('orphaned_template_link')\n    if (orphanedTemplateLink) {\n      orphanedTemplateLink.addEventListener('click', (event) => {\n        const url = orphanedTemplateLink.getAttribute('data-url')\n        window.fetch(url)\n          .then((response) => {\n            return response.text()\n          })\n          .then((data) => {\n            let orphanedTemplate = document.getElementById('orphaned_templates')\n            if (orphanedTemplate) {\n              orphanedTemplate.innerHTML = data\n            }\n          })\n      })\n    }\n\n    let collapsibleHelps = document.querySelectorAll('a.template-help.collapsible')\n    if (collapsibleHelps) {\n      for (let i = 0; i < collapsibleHelps.length; i++) {\n        let element = collapsibleHelps[i]\n        element.addEventListener('click', (event) => {\n          let targetName = event.target.getAttribute('data-template-help-target')\n          let target = document.getElementById(targetName)\n          if (target) {\n            let style = target.style.display\n            target.style.display = (style === 'none' ? 'inline' : 'none')\n          }\n        })\n      }\n    }\n  }\n}\n\n// ------- fot NoteTemplate\n\nfunction NOTE_TEMPLATE (config) {\n  this.baseElementId = config.baseElementId\n  this.baseTemplateListUrl = config.baseTemplateListUrl\n  this.baseTrackerId = config.baseTrackerId\n  this.baseProjectId = config.baseProjectId\n  this.loadNoteTemplateUrl = config.loadNoteTemplateUrl\n}\n\nNOTE_TEMPLATE.prototype = {\n  setNoteDescription: function (target, value, container) {\n    let element = document.getElementById(target)\n    if (element.value.length === 0) {\n      element.value = value\n    } else {\n      element.value += '\\n\\n' + value\n    }\n    element.focus()\n    container.style.display = 'none'\n\n    try {\n      if (CKEDITOR.instances.issue_notes) {\n        CKEDITOR.instances.issue_notes.setData(value)\n        CKEDITOR.instances.issue_notes.focus()\n      }\n    } catch (e) {\n      // do nothing.\n    }\n  },\n  applyNoteTemplate: function (targetElement) {\n    let ns = this\n    let templateId = targetElement.dataset.noteTemplateId\n    let projectId = document.getElementById('issue_project_id')\n    let loadUrl = ns.loadNoteTemplateUrl\n\n    let JSONdata = {\n      note_template: { note_template_id: templateId }\n    }\n\n    if (targetElement.classList.contains('template-global')) {\n      JSONdata.note_template.template_type = 'global'\n      JSONdata.note_template.project_id = ns.baseProjectId\n      if (projectId && projectId.value) {\n        JSONdata.note_template.project_id = projectId.value\n      }\n    }\n\n    let token = document.querySelector('#issue-form input[name=\"authenticity_token\"]')\n    let req = new window.XMLHttpRequest()\n    req.onreadystatechange = function () {\n      let container = targetElement.closest('div.overlay')\n      let target = container.id.replace('template_', '')\n      target = target.replace('_dialog', '')\n      if (req.readyState === 4) {\n        if (req.status === 200 || req.status === 304) {\n          let value = JSON.parse(req.responseText)\n          ns.setNoteDescription(target, value.note_template.description, container)\n        }\n      }\n    }\n    req.open('POST', loadUrl, true)\n    if (token) {\n      req.setRequestHeader('X-CSRF-Token', token.value)\n    }\n    req.setRequestHeader('Content-Type', 'application/json')\n    req.send(JSON.stringify(JSONdata))\n  },\n  changeNoteTemplateList: function (elementId) {\n    let ns = this\n    let token = document.querySelectorAll('#issue-form input[name=\"authenticity_token\"]')\n\n    let projectId = document.getElementById('issue_project_id')\n    let trackerId = document.getElementById('issue_tracker_id')\n    let templateListUrl = ns.baseTemplateListUrl\n    if (trackerId != null && projectId != null) {\n      templateListUrl += '?tracker_id=' + trackerId.value\n      templateListUrl += '&project_id=' + projectId.value\n    } else {\n      templateListUrl += '?tracker_id=' + ns.baseTrackerId + '&project_id=' + ns.baseProjectId\n    }\n\n    let req = new window.XMLHttpRequest()\n    req.onreadystatechange = function () {\n      if (req.readyState === 4) {\n        if (req.status === 200 || req.status === 304) {\n          let value = req.responseText\n          // replace here!\n          let dialog = document.getElementById(`${elementId}_dialog`)\n          let target = document.querySelector(`#${elementId}_dialog .popup .filtered_templates_list`)\n          target.innerHTML = value\n          dialog.style = 'display: block;'\n        }\n      }\n    }\n    req.open('GET', templateListUrl, true)\n    if (token) {\n      req.setRequestHeader('X-CSRF-Token', token.value)\n    }\n    req.send()\n  }\n}\n"
  },
  {
    "path": "assets/javascripts/template_fields.js",
    "content": "// This JS is used only when create / edit template. (Using Vue.js)\n'use strict'\nconst vm = new Vue({\n  el: '#json_generator',\n  data: {\n    items: [],\n    customFields: {},\n    newItemTitle: '',\n    newItemValue: '',\n    api_builtin_fields: {},\n    api_custom_fields: {},\n    customFieldUrl: ''\n  },\n  methods: {\n    addField: function (newFieldName, newFieldValue) {\n      if (newFieldName === '' || newFieldValue === '') {\n        return\n      }\n      this.items.push({\n        title: newFieldName,\n        value: newFieldValue\n      })\n      this.newFieldName = ''\n      this.newFieldValue = ''\n    },\n    deleteField: function (target) {\n      this.items = this.items.filter(function (item) {\n        return item !== target\n      })\n    },\n    loadField: function () {\n      this.api_builtin_fields = base_builtin_fields\n      this.api_custom_fields = base_custom_fields\n      this.items = []\n      if (this.api_builtin_fields) {\n        for (const [key, value] of Object.entries(this.api_builtin_fields)) {\n          this.items.push({\n            title: key,\n            value: value\n          })\n        }\n      }\n      // { \"issue_priority_id\":\"Priority\", \"issue_start_date\":\"Start date\" }\n      if (this.api_custom_fields) {\n        for (const [key, value] of Object.entries(this.api_custom_fields)) {\n\n          this.customFields[key] = value\n        }\n      }\n    },\n    updateSelectableField: function () {\n      let tmpFields = {}\n      if (this.api_custom_fields) {\n        for (const [key, value] of Object.entries(this.api_custom_fields)) {\n          tmpFields[key] = value\n        }\n      }\n      this.customFields = tmpFields\n    },\n    fieldFormat: function () {\n      const fields = this.customFields\n      const title = this.newItemTitle\n      if (fields[title] && fields[title].field_format) {\n        const format = fields[title].field_format\n        if (format === 'int' || format === 'date' || format === 'ratio' ||\n            format === 'list' || format === 'bool' || format === 'string') {\n          return fields[title].field_format\n        }\n      }\n      return 'text'\n    },\n    possibleValues: function () {\n      const fields = this.customFields\n      const title = this.newItemTitle\n      return fields[title].possible_values\n    }\n  },\n  mounted: function () {\n    const trackerPulldown = document.getElementById(trackerPulldownId)\n    if (trackerPulldown) {\n      if (trackerPulldown.value === '') {\n        this.$el.style.display = 'none'\n      }\n      trackerPulldown.addEventListener('change', event => {\n        if (event.target.value === '') {\n          this.$el.style.display = 'none'\n          return\n        }\n        this.$el.style.display = 'block'\n        const trackerId = event.target.value\n        let url = baseUrl + '?tracker_id=' + trackerId + '&template_id=' + templateId\n        if (typeof projectId !== 'undefined') {\n          url += '&project_id=' + projectId\n        }\n        window.fetch(url)\n          .then((response) => {\n            return response.text()\n          })\n          .then((data) => {\n            let obj = JSON.parse(data)\n            this.api_custom_fields = obj.custom_fields\n            this.updateSelectableField()\n          })\n      })\n    }\n    this.loadField()\n  },\n  computed: {\n    // not yet\n  },\n  watch: {\n    newItemTitle: function (val) {\n      if (typeof relativeUrlRoot === 'undefined') {\n        this.customFieldUrl = ''\n        return\n      }\n\n      let field = this.customFields[val]\n      if (field == null || field.type != 'IssueCustomField') {\n        this.customFieldUrl = ''\n        return\n      }\n      this.customFieldUrl = relativeUrlRoot + '/custom_fields/' + field.id + '/edit'\n    }\n  }\n})\n\n// Apply post data.\nconst copyJson = document.getElementById('paste-json')\nif (copyJson) {\n  copyJson.addEventListener('click', (event) => {\n    const data = document.getElementById('builtin_fields_data_via_vue')\n    if (data) {\n      const text = data.innerText\n      let jsonObj = JSON.parse(text)\n      let convertObj = {}\n      jsonObj.forEach(item => {\n        let value = item.value\n        if (item.title === 'issue_watcher_user_ids') {\n          value = item.value.map(user => {\n            let idx = user.lastIndexOf(':')\n            return user.substring(idx + 1)\n          })\n        }\n        convertObj[item.title] = value\n      })\n      document.getElementById(templateType + '_builtin_fields').value = JSON.stringify(convertObj)\n    }\n  })\n}\n"
  },
  {
    "path": "assets/stylesheets/issue_templates.css",
    "content": "fieldset.issue {\n    padding-top: 5px;\n    padding-bottom: 5px;\n    background-color: #F6F6F6;\n    margin-top: 10px;\n    margin-bottom: 10px;\n}\n\ndiv.issue_template {\n    margin-left: 100pt;\n    border: .1pt solid #E4E4E4;\n    padding: 4pt;\n    background-color: white;\n}\n\n.issue_template.help_content {\n    color: #8b0000;\n    padding: 6px;\n}\n\n#issue_template_builtin_fields, #issue_template_json_setting_field {\n    width: 60%;\n}\n\n#template_status-area .flash_message {\n    position: fixed;\n    bottom: 0;\n    right: 10px;\n    margin-left: 10px;\n    margin-top: 5pt;\n    margin-bottom: 20pt;\n    display: block;\n    font-style: italic;\n    padding: 8px 10px 8px 20px;\n    color: #31708f;\n    background: #eaf5fb url(\"../images/lamp.png\") no-repeat 3px center;\n    border: solid #a7e4fd 1px;\n}\n\n#field_information {\n    margin-left: 240px;\n    margin-right: 300px;\n    color: grey;\n}\n\noption.inherited {\n    background-color: #FCFD8D;\n    font-style: oblique;\n}\n\noption.global {\n    background-color: #FCFD8D;\n    color: darkred;\n    font-style: oblique;\n}\n\n.non_project_tracker {\n    background: url(\"../images/lamp.png\") no-repeat 3px center;\n    color: #dd8888;\n    font-style: italic;\n    font-weight: lighter;\n    padding-top: 3px;\n    padding-left: 20px;\n}\n\n.template_tracker {\n    background: url(\"../images/ticket.png\") no-repeat 3px center;\n    padding-top: 3px;\n    padding-left: 18px;\n}\n\n.template_box {\n    padding: 6px;\n    margin-bottom: 10px;\n    color: #505050;\n    line-height: 1.5em;\n    border: 1px solid #E4E4E4;\n}\n\n.icon-erase {\n    background-image: url(\"../images/eraser.png\");\n}\n\n.icon-global_issue_templates {\n    background-image: url(\"../images/issue_templates.png\");\n}\n\n.icon-template {\n    background: url(\"../images/issue_templates.png\") no-repeat 3px center;\n}\n\n.icon-hint {\n    background: url(\"../images/ticket.png\") no-repeat 3px center;\n}\n\na.template_tooltip {\n    background-image: url(\"../images/preview.png\");\n    background-repeat: no-repeat;\n    padding-left: 20px;\n}\n\n#issue_template-form textarea {\n    overflow: auto;\n}\n\n.box-white {\n    background-color: white;\n}\n\n/*--- Tooltip: Use to display template description -----*/\n\n.template_tooltip_wrapper {\n    color: #555;\n    display: inline-block;\n}\n\n/* Hide tooltip body */\n\n.template_tooltip_wrapper .template_tooltip_body {\n    display: none;\n}\n\n/* Mouse over action */\n\n.template_tooltip_wrapper:hover {\n    position: relative;\n    color: #333;\n}\n\n/* tooltip body */\n\n.template_tooltip_wrapper:hover .template_tooltip_body {\n    text-align: left;\n    display: block;\n    position: absolute;\n    top: 12px;\n    left: 0;\n    font-size: 90%;\n    background-color: #ffffff;\n    min-width: 300px;\n    padding: 8px 10px 12px;\n    border: 1px solid #CCCCCC;\n    z-index: 20000;\n    word-break: break-all;\n    word-wrap: break-word;\n    white-space: normal;\n}\n\n.template_tooltip_wrapper:hover .template_tooltip_body .title {\n    color: #979797;\n    padding-bottom: 10px;\n    font-weight: bold;\n    display: inline-block;\n    font-style: italic;\n}\n\ntable.list.template_list {\n  margin: 8px 0;\n  border: 2px solid #e4e4e4;\n  overflow: visible;\n}\n\ntd.template_title {\n    max-width: 200px;\n    overflow: hidden;\n    text-overflow: ellipsis;\n}\n\n.list.template_list th {\n    text-align: left;\n}\n\n.list.template_list td {\n    text-align: left;\n    padding: 5px;\n}\n\n.overflow_dialog {\n    overflow: visible;\n    width: auto;\n}\n\n.filtered_templates_list {\n    padding-top: 2px;\n}\n\nselect.issue_template {\n    width: 240px;\n}\n\n.issue_template.icon.settings {\n    background: url(\"../images/lamp.png\") no-repeat 3px center;\n}\n\n.issue_template.icon.plugins {\n    background: url(\"../../../images/plugin.png\") no-repeat 3px center;\n}\n\n.contextual.issue_templates {\n    margin-bottom: 5px;\n}\n\n.popup p {\n    margin-left: 0;\n    padding-left: 0;\n}\n\n#revert_template {\n    -webkit-transition: .3s ease-in-out;\n    transition: .3s ease-in-out;\n}\n\n#revert_template:not(.disabled):hover {\n    -webkit-animation: scale .4s ease-in-out;\n    animation: scale .4s ease-in-out;\n}\n\n@-webkit-keyframes scale {\n    50% {\n        -webkit-transform: scale(1.04);\n    }\n}\n\n@keyframes scale {\n    50% {\n        transform: scale(1.04);\n    }\n}\n\n#revert_template.disabled {\n    filter: alpha(opacity=20);\n    -moz-opacity: .2;\n    opacity: .2;\n}\n\na.icon.icon-del[disabled=disabled] {\n    opacity: .5;\n}\n\n#fields_setting_display_area {\n    margin-left: 180px;\n}\n\n#template-help-message-area > p {\n    padding-left: 4px;\n}\n\n/*------------ for responsive -----------------*/\n\n@media (max-width: 899px) {\n    #orphaned_templates>table>thead>tr>th.hideable {\n        display: none;\n    }\n    #orphaned_templates>table>tbody>tr>td.hideable {\n        display: none;\n    }\n    #content>div.template_box>table>thead>tr>th.hideable {\n        display: none;\n    }\n    #content>div.template_box>table>tbody>tr>td.hideable {\n        display: none;\n    }\n    #fields_setting_display_area {\n        margin-left: 0;\n    }\n    #field_information {\n        margin-left: 0;\n        margin-right: 0;\n    }\n}\n\n/*---- help tooltip --*/\na.icon-help.template-help {\n    cursor: help;\n}\n\na.icon-help .tooltip-area {\n    display: none;\n    position: absolute;\n    width: 300px;\n    margin-left: 8px;\n    padding: 8px;\n    border: 1px solid #cccccc;\n    background-color: #FFFFFF;\n    color: #000000;\n    font-size: 12px;\n    line-height: 1.6;\n}\n\na.icon-help:hover .tooltip-area {\n    display: inline;\n}\n\n/*--------- Note Template / Issue Template popup --------*/\n.overlay {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    background: rgba(87, 87, 87, 0.311);\n    transition: opacity 500ms;\n    visibility: hidden;\n    opacity: 0;\n    overflow: visible;\n    width:100%;\n    height:100%;\n    z-index: -1;\n}\n.overlay:target, .overlay.active {\n    visibility: visible;\n    opacity: 1;\n    z-index: 10;\n}\n\n.popup {\n    margin: 100px auto;\n    padding: 20px;\n    background: #fff;\n    border-radius: 5px;\n    width: 60%;\n    max-width: 860px;\n    min-width: 520px;\n    position: relative;\n    transition: all 5s ease-in-out;\n}\n\n.popup h2 {\n    margin-top: 0;\n    margin-bottom: 0;\n    color: #333;\n    background-color: #c6d9ec;\n    font-family: Tahoma, Arial, sans-serif;\n}\n\n.popup .close {\n    position: absolute;\n    width: 20px;\n    height: 20px;\n    top: 20px;\n    right: 20px;\n    opacity: 0.8;\n    transition: all 200ms;\n    font-size: 24px;\n    font-weight: bold;\n    text-decoration: none;\n    color: #666;\n    line-height: initial;\n}\n\n.popup .close:hover {\n    color: #06D85F;\n    opacity: 1;\n}\n\n.popup .content {\n  max-height:50%;\n  overflow: auto;\n}\n\n.popup.small {\n    width: 500px;\n    text-align: center;\n}\n\n#note_template_memo {\n    width: 50%;\n}\n\n.light .popup {\n    border-color: #aaa;\n    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);\n}\n\n.popup label {\n    margin-left: 0;\n    text-align: left;\n}\n\n.popup_header a.close {\n    margin-right: 8px;\n}\n\n.popup_header h2 {\n    font-size: 12pt;\n}\n\n.overlay .header_wrapper {\n    width: auto;\n    background-color: #c6d9ec;\n    padding: 6px;\n    margin-bottom: 2px;\n}\n\n.overlay .cancel {\n    position: absolute;\n    width: 100%;\n    height: 100%;\n    cursor: default;\n}\n\n.overlay .template_search_filter_wrapper {\n    margin-top:  8px;\n    margin-bottom: 8px;\n}\n\n/*--------- for Flash message --------*/\n.fadeout {\n    animation : fadeOut 5s;\n    animation-fill-mode: both;\n}\n\n@keyframes fadeOut {\n    0% {\n      opacity: 1;\n    }\n    100% {\n      opacity: 0;\n    }\n}\n/*--------- for Flash message --------*/\n\n/*--------- for Template related Link --------*/\ndiv.template_link_area {\n    margin-right: 10px;\n    border: rgb(202, 200, 197);\n    border-width: 1px;\n    border-style: solid;\n    padding-left: 10px;\n    padding-right: 40px;\n    padding-top: 4px;\n    padding-bottom: 4px;\n}\n\ndiv.template_link_area label {\n    font-weight: bold;\n}\n\n.template-update-link {\n    cursor: pointer;\n}\n/*--------- for Template related Link --------*/\n\n.overwrite_confirm_btn {\n    margin-top: 10px;\n    display: inline-block;\n    position: relative;\n    width: 100px;\n    padding: 0.8em;\n    text-align: center;\n    text-decoration: none;\n    color: #1B1B1B;\n    background: #fff;\n    border:1px solid rgb(165, 164, 164);\n    border-radius: 6px;\n}\n\n/*--------- for Overwrite Confirmation --------*/\n.overwrite_confirm_btn:hover {\n     background: rgb(190, 187, 187);\n     color: #fff;\n     cursor: pointer;\n     text-decoration: none;\n}\n\n#template_area > p a {\n    display: inline-block;\n    margin-right: .85em;\n}\n\n#template_help_content {\n    position: relative;\n    text-align: left;\n    margin-left: .5em;\n}\n\n#template_help_content p {\n    padding-left: 5px;\n}\n\n#template-help-wiki > p {\n    padding-left: 5px;\n}\n\n#filtered_templates_list > table div.wiki.template_tooltip_body p {\n    padding-left: 0;\n}\n\nul.json-list {\n    width: 70%;\n    padding: 10px;\n    background-color: white;\n}\n\nul.json-list li {\n    list-style: none;\n    line-height: 1.6em;\n    padding: 0.5em 0;\n}\n\nform#global_issue_template-form select[multiple=multiple] {\n    min-width: 120px;\n}\n\nform#issue_template-form select[multiple=multiple] {\n    min-width: 120px;\n}\n"
  },
  {
    "path": "config/locales/bg.yml",
    "content": "# Bulgarian translation\r\nbg:\r\n  issue_templates: Шаблони\r\n  issue_template: Шаблони за задачи\r\n  issue_template_note: Описание на шаблона, което не се показва при създаване на задачите\r\n  label_enabled: \"Активиране\"\r\n  label_disabled: \"Забранено\"\r\n  label_help_message: \"Кратко описание на работата с шаблоните в този проект\"\r\n  label_show_help_message: \"Показване на помощ при създаване на задачи\"\r\n  about_help_message: \"Всеки проект може да има свое помощно съобщение за шаблоните.\"\r\n  close_help: \"Затваряне\"\r\n  about_template_help_message: \"Можете да видите инструкция за шаблоните на този проект\"\r\n  label_enabled_help_message: \"Активиране на шаблона. Ако този шаблон е все още недовършен, изключете това поле.\"\r\n  label_list_templates: \"Списък\"\r\n  label_new_templates: \"Нов шаблон\"\r\n  issue_template_name: \"Наименование\"\r\n  issue_description: \"Описание на задачата\"\r\n  issue_title: \"Заглавие на задачата (поле \\\"Относно:\\\")\"\r\n  label_applied_for_issue: \"Полета, приложени към задачата: \"\r\n  help_for_issue_title: \"Ако дефинирате заглавие, то ще бъде приложено към полето \\\"Относно:\\\" при избиране на шаблона.\"\r\n  help_for_this_field: \"Помощ за това поле\"\r\n  permission_manage_issue_templates: \"Управление на шаблони\"\r\n  permission_edit_issue_templates: \"Редактиране на шаблони\"\r\n  permission_show_issue_templates: \"Използване на шаблони\"\r\n  project_module_issue_templates: \"Шаблони за задачи\"\r\n  label_isdefault_help_message: \"Подразбиращ се шаблон за този тракер.\"\r\n  defaulf_template_loaded: \"Подразбиращият се шаблон е зареден в описанието на задачата. (Тракер: %{tracker})\"\r\n  text_no_tracker_enabled: \"Не са избрани тракери за този проект.\\nПърво изберете тракери, понеже шаблоните се свързват с проектните тракери. \"\r\n  label_enabled_sharing: \"Разрешено споделянето с дървото на проектите.\"\r\n  label_inherit_templates: \"Наследяване на шаблоните\"\r\n  label_inherit_templates_help_message: \"Наследяване на шаблоните от родителския проект. (Показват се само шаблоните, които са споделени с дървото на проектите.)\"\r\n  label_inherited_templates: \"Наследени шаблони\"\r\n  no_issue_templates_for_this_project: \"За този проект не са дефинирани шаблони.\"\r\n  link_to_index_edit_template: \"Списък на шаблоните / редактиране на шаблони\"\r\n  erase_issue_subject_and_description: \"Изчистване на заглавието и описанието.\"\r\n  unused_tracker_at_this_project: \"Забележка: Този тракер не е дефиниран за използване в този проект. Моля проверете и редактрирайте конфигурацията на шаблона, ако е необходимо.\"\r\n  label_enabledshaing_help_message: \"Ако е избрано, този шаблон може да се използва във вложените (child) проекти. (Също така, вие трябва да активирате опцията за наследяване във вложените проекти.)\"\r\n  label_should_replaced: \"Замяна на заглавието и описанието\"\r\n  label_should_replaced_help_message: \"Ако е избрано, съществуващото заглавие и описание се премахват и заменят с текстовете от шаблона. （По подразбиране не е избрано, и текстовете се добавят.)\"\r\n  global_issue_templates: \"Глобални шаблони за задачи\"\r\n  no_issue_templates_for_this_redmine: \"Глобални шаблони не са дефинирани.\"\r\n  only_admin_can_associate_global_template: \"Само администраторите на Redmine могат да асоциират глобални шаблони с с тожи проект.\"\r\n  text_no_tracker_enabled_for_global: \"Не са дефинирани тракери.\\nПърво дефинирайте тракери, понеже шаблоните се асоциират с тракери.\"\r\n  display_and_filter_issue_templates_in_dialog: \"Преглед\"\r\n  label_filter_template: \"Филтриране на шаблоните\"\r\n  label_msg_confirm_to_replace: \"Желаете да замените заглавието и описанието?\"\r\n  label_apply_global_template_to_all_projects: \"Прилагане на глобалните шаблони към всички проекти.\"\r\n  note_apply_global_template_to_all_projects_setting_enabled: \"Този глобален шаблон е приложен към всички проекти в конфигурацията на плъгина.\"\r\n  project_list_associated_this_template: \"Проекти:  (приложени: %{applied} от %{all})\"\r\n  note_project_local_template_override_global_template: \"Ако съществува локален шаблон в проекта, тпой ще има приоритет пред глобални шаблони.\"\r\n  help_project_local_template_override_global_template: \"Ако тази опция е активна, всеки глобален шаблон ще бъде приложен към всички проекти. Ако в даден проект има шаблон за същия тракер, то той има приоритет пред глобалния шаблон. Глобалният шаблон не се показва в списъка с шаблони при създаване на задача.\"\r\n  warning_project_local_template_override_global_template: \"Моля бъдете внимателни, когато създавате глобални шаблони, които съдържат конфиденциална информация. Ако тази опция е активирана, всички глобални шаблони ще бъдат приложени към всички проекти.\"\r\n  revert_before_applying_template: \"Отмяна\"\r\n  template_remove_confirm: \"Да бъде ли премахнат шаблонът? %{count} подпроекта използват този шаблон.\"\r\n  label_number_of_subprojects_use_this_template: \"%{count} подпроекта използват този шаблон.\"\r\n  enabled_template_cannot_destroy: \"Само забранени шаблони могат да бъдат премахвани. Проверете дали други подпроекти използват този шаблон или не и го забранете преди да го изтриете.\"\r\n  orphaned_templates: \"Шаблони без тракер\"\r\n  orphaned_template: \"Шаблон без тракер\"\r\n  label_template_applied: \"Шаблонът беше приложен. Можете да възстановите старото състояние, като натиснете връзката 'Отмяна'.\"\r\n  label_hide_confirm_dialog_in_the_future: \"Без потвърждение за в бъдеще, направо прилагане на шаблона.\"\r\n  label_template_for_note: \"Шаблон за коментар\"\r\n  label_use_template_when_edit: \"Използване на шаблони когато се редактират задачи\"\r\n  note_template: \"Шаблон за коментар\"\r\n  no_note_templates_for_this_project: \"Шаблони за коментари не са дефинирани за този проект.\"\r\n  label_memo_help_message: \"Моля запишете тук обяснителна бележка, която се появява при прилагане на този шаблон.\"\r\n  note_template_name: \"Име на шаблона за коментар\"\r\n  note_description: \"Коментар\"\r\n  field_template_visibility: Видимост на шаблоните\r\n  note_templates:\r\n    visibility:\r\n      mine: само за мен\r\n      roles: само за тези роли\r\n      open: за всички потребители\r\n  please_select_at_least_one_role: \"Моля изберете поне една роля.\"\r\n  issue_templates_settings: Конфигурация за шаблони за задачи\r\n  issue_templates_optional_settings: Допълнителна конфигурация, по избор\r\n  issue_template_related_link: Връзка\r\n  issue_template_link_title: Заглавие на връзката\r\n  label_related_link_help_message: \"Ако имате примерни страници или задачи, които използват шаблона, моля запишете тук връзка към тях. Така потребителят може да ги види за примери.\"\r\n  label_link_title_help_message: \"Можете да зададете заглавите на връзката (По подразбиране : Връзка)\"\r\n  enter_value: Моля въведете стойност.\r\n  label_select_field: Изберете полета\r\n  label_builtin_fields_help_message: Въведете потребителски полета и стойности за тях. След това натиснете бутон \"Потвърждение\" за генериране на данни в JSON формат.\r\n  label_builtin_fields_json: JSON за полета\r\n  label_enable_builtin_fields: Разрешаване на поддръжка за потребителски полета\r\n  help_enable_builtin_fields: Ако тази поддръжка е позволена, ще се покаже форма, в която можете да установите шаблони за потребителски полета. Моля записвайте данните в JSON формат.\r\n  warning_enable_builtin_fields: Моля бъдете внимателни, ако активирате тази поддръжка, защото тя все още е в експериментален стадий. Все още не е предвиден достатъчно UI и функции за поддръжка на всички типове полета. Възможна е несигурна работа в зависимост от браузъра. Бъдете внимателни.\r\n  label_field_information: Информация за полето\r\n  unavailable_fields_for_this_tracker: Недостъпно поле за този тракер\r\n  global_note_templates: Глобален шаблон за коментар\r\n  link_to_index_edit_note_template: Шаблони за коментари / редактиране на шаблони\r\n"
  },
  {
    "path": "config/locales/da.yml",
    "content": "﻿# Danish strings go here for Rails i18n\nda:\n  issue_templates: Sagsskabeloner\n  issue_template: Sagsskabelon\n  issue_template_note: Note\n  label_enabled: Aktiveret\n  label_disabled: Deaktiveret\n  label_help_message: Skabelon-hjælpetekst\n  label_show_help_message: Vis hjælpetekst ved oprettelse eller redigering af sag.\n  about_help_message: Hvert projekt kan have sin egen hjælpetekst.\n  close_help: Luk hjælpetekst.\n  about_template_help_message: Du kan se instruktioner om sagsskabeloner på dette projekt.\n  label_enabled_help_message: Tjekboks til aktivering af denne skabelon. Fjern afkrydsning for at gemme som kladde.\n  label_list_templates: \"Skabeloner\"\n  label_new_templates: \"Tilføj skabelon\"\n  issue_template_name: \"Skabelonnavn\"\n  issue_description: \"Sagsbeskrivelse\"\n  issue_title: \"Sagsemne\"\n  label_applied_for_issue: \"Felter: \"\n  help_for_issue_title: \"Hvis sat, vil sagens emnefelt blive udfyldt når skabelonen vælges.\"\n  help_for_this_field: \"Forklaring til dette felt.\"\n  permission_manage_issue_templates: \"Administrér skabeloner\"\n  permission_edit_issue_templates: \"Ret skabeloner\"\n  permission_show_issue_templates: \"Vis skabeloner\"  \n  project_module_issue_templates: \"Sagsskabeloner\"\n  label_isdefault_help_message: \"Anvend som den forudvalgte skabelon på sagstypen.\"\n  defaulf_template_loaded: \"Indlæste forudvalgt skabelon. (Tracker: %{tracker})\"\n  text_no_tracker_enabled: \"Der er ikke defineret sagstyper for dette projekt.\\nSæt disse inden der defineres sagsskabeloner.. \"\n  label_enabled_sharing: \"Del med projekttræet.\"\n  label_inherit_templates: \"Arv sagsskabeloner\"\n  label_inherit_templates_help_message: \"Arv sagsskabeloner fra hovedprojekt. Hovedprojektets sagsskabeloner skal være delt med projekttræet.\"\n  label_inherited_templates: \"Nedarvede sagsskabeloner\"\n  no_issue_templates_for_this_project: \"Ingen sagsskabeloner defineret for dette projekt.\"\n  link_to_index_edit_template: \"Sagsskabeloner / ret skabeloner\"\n  erase_issue_subject_and_description: \"Tøm emne og beskrivelse.\"\n  unused_tracker_at_this_project: \"NB: Sagstypen anvendes ikke med projektet.\"\n  label_enabledshaing_help_message: \"Hvis valgt deles skabelonen med underliggende projekter. (Arv sagsskabeloner skal dog være valgt til på underprojekter.)\"\n  label_should_replaced: \"Erstat emne og beskrivelse\"\n  label_should_replaced_help_message: \"Hvis valgt erstattes emne og beskrivelse med skabelonen. Ellers tilføjes skabelonens indhold den eksisterende tekst.\"\n  global_issue_templates: \"Fælles sagsskabeloner\"\n  no_issue_templates_for_this_redmine: \"Ingen fælles sagsskabeloner defineret.\"\n  only_admin_can_associate_global_template: \"Kun administratorer kan sammenkoble fælles sagsskabeloner med projekter.\"\n  text_no_tracker_enabled_for_global: \"Der er ikke defineret nogen sagstyper.\\nSæt disse inden der defineres sagsskabeloner.\"\n  display_and_filter_issue_templates_in_dialog: \"Filtrér Skabeloner\"\n  label_filter_template: \"Filtrér Skabeloner\"\n  "
  },
  {
    "path": "config/locales/de.yml",
    "content": "# German strings go here for Rails i18n\r\nde:\r\n  issue_templates: Vorlagen\r\n  issue_template: Ticketvorlage\r\n  issue_template_note: Notiz\r\n  label_enabled: aktivieren\r\n  label_disabled: deaktivieren\r\n  label_help_message: Hilfe\r\n  label_show_help_message: Hilfe-Dialog im Vorlagenformular anzeigen\r\n  about_help_message: Jedes Projekt kann die Onlinehilfe für ihre Vorlagen definieren.\r\n  close_help: Hilfedialog schließen\r\n  about_template_help_message: Dies ist die Onlinehilfe für Ticketvorlagen in diesem Projekt.\r\n  label_enabled_help_message: Diese Vorlage aktivieren. Deaktvieren Sie diese Checkbox, um die Vorlage als Entwurf abzulegen.\r\n  label_list_templates: Vorlagenliste\r\n  label_new_templates: Vorlage hinzufügen\r\n  issue_template_name: Vorlagenname\r\n  issue_description: Beschreibung\r\n  issue_title: Thema\r\n  label_applied_for_issue: \"Vorausgefüllte Felder:\"\r\n  help_for_issue_title: \"Der hier angegebene Text wird als Thema im neuen Ticket übernommen, falls die Vorlage ausgewählt wird.\"\r\n  help_for_this_field: Hilfe\r\n  permission_manage_issue_templates: Vorlagen verwalten\r\n  permission_edit_issue_templates: Vorlagen ändern\r\n  permission_show_issue_templates: Vorlagen anzeigen\r\n  project_module_issue_templates: Ticketvorlagen\r\n  label_isdefault_help_message: Aktivieren Sie diese Option um die Vorlage als Standard für den Standardtracker zu verwenden.\r\n  defaulf_template_loaded: \"Die Standardvorlage für den Tracker '%{tracker}' wurde in das Beschreibungsfeld übernommen.\"\r\n  text_no_tracker_enabled: Bisher wurde keine Konfiguration der Tracker und Ticketvorlagen für dieses Projekt vorgenommen.\\nBitte konfigurieren Sie diese notwendige Einstellung, um die Funktion zu nutzen.\r\n  label_enabled_sharing: Vererbung mit Projektbaum erlauben.\r\n  label_inherit_templates: Vorlagen vererben\r\n  label_inherit_templates_help_message: Vorlage von Elternprojekt erben (nur falls Vererbung erlaubt)\r\n  label_inherited_templates: Geerbte Vorlagen\r\n  no_issue_templates_for_this_project: Für dieses Projekt sind keine Vorlagen definiert.\r\n  link_to_index_edit_template: Vorlagenliste / Vorlagen bearbeiten\r\n  erase_issue_subject_and_description: Lösche Thema und Beschreibung\r\n  unused_tracker_at_this_project: \"ACHTUNG: Dieser Tracker ist für dieses Projekt nicht aktiviert. Bitte Vorlage anpassen.\"\r\n  label_enabledshaing_help_message: Falls aktiv kann diese Vorlage an Unterprojekte vererbt werden.\r\n  label_should_replaced: Ersetze Thema und Beschreibung\r\n  label_should_replaced_help_message: Falls aktiv werden Thema und Beschreibung gelöscht und durch den Vorlagentext ersetzt. Ansonsten wird der Vorlagentext am Ende angehangen.\r\n  global_issue_templates: Globale Ticketvorlagen\r\n  no_issue_templates_for_this_redmine: Es sind keine globalen Ticketvorlagen definiert.\r\n  only_admin_can_associate_global_template: Nur Administratoren können globale Vorlagen diesem Projekt zuweisen.\r\n  text_no_tracker_enabled_for_global: Es sind keine Tracker aktiviert.\\nVor der Definition von Vorlagen muss mindestens ein Tracker im Projekt freigegeben sein.\r\n  display_and_filter_issue_templates_in_dialog: Vorlagen ansehen und filtern\r\n  label_filter_template: Vorlagen filtern\r\n  label_msg_confirm_to_replace: \"Soll das aktuelle Thema und die Beschreibung durch die Vorlage ersetzt werden?\"\r\n  label_apply_global_template_to_all_projects: \"Wende Globale Ticketvorlagen auf alle Projekte an.\"\r\n  note_apply_global_template_to_all_projects_setting_enabled: \"Diese Globale Ticketvorlage wird auf alle Projekte angewendet weil das Vorlagen-Plugin entsprechend konfiguriert ist.\"\r\n  project_list_associated_this_template: \"Projekte:  (angewendet auf: %{applied} von %{all})\"\r\n  note_project_local_template_override_global_template: \"Wenn eine lokale Projektvorlage vorhanden ist, überschreiben Sie globale Vorlagen, und globale Vorlagen werden auf dem Bildschirm zum Erstellen von Problemen nicht angezeigt.\"\r\n  help_project_local_template_override_global_template: \"Wenn diese Option aktiviert ist, werden alle globalen Ticketvorlagen auf alle Projekte angewendet. Wenn eine projektspezifische Vorlage pro Tracker festgelegt ist, wird diese überschrieben und die globale Vorlage wird auf dem Bildschirm zur Erstellung neuer Tickets ausgeblendet.\"\r\n  warning_project_local_template_override_global_template: \"Bitte seien Sie vorsichtig globale Problemvorlagen mit vertraulichen Inhalten zu hinterlegen. Wenn diese Option aktiviert ist, werden alle globalen Vorlagen auf alle Projekte angewendet.\"\r\n  revert_before_applying_template: \"Rückgängig\"\r\n  template_remove_confirm: \"Möchten Sie dieses Template wirklich löschen? %{count} Unterprojekte nutzen diese Vorlage.\"\r\n  label_number_of_subprojects_use_this_template: \"%{count} Unterprojekte nutzen diese Vorlage.\"\r\n  enabled_template_cannot_destroy: \"Nur deaktivierte Vorlagen können gelöscht werden! Prüfe ob andere (Unter-)Projekte diese Vorlage verwenden und deaktiviere sie dort.\"\r\n  orphaned_templates: \"Verwaiste Vorlage vom Tracker\"\r\n  orphaned_template: \"Verwaiste Vorlage vom Tracker\"\r\n  label_template_for_note: \"Notizvorlage\"\r\n  label_use_template_when_edit: \"Verwenden Sie Vorlagen, wenn Sie das Problem bearbeiten\"\r\n  note_template: \"Notizvorlage\"\r\n  note_template_name: Name für Notizvorlage\r\n  label_template_applied: Die Ausgabevorlage wird angewendet. Sie können mit dem Link \"Zurücksetzen\" rückgängig gemacht werden.\r\n  label_hide_confirm_dialog_in_the_future: \"Diese Bestätigung in Zukunft ausblenden, einfach überschreiben.\"\r\n  no_note_templates_for_this_project: \"Für dieses Projekt sind keine Kommentarvorlagen definiert.\"\r\n  label_memo_help_message: \"Bitte richten Sie einen Hinweis ein, der erklärt, wann Sie diese Vorlage anwenden.\"\r\n  note_description: \"Comment body\"\r\n  field_template_visibility: Sichtbarkeit von Vorlagen\r\n  note_templates:\r\n    visibility:\r\n      mine: nur für mich\r\n      roles: nur für diese Rolle\r\n      open: für alle\r\n  please_select_at_least_one_role: \"Bitte zunächst eine Rolle auswählen\"\r\n  issue_templates_settings: Template Einstellungen\r\n  issue_templates_optional_settings: Optionale Template Einstellungen\r\n  issue_template_related_link: Verwandter Link\r\n  issue_template_link_title: Zugehöriger Link-Titel\r\n  label_related_link_help_message: \"Bitte bei Beispielseiten oder Beispieltickets die Vorlagen nutzen den Link angeben. So können Benutzer diese Beispiele ansehen.\"\r\n  label_link_title_help_message: \"Sie können den Titel des zugehörigen Links anpassen. (Standard: Verwandter Link)\"\r\n  enter_value: Bitte einen Wert eingeben.\r\n  label_select_field: Wählen Sie ein Feld aus\r\n  label_builtin_fields_help_message: Geben Sie eigene Felder oder benutzerdefinierte Felder als Standardwerte im JSON-Format ein. Bitte Felder auswählen und Werte einstellen. Klicken Sie dann auf \"Übernehmen\" und Sie können Daten im JSON-Format generieren.\r\n  label_builtin_fields_json: JSON für Felder\r\n  label_enable_builtin_fields: Aktivieren Sie die integrierte Feldunterstützung\r\n  help_enable_builtin_fields: Wenn dieses Flag aktiviert ist, wird ein Formular angezeigt in dem Sie Vorlagen für integrierte oder benutzerdefinierte Felder festlegen können. Bitte registrieren Sie die Einstellungen im JSON-Format.\r\n  warning_enable_builtin_fields: Bitte mit Vorsicht dieses Flag zu aktivieren. Diese Funktion ist nur experimentell. Da ich noch nicht genügend UI und Funktionen zur Verfügung gestellt habe, um alle Feldtypen zu unterstützen. Je nach Browser funktioniert dies möglicherweise nicht. Nutzen Sie diese Funktion in einer Produktionsumgebung mit Vorsicht.\r\n  label_field_information: Feld Information\r\n  unavailable_fields_for_this_tracker: Feld für diesen Tracker nicht verfügbar\r\n"
  },
  {
    "path": "config/locales/en.yml",
    "content": "# English strings go here for Rails i18n\nen:\n  issue_templates: Issue templates\n  issue_template: Issue template\n  issue_template_note: Note\n  label_enabled: Enable\n  label_disabled: Disable\n  label_help_message: About templates\n  label_show_help_message: Show help message when creating/updating issues.\n  about_help_message: Each project can have custom help messages for templates.\n  close_help: Close help message.\n  about_template_help_message: You can see the instruction of issue templates on this project.\n  label_enabled_help_message: Checkbox to activate this template. If you would like to save this template as a draft, un-check this box.\n  label_list_templates: \"Template list\"\n  label_new_templates: \"Add template\"\n  issue_template_name: \"Template name\"\n  issue_description: \"Issue body\"\n  issue_title: \"Issue title\"\n  label_applied_for_issue: \"Fields applied for issue: \"\n  help_for_issue_title: \"If the Issue title is defined, it will be applied to the Subject of an issue when selecting this template.\"\n  help_for_this_field: \"Help for this field.\"\n  permission_manage_issue_templates: \"Manage Templates\"\n  permission_edit_issue_templates: \"Edit Templates\"\n  permission_show_issue_templates: \"Show Templates\"\n  project_module_issue_templates: \"Issue Templates\"\n  label_isdefault_help_message: \"Check and you can use this as a default template for the target tracker.\"\n  defaulf_template_loaded: \"Loaded default template into description textarea. (Tracker: %{tracker})\"\n  text_no_tracker_enabled: \"Any trackers for this project have not been configured yet.\\nPlease set them first because templates are assigned to project trackers. \"\n  label_enabled_sharing: \"Enabled sharing with project tree.\"\n  label_inherit_templates: \"Inherit templates\"\n  label_inherit_templates_help_message: \"Inherit templates from parent project. (Only parent's templates are listed which marked as enabled sharing with project tree.)\"\n  label_inherited_templates: \"Inherited templates\"\n  no_issue_templates_for_this_project: \"No issue templates are defined for this project.\"\n  link_to_index_edit_template: \"Issue templates list / edit templates\"\n  erase_issue_subject_and_description: \"Clear subject and description text.\"\n  unused_tracker_at_this_project: \"NOTE: This tracker is not defined to use for this project. Please re-define template setting if necessary.\"\n  label_enabledshaing_help_message: \"If true, this template can be shared with descendant projects. (You also have to activate Inherited template option at child project.)\"\n  label_should_replaced: \"Replace subject and description\"\n  label_should_replaced_help_message: \"If true, existing subject and description are cleared and replaced with template text.（Default is false, and appended text.)\"\n  global_issue_templates: \"Global Issue Templates\"\n  no_issue_templates_for_this_redmine: \"No global issue templates are defined for this Redmine site.\"\n  only_admin_can_associate_global_template: \"Only Redmine administrator can associate global templates with this project.\"\n  text_no_tracker_enabled_for_global: \"Trackers are not defined yet.\\nPlease set them first because templates are assigned to trackers.\"\n  display_and_filter_issue_templates_in_dialog: \"Preview Template Contents\"\n  label_filter_template: \"Filter templates\"\n  label_msg_confirm_to_replace: \"Do you replace subject and description?\"\n  label_apply_global_template_to_all_projects: \"Apply Global issue templates to all the projects.\"\n  note_apply_global_template_to_all_projects_setting_enabled: \"This global issue template is applied to all the project by plugin setting.\"\n  project_list_associated_this_template: \"Project List:  (applied: %{applied} of %{all})\"\n  note_project_local_template_override_global_template: \"If project local template exists, override global templates and any global templates are not shown on create issue screen.\"\n  help_project_local_template_override_global_template: \"If this option is activated, every global ticket templates will be applied to all projects. If a project-specific template per tracker is set, it takes override and the global template is hidden on the new ticket creation screen.\"\n  warning_project_local_template_override_global_template: \"Please be careful when registering global issue template, that contain confidential content you want to pay attention to. In case this option is activated, all the global templates will be applied to all projects.\"\n  revert_before_applying_template: \"Revert\"\n  template_remove_confirm: \"Are you sure to remove this template？ %{count} subprojects use this template.\"\n  label_number_of_subprojects_use_this_template: \"%{count} subprojects use this template.\"\n  enabled_template_cannot_destroy: \"Only disabled template can be destroyed. Check if other subprojects use this template or not, and disable this before deleting.\"\n  orphaned_templates: \"Orphaned templates from tracker\"\n  orphaned_template: \"Orphaned template from tracker\"\n  label_template_applied: \"Issue template is applied. You can revert with click 'Revert' link.\"\n  label_hide_confirm_dialog_in_the_future: \"Hide this confirmation in the future, just overwrite.\"\n  label_template_for_note: \"Template for note\"\n  label_use_template_when_edit: \"Use templates when edit issue\"\n  note_template: \"Template for note\"\n  no_note_templates_for_this_project: \"No comment templates are defined for this project.\"\n  label_memo_help_message: \"Please set up a note explaining when applying this template.\"\n  note_template_name: \"Template name for note\"\n  note_description: \"Comment body\"\n  field_template_visibility: Templates visibility\n  note_templates:\n    visibility:\n      mine: to me only\n      roles: to these roles only\n      open: to any users\n  please_select_at_least_one_role: \"Please select at least one role.\"\n  issue_templates_settings: Issue Templates Setting\n  issue_templates_optional_settings: Templates Optional Settings\n  issue_template_related_link: Related Link\n  issue_template_link_title: Related Link Title\n  label_related_link_help_message: \"If there are some example pages or sample issues which using issue template, please specify the link. So operator can see them as an usage or example for template.\"\n  label_link_title_help_message: \"You can customize the title of the related link. (Default: Related Link)\"\n  enter_value: Please enter a value.\n  label_select_field: Select a field\n  label_builtin_fields_help_message: Enter builtin fields or custom fields default values with JSON format. Please select fields and set values. Then click \"Apply\" and you can generate JSON format data.\n  label_builtin_fields_json: JSON for fields\n  label_enable_builtin_fields: Enable Builtin Field support\n  help_enable_builtin_fields: If this flag is enabled, a form will be displayed that allows you to set templates for built-in or custom fields. Please register the settings in JSON format.\n  warning_enable_builtin_fields: Please be careful to activate this flag. Now this feature is an experimental one. Since I have not provided enough UI and functions yet to support all the field types. It may not work depending on the browser. Use caution when applying in a production environment.\n  label_field_information: Field information\n  unavailable_fields_for_this_tracker: Unavailable field for this tarcker\n  global_note_templates: Global Template for note\n  link_to_index_edit_note_template: Note templates list / edit templates\n"
  },
  {
    "path": "config/locales/es.yml",
    "content": "# Spanish strings go here for Rails i18n\n# Translation by Andres Arias https://github.com/mrlocke\nes:\n  issue_templates: \"Plantillas de peticiones\"\n  issue_template: \"Plantilla de peticiones\"\n  issue_template_note: \"Nota\"\n  label_enabled: \"Habilitado\"\n  label_disabled: \"Deshabilitado\"\n  label_help_message: \"Acerca de plantillas\"\n  label_show_help_message: \"Mostrar el mensaje de ayuda cunado se crean/modifican las peticiones.\"\n  about_help_message: \"Cada proyecto puede personalizar el mensaje de ayuda para las plantillas.\"\n  close_help: \"Cerrar mensaje de ayuda.\"\n  about_template_help_message: \"Puede ver las instrucciones para las plantillas de peticiones en este proyecto.\"\n  label_enabled_help_message: \"Marque para activar (habilitar) esta plantilla. Si desea guardarla como borrador, desmarque esta casilla.\"\n  label_list_templates: \"Lista plantillas\"\n  label_new_templates: \"Añadir plantilla\"\n  issue_template_name: \"Nombre de la plantilla\"\n  issue_description: \"Descripción\"\n  issue_title: \"Asunto\"\n  label_applied_for_issue: \"Campos que rellenará la plantilla: \"\n  help_for_issue_title: \"Si el Asunto ya existe, será reemplazado por el de la plantilla.\"\n  help_for_this_field: \"Ayuda para este campo.\"\n  permission_manage_issue_templates: \"Administrar Plantillas\"\n  permission_edit_issue_templates: \"Editar Plantillas\"\n  permission_show_issue_templates: \"Ver Plantillas\"\n  project_module_issue_templates: \"plantillas de Peticiones\"\n  label_isdefault_help_message: \"Marque la casilla para seleccionar como plantilla por defecto para este tipo de peticiones.\"\n  defaulf_template_loaded: \"Cargada la plantilla por defecto. (Tipo de Petición: %{tracker})\"\n  text_no_tracker_enabled: \"Todavía no se han configurado Tipos de Peticiones para este proyecto.\\nPor favor, configure los primero, ya que las plantillas son asignadas a Tipos de Peticiones.\"\n  label_enabled_sharing: \"Compartir con el árbol de proyectos.\"\n  label_inherit_templates: \"Heredar plantillas\"\n  label_inherit_templates_help_message: \"Heredar plantillas desde el proyecto padre. (Sólo se comparten las plantillas marcadas como habilitadas.)\"\n  label_inherited_templates: \"Plantillas heredadas\"\n  no_issue_templates_for_this_project: \"No se han definido plantillas de peticiones para este proyecto.\"\n  link_to_index_edit_template: \"Ver/Editar plantillas de peticiones\"\n  erase_issue_subject_and_description: \"Borrar el Asunto y la Descripción.\"\n  unused_tracker_at_this_project: \"NOTA: Este Tipo de Petición no está definido para este proyecto. Por favor, cambie la configuración de la plantilla, si es necesario.\"\n  label_enabledshaing_help_message: \"Si está marcada, la plantilla podrá ser compartida con los sub-proyectos descendientes. (También debe ser activada la opción de heredar plantillas en los proyectos hijos.)\"\n  label_should_replaced: \"Reemplazar Asunto y Descripción\"\n  label_should_replaced_help_message: \"Si está habilitado, el Asunto y Descripción serán borrados y reemplazados con el texto de la plantilla. De lo contrario, serán añadidos. (Opción por defecto.)\"\n  global_issue_templates: \"Plantillas de Peticiones Globales\"\n  no_issue_templates_for_this_redmine: \"No hay plantillas globales definidas en este redmine.\"\n  only_admin_can_associate_global_template: \"Solamente el Administrador de Redmine puede asociar plantillas globales con esté proyecto.\"\n  text_no_tracker_enabled_for_global: \"No se han definido todavía Tipos de Peticiones. Por favor, configurelos primero, ya que las plantillas son asignadas a Tipos de Peticiones.\"\n"
  },
  {
    "path": "config/locales/fr.yml",
    "content": "# Les chaines en français sont définies ici pour Rails i18n\nfr:\n  issue_templates: \"Gabarits\"\n  issue_template: \"Gabarit des demandes\"\n  issue_template_note: \"Note\"\n  label_enabled: \"Activer\"\n  label_disabled: \"Désactiver\"\n  label_help_message: \"À propos des gabarits\"\n  label_show_help_message: \"Afficher le message d'aide lors de la création ou mise à jour d'une demande.\"\n  about_help_message: \"Le message d'aide peut-être personnalisé pour chaque projet.\"\n  close_help: \"Fermer le messsage d'aide\"\n  about_template_help_message: \"Aide au sujet des gabarits de ce projet.\"\n  label_enabled_help_message: \"Case à cocher pour activer ce gabarit. Si vous prévoyez sauvegarder ce gabarit en brouillon, décochez cette case.\"\n  label_list_templates: \"Liste des gabarits\"\n  label_new_templates: \"Ajouter un gabarit\"\n  issue_template_name: \"Nom du gabarit\"\n  issue_description: \"Description de la demande\"\n  issue_title: \"Titre de la demande\"\n  label_applied_for_issue: \"Champs spécifiques de la demande: \"\n  help_for_issue_title: \"Si le titre est défini, il sera appliqué aux demandes en choisissant un gabarit.\"\n  help_for_this_field: \"Aide pour ce champ.\"\n  permission_manage_issue_templates: \"Gérer les gabarits\"\n  permission_edit_issue_templates: \"Modifier le gabarit\"\n  permission_show_issue_templates: \"Afficher les gabarits\"  \n  project_module_issue_templates: \"Gabarit de demande\"\n  label_isdefault_help_message: \"Cochez cette case pour établir ce gabarit par défaut pour ce type de demande.\"\n  defaulf_template_loaded: \" Le gabarit par défaut est chargé dans la zone de description (Type de demande: %{tracker})\"\n  text_no_tracker_enabled: \" Aucun type de demande n'a été configuré encore.\\nDéfinissez au moins un type car les gabarits sont définis en fonction des types de demandes.\" \n  label_enabled_sharing: \"Activer le partage avec l'arborescence du projet.\"\n  label_inherit_templates: \"Hériter gabarit\"\n  label_inherit_templates_help_message: \"Hériter des gabarits du projet parent. (Seuls les gabarits parents dont l'option partage avec l'arborescence du projet est cochée sont listés.)\"\n  label_inherited_templates: \"Gabarit hérité\"\n  no_issue_templates_for_this_project: \"Aucun gabarit de demande n'est défini pour ce projet.\"\n  link_to_index_edit_template: \"Liste de gabarits de demandes / éditer gabarit\"\n  erase_issue_subject_and_description: \"Enlever le sujet et le texte descriptif\"\n  unused_tracker_at_this_project: \"NOTE: Ce tracker n'est pas défini pour ce projet. Veuillez redéfinir les réglages du gabarit si nécessaire.\"\n  label_enabledshaing_help_message: \"Si vrai, ce gabarit peut être partagé avec les sous-projets. (Vous devez également activer l'option Gabarit hérité dans le projet enfant.)\"\n  label_should_replaced: \"Remplacer le sujet et la description\"\n  label_should_replaced_help_message: \"Si vrai, les champs sujet et description sont effacés et remplacés par le texte du gabarit. (Par défaut à Faux et le texte en annexe.)\"\n  global_issue_templates: \"Modèle de gabarit de demande\"\n  no_issue_templates_for_this_redmine: \"Aucun modèle de gabarit de demande n'est défini pour ce redmine.\"\n  only_admin_can_associate_global_template: \"Seul l'administrateur peut associer un modèle de gabarit avec ce projet.\"\n  text_no_tracker_enabled_for_global: \"Aucun tracker n'est encore défini.\\nVeuillez les définir en premier car les gabarits sont assignés à des trackers.\"\n"
  },
  {
    "path": "config/locales/it.yml",
    "content": "# Italian strings go here for Rails i18n\nit:\n  issue_templates: Modelli segnalazioni\n  issue_template: Modello segnalazione\n  issue_template_note: Note\n  label_enabled: Attivato\n  label_disabled: Disattivato\n  label_help_message: Info sui modelli\n  label_show_help_message: Mostra messaggio d'aiuto durante la creazione o modifica delle segnalazioni.\n  about_help_message: Ogni progetto può avere messaggi d'aiuto personalizzati per i modelli.\n  close_help: Chiudi messaggio d'aiuto.\n  about_template_help_message: Puoi vedere le istruzioni per i modelli di segnalazione di questo progetto.\n  label_enabled_help_message: Abilita questo modello. Se vuoi salvarlo come bozza, disattiva questa opzione.\n  label_list_templates: \"Elenco modelli\"\n  label_new_templates: \"Nuovo modello\"\n  issue_template_name: \"Nome modello\"\n  issue_description: \"Testo della segnalazione\"\n  issue_title: \"Titolo segnalazione\"\n  label_applied_for_issue: \"Campi applicati per la segnalazione: \"\n  help_for_issue_title: \"Se il titolo della Segnalazione è definito, sarà applicato all'Oggetto della segnalazione quando si applica questo modello.\"\n  help_for_this_field: \"Aiuto per questo campo.\"\n  permission_manage_issue_templates: \"Gestisci Modelli\"\n  permission_edit_issue_templates: \"Modifica Modelli\"\n  permission_show_issue_templates: \"Mostra Modelli\"\n  project_module_issue_templates: \"Modelli Segnalazioni\"\n  label_isdefault_help_message: \"Usa questo come modello predefinito per le segnalazioni del tracker.\"\n  defaulf_template_loaded: \"Caricato modello predefinito nella descrizione. (Tracker: %{tracker})\"\n  text_no_tracker_enabled: \"Nessun tracker è stato configurato per questo progetto.\\nPer favore configurali prima perché i modelli segnalazione sono assegnati ai tracker. \"\n  label_enabled_sharing: \"Abilita condivisione con gerarchia progetto.\"\n  label_inherit_templates: \"Eredita modelli segnalazioni\"\n  label_inherit_templates_help_message: \"Eredita modelli da progetto padre. (Only parent's templates are listed which marked as enabled sharing with project tree.)\"\n  label_inherited_templates: \"Modelli ereditati\"\n  no_issue_templates_for_this_project: \"Nessun modello di segnalazione è definito per questo progetto.\"\n  link_to_index_edit_template: \"Elenco modelli segnalazione / modifica modelli\"\n  erase_issue_subject_and_description: \"Pulisci oggetto e descrizione.\"\n  unused_tracker_at_this_project: \"NOTA: Questo tracker non è abilitato per questo progetto. Per favore modifica le impostazioni del modello se necessario.\"\n  label_enabledshaing_help_message: \"Se abilitato, questo modello può essere condiviso con i sottoprogetti. (Devi anche abilitare nel sottoprogetto l'opzione Eredita modelli segnalazioni.)\"\n  label_should_replaced: \"Sostituisci oggetto e descrizione\"\n  label_should_replaced_help_message: \"Se abilitato, l'oggetto e la descrizione esistenti saranno sostituiti con il testo del modello.（Normalmente disattivato, i testi saranno accodati.)\"\n  global_issue_templates: \"Modelli Segnalazioni Globali\"\n  no_issue_templates_for_this_redmine: \"Nessun modello globale di segnalazione è definito per questo sito Redmine.\"\n  only_admin_can_associate_global_template: \"Solo un amministratore di Redmine può associare modelli globali a questo progetto.\"\n  text_no_tracker_enabled_for_global: \"Nessun tracker definito\\nÈ necessario configurarli prima perché i Modelli segnalazione sono assegnati ai tracker.\"\n  display_and_filter_issue_templates_in_dialog: \"Filtra modelli\"\n  label_filter_template: \"Filtra modelli\"\n"
  },
  {
    "path": "config/locales/ja.yml",
    "content": "# Japanese translation\nja:\n  issue_templates: チケットテンプレート\n  issue_template: チケットテンプレート\n  issue_template_note: メモ\n  label_enabled: \"有効\"\n  label_disabled: \"無効\"\n  label_help_message: \"テンプレートについて\"\n  label_show_help_message: \"ヘルプメッセージを有効にする\"\n  about_help_message: \"プロジェクト毎にテンプレートに関するヘルプを設定できます。\"\n  close_help: \"ヘルプメッセージを閉じます。\"\n  about_template_help_message: \"プロジェクト毎のテンプレートに関するヘルプを表示します。\"\n  label_enabled_help_message: \"有効にチェックを入れると、選択できるようになります。ドラフト状態の場合は、チェックを外して下さい。\"\n  label_list_templates: \"一覧\"\n  label_new_templates: \"新規作成\"\n  issue_template_name: \"テンプレート名\"\n  issue_description: \"チケット本文\"\n  issue_title: \"チケットタイトル\"\n  label_applied_for_issue: \"チケットへの適用項目: \"\n  help_for_issue_title: \"チケットタイトルを設定すると、テンプレート選択時に、タイトルもテンプレート化されたものをセットできます。\"\n  help_for_this_field: \"この項目のヘルプ\"\n  permission_manage_issue_templates: \"テンプレートの管理\"\n  permission_edit_issue_templates: \"テンプレートの編集\"\n  permission_show_issue_templates: \"テンプレートの表示\"\n  project_module_issue_templates: \"チケットテンプレート\"\n  label_isdefault_help_message: \"デフォルト値にチェックすると、チケットの新規登録時に、該当するトラッカーのテンプレートとして読み込まれます。\"\n  defaulf_template_loaded: \"デフォルトテンプレートが「詳細」テキストエリアにロードされました。(トラッカー: %{tracker})\"\n  text_no_tracker_enabled: \"テンプレートはトラッカー毎に設定します。\\nプロジェクトが利用するトラッカーの設定が必要です。\"\n  label_enabled_sharing: \"プロジェクトツリーでの共有を許可\"\n  label_inherit_templates: \"親プロジェクトのテンプレートを継承\"\n  label_inherit_templates_help_message: \"親プロジェクトのテンプレートを継承します。ただし、親プロジェクトのテンプレートで、プロジェクトツリーでの利用を許可しているものに限られます。\"\n  label_inherited_templates: \"継承されたテンプレート\"\n  no_issue_templates_for_this_project: \"このプロジェクト用のテンプレートは未だ登録されていません。\"\n  link_to_index_edit_template: \"テンプレート一覧 / 編集\"\n  erase_issue_subject_and_description: \"タイトルと詳細をクリア\"\n  unused_tracker_at_this_project: \"このプロジェクトでは利用されていないトラッカーです。必要に応じて、トラッカーとテンプレートの関連付けを修正して下さい。\"\n  label_enabledshaing_help_message: \"オプションをチェックすると、子プロジェクトでの利用を許可します。（子プロジェクト側での『テンプレートの継承』を設定した場合）\"\n  label_should_replaced: \"テンプレート読み込みの際に本文とタイトルを上書き\"\n  label_should_replaced_help_message: \"オプションをチェックすると、テンプレートを適用する際に、入力済みの本文とタイトルを上書きします。（デフォルトはOFFです）\"\n  global_issue_templates: \"グローバル チケットテンプレート\"\n  no_issue_templates_for_this_redmine: \"このRedmineにはグローバルチケットテンプレートは定義されていません。\"\n  only_admin_can_associate_global_template: \"このプロジェクトでグローバルチケットテンプレートを利用するには、Redmine管理者権限が必要です。\"\n  text_no_tracker_enabled_for_global: \"テンプレートはトラッカー毎に設定します。\\nトラッカーの設定をお願いします。\"\n  display_and_filter_issue_templates_in_dialog: \"テンプレートの内容を確認\"\n  label_filter_template: \"テンプレートの絞り込み\"\n  label_msg_confirm_to_replace: \"説明と題名を上書きしてもよろしいですか？\"\n  label_apply_global_template_to_all_projects: \"グローバルチケットテンプレートを全てのプロジェクトに適用\"\n  note_apply_global_template_to_all_projects_setting_enabled: \"プラグイン設定によって、グローバルチケットテンプレートは全てのプロジェクトに適用されます\"\n  project_list_associated_this_template: \"このテンプレートが利用可能なプロジェクト (全 %{all}プロジェクト中:  %{applied}プロジェクトが有効) \"\n  note_project_local_template_override_global_template: \"プロジェクト固有のテンプレートが設定されている場合は、プロジェクト固有のテンプレートが優先されます。また、グローバルテンプレートはチケットの新規作成画面では非表示になります。\"\n  help_project_local_template_override_global_template: \"このオプションが設定されている場合、グローバルチケットテンプレートは全てのプロジェクトに適用されます。\n  プロジェクト固有のテンプレートが設定されている場合は、プロジェクト固有のテンプレートが優先され、グローバルテンプレートはチケットの新規作成画面では非表示になります。\"\n  warning_project_local_template_override_global_template: \"このオプションを設定すると、全てのプロジェクトにグローバルテンプレートが適用されます。取り扱いに注意したい内容を含むグローバルテンプレートを登録する場合は、十分注意してください。\"\n  revert_before_applying_template: \"テンプレート適用前に戻す\"\n  template_remove_confirm: \"このテンプレートを削除してよろしいですか？ %{count}個のサブプロジェクトがこのテンプレートを利用しています。\"\n  label_number_of_subprojects_use_this_template: \"%{count}個のサブプロジェクトがこのテンプレートを利用しています \"\n  enabled_template_cannot_destroy: \"有効になっているテンプレートは削除できません。他に利用しているサブプロジェクトの有無を確認して、無効化してから削除を行なってください\"\n  orphaned_templates: \"トラッカーから孤立したテンプレート\"\n  orphaned_template: \"トラッカーから孤立したテンプレート\"\n  label_template_applied: \"テンプレートが適用されました。（元に戻す場合：「テンプレート適用前に戻す」をクリック）\"\n  label_hide_confirm_dialog_in_the_future: \"次回からは、この上書きの確認メッセージを表示しない\"\n  label_template_for_note: \"コメント用テンプレート\"\n  label_use_template_when_edit: \"チケットの編集時にもテンプレートを利用する\"\n  note_template: \"コメント用テンプレート\"\n  no_note_templates_for_this_project: \"このプロジェクトのコメント用テンプレートは未だ登録されていません。\"\n  label_memo_help_message: \"このテンプレートは、どのような場合に利用すればいいか説明を入力してください。\"\n  note_template_name: \"コメント用テンプレート名\"\n  note_description: \"コメント本文\"\n  field_template_visibility: 表示できるユーザ\n  note_templates:\n    visibility:\n      mine: 自分のみ\n      roles: 次のロールのみ\n      open: すべてのユーザー\n  please_select_at_least_one_role: 1つ以上のロールを指定してください。\n  issue_templates_settings: チケットテンプレート設定\n  issue_templates_optional_settings: テンプレートオプション設定\n  issue_template_related_link: 関連リンク\n  issue_template_link_title: 関連リンクのタイトル\n  label_related_link_help_message: \"テンプレートの利用例や、説明のページがあれば、関連リンクを設定できます。\"\n  label_link_title_help_message: \"関連リンクのタイトルは任意で設定できます（デフォルト: 関連リンク）\"\n  enter_value: 値を入力してください\n  label_select_field: フィールドの選択\n  label_builtin_fields_help_message: フィールドの設定はJSONフォーマットで登録します。フィールドを指定し、値を設定してください。「適用」を押すとJSONフォーマットのデータが作成されます。\n  label_builtin_fields_json: フィールド設定用JSON\n  label_enable_builtin_fields: 標準/カスタムフィールドの利用を可能にする\n  help_enable_builtin_fields: 設定を有効にすると、標準/カスタムフィールドのテンプレートを設定するためのフォームが表示されます。設定は「フィールドのID ＆ 値」のJSON形式で登録してください。\n  warning_enable_builtin_fields: 設定の有効化には十分注意してください。この機能は実験的なものです。入力のUIや値の適用のための十分な機能が提供できていません。また、ブラウザの互換性は保証されていません。本番環境への適用には十分注意してください。\n  label_field_information: このフィールドの情報\n  unusable_fields_for_this_tracker: このトラッカーでは利用できません\n  global_note_templates: \"グローバル コメント用テンプレート\"\n  link_to_index_edit_note_template: \"コメント用テンプレート一覧 / 編集\"\n"
  },
  {
    "path": "config/locales/ko.yml",
    "content": "# Korean translation\r\nko:\r\n  issue_templates: 템플릿\r\n  issue_template: 일감 템플릿\r\n  issue_template_note: 메모\r\n  label_enabled: 활성화\r\n  label_disabled: 비활성화\r\n  label_help_message: 템플릿에 대하여\r\n  label_show_help_message: 일감을 생성/수정할 때 도움말을 표시합니다.\r\n  about_help_message: 프로젝트마다 템플릿에 대한 사용자 정의 도움말을 설정할 수 있습니다.\r\n  close_help: 도움말을 닫습니다.\r\n  about_template_help_message: 이 프로젝트에서 일감 템플릿에 대한 지침을 볼 수 있습니다.\r\n  label_enabled_help_message: 이 템플릿을 활성화하기 위한 체크 상자. 아직 이 템플릿을 완성하지 않았다면 이 상자를 체크하지 마세요.\r\n  label_list_templates: \"템플릿 목록\"\r\n  label_new_templates: \"템플릿 추가\"\r\n  issue_template_name: \"템플릿 이름\"\r\n  issue_description: \"일감 본문\"\r\n  issue_title: \"일감 제목\"\r\n  label_applied_for_issue: \"일감에 적용될 항목들: \"\r\n  help_for_issue_title: \"일감 제목이 정의되면 이 템플릿을 선택할 때 자동으로 일감 제목에 적용될 것입니다.\"\r\n  help_for_this_field: \"이 항목에 대한 도움말\"\r\n  permission_manage_issue_templates: \"템플릿 관리\"\r\n  permission_edit_issue_templates: \"템플릿 편집\"\r\n  permission_show_issue_templates: \"템플릿 표시\"\r\n  project_module_issue_templates: \"일감 템플릿\"\r\n  label_isdefault_help_message: \"대상 유형에 대해 기본 템플릿으로 사용합니다.\"\r\n  defaulf_template_loaded: \"본문 영역에 기본 템플릿을 불러왔습니다. (유형: %{tracker})\"\r\n  text_no_tracker_enabled: \"이 프로젝트에서 사용되는 유형이 없습니다.\\n템플릿은 유형에 할당되기 때문에 이를 먼저 설정해주세요.\"\r\n  label_enabled_sharing: \"프로젝트 트리에서 공유할 수 있습니다.\"\r\n  label_inherit_templates: \"템플릿 상속\"\r\n  label_inherit_templates_help_message: \"상위 프로젝트로부터 템플릿들을 상속합니다. (상위 프로젝트에서 프로젝트 트리에서 상속하도록 설정한 템플릿들만 나열됩니다.)\"\r\n  label_inherited_templates: \"상속된 템플릿\"\r\n  no_issue_templates_for_this_project: \"이 프로젝트를 위해 정의된 일감 템플릿이 없습니다.\"\r\n  link_to_index_edit_template: \"일감 템플릿 나열/편집\"\r\n  erase_issue_subject_and_description: \"제목과 설명을 비움\"\r\n  unused_tracker_at_this_project: \"참고: 이 프로젝트에서 사용하는 유형이 아닙니다. 필요한 경우 템플릿 설정을 다시 해주세요.\"\r\n  label_enabledshaing_help_message: \"이 템플릿은 하위 프로젝트와 공유될 수 있게 됩니다. (하위 프로젝트에서 템플릿 상속을 활성화해야 합니다.)\"\r\n  label_should_replaced: \"제목과 설명을 대체\"\r\n  label_should_replaced_help_message: \"제목과 본문이 템플릿의 내용으로 대체됩니다. (기본값은 사용 안함)\"\r\n  global_issue_templates: \"전역 일감 템플릿\"\r\n  no_issue_templates_for_this_redmine: \"이 레드마인을 위해 정의된 전역 일감 템플릿이 없습니다.\"\r\n  only_admin_can_associate_global_template: \"레드마인 관리자만 전역 템플릿과 이 프로젝트를 연결할 수 있습니다.\"\r\n  text_no_tracker_enabled_for_global: \"유형이 정의되지 않았습니다.\\n템플릿은 유형에 할당되기 때문에 이를 먼저 설정해주세요.\"\r\n  display_and_filter_issue_templates_in_dialog: \"템플릿 내용 미리보기\"\r\n  label_filter_template: \"Filter templates\"\r\n  label_msg_confirm_to_replace: \"제목과 설명을 대체하시겠습니까?\"\r\n  label_apply_global_template_to_all_projects: \"전역 일감 텔플릿을 모든 프로젝트에 적용.\"\r\n  note_apply_global_template_to_all_projects_setting_enabled: \"이 전역 일감 템플릿은 플러그인 설정에 따라 모든 프로젝트에 적용됩니다.\"\r\n  project_list_associated_this_template: \"프로젝트 목록: (적용됨: %{all}개 중 %{applied}개)\"\r\n  note_project_local_template_override_global_template: \"프로젝트 한정 템플릿이 있다면 전역 템플릿보다 우선되고, 일감 생성 화면에서 어떤 전역 템플릿도 보여지지 않게 됩니다.\"\r\n  help_project_local_template_override_global_template: \"이 옵션이 활성화되면 모든 전역 티켓 템플릿이 모든 프로젝트에 적용됩니다. 유형 별로 프로젝트 한정 템플릿이 있다면 전역 템플릿보다 우선되고, 일감 생성 화면에서 전역 템플릿이 보여지지 않게 됩니다.\"\r\n  warning_project_local_template_override_global_template: \"전역 일감 템플릿을 등록할 때에는 기밀 내용이 포함되어 있는지 주의가 필요합니다. 이 옵션이 활성화되면 모든 전역 템플릿이 모든 프로젝트에 적용됩니다.\"\r\n  revert_before_applying_template: \"되돌리기\"\r\n  template_remove_confirm: \"이 템플릿을 삭제하시겠습니까? %{count}개의 하위 프로젝트들이 이 템플릿을 사용하고 있습니다.\"\r\n  label_number_of_subprojects_use_this_template: \"%{count}개의 하위 프로젝트들이 이 템플릿을 사용하고 있습니다.\"\r\n  enabled_template_cannot_destroy: \"비활성화된 템플릿만 삭제될 수 있습니다. 다른 하위 프로젝트들이 이 템플릿을 사용하는지 확인하고 삭제하기 전에 비활성화하세요.\"\r\n  orphaned_templates: \"유형에 독립적인 템플릿\"\r\n  orphaned_template: \"유형에 독립적인 템플릿\"\r\n  label_template_applied: \"일감 템플릿이 적용되었습니다. '되돌리기'를 통해 적용하기 전으로 되돌릴 수 있습니다.\"\r\n  label_hide_confirm_dialog_in_the_future: \"앞으로 이 확인은 나타나지 않으며, 바로 덮어쓰여집니다.\"\r\n  label_template_for_note: \"댓글 템플릿\"\r\n  label_use_template_when_edit: \"일감을 편집할 때 템플릿을 사용\"\r\n  note_template: \"댓글 템플릿\"\r\n  no_note_templates_for_this_project: \"이 프로젝트에는 댓글 템플릿이 없습니다.\"\r\n  label_memo_help_message: \"이 템플릿을 적용할 때 설명을 하는 노트를 작성해주세요.\"\r\n  note_template_name: \"댓글 템플릿 이름\"\r\n  note_description: \"댓글 본문\"\r\n  field_template_visibility: 템플릿 공개 범위\r\n  note_templates:\r\n    visibility:\r\n      mine: 나에게만\r\n      roles: 특정 역할에게만\r\n      open: 모든 사용자에게\r\n  please_select_at_least_one_role: \"하나 이상의 역할을 선택해주세요.\"\r\n  issue_templates_settings: 일감 템플릿 설정\r\n  issue_templates_optional_settings: 템플릿 옵션 설정\r\n  issue_template_related_link: 참고 링크\r\n  issue_template_link_title: 참고 링크 제목\r\n  label_related_link_help_message: \"일감 템플릿을 사용하는 예시 페이지나 일감들이 있다면 링크를 지정함으로써 템플릿에 대한 사용법이나 예제를 확인할 수 있습니다.\"\r\n  label_link_title_help_message: \"참고 링크의 제목을 변경할 수 있습니다. (기본값: 참고 링크)\"\r\n  enter_value: 값을 입력해주세요.\r\n  label_select_field: 필드 선택\r\n  label_builtin_fields_help_message: 내장 필드 혹은 사용자 정의 필드의 기본값을 JSON 포맷으로 입력하세요. 필드들을 선택하고 값을 입력한 뒤에 \"적용\" 버튼을 누리면 JSON 포맷의 데이터를 만들 수 있습니다.\r\n  label_builtin_fields_json: 필드들에 대한 JSON 값\r\n  label_enable_builtin_fields: 내장된 필드 활성화\r\n  help_enable_builtin_fields: 이 항목이 활성화되면 내장 혹은 사용자 정의된 필드들에 대해 템플릿을 설정할 수 있는 폼이 보여질 것입니다. JSON 포맷으로 이 설정을 등록해주세요.\r\n  warning_enable_builtin_fields: 이 항목을 활성화하는 것을 주의해주세요. 아직 모든 필드 유형을 지원하기에 충분한 UI와 기능을 제공하지 않기 때문에 실험 중인 기능입니다. 사용 중인 웹 브라우저에 따라 동작하지 않을 수도 있습니다. 실 환경에 적용할 때에는 주의하세요.\r\n  label_field_information: 필드 정보\r\n  unavailable_fields_for_this_tracker: 이 유형에서 사용할 수 없는 필드\r\n"
  },
  {
    "path": "config/locales/pl.yml",
    "content": "# Polish strings go here for Rails i18n\npl:\n  issue_templates: Szablony zagadnień\n  issue_template: Szablon zagadnienia\n  issue_template_note: info\n  label_enabled: Włącz\n  label_disabled: Wyłącz\n  label_help_message: O szablonach\n  label_show_help_message: Pokazuj pomoc przy tworzeniu / edycji zagadnień. \n  about_help_message: Każdy projekt może mieć swoje wiadomości pomocy dla szablonów.\n  close_help: Zamknij pomoc.\n  about_template_help_message: Możesz zobaczyć instrukcję dla szablonów zagadnień w tym projekcie.\n  label_enabled_help_message: Powoduje możliwość korzystania z tego szablonu. Jeśli chcesz, aby szablon był zapisany jako szkic, odznacz to pole.\n  label_list_templates: \"Lista szablonów\"\n  label_new_templates: \"Dodaj szablon\"\n  issue_template_name: \"Nazwa szablonu\"\n  issue_description: \"Treść zagadnienia\"\n  issue_title: \"Tytuł zagadnienia\"\n  label_applied_for_issue: \"Pola wpisywane do zagadnienia: \"\n  help_for_issue_title: \"Jeśli wpisany jest tytuł zagadnienia, to także będzie wpisywane przy wyborze szablonu.\"\n  help_for_this_field: \"Pomoc dla tego pola.\"\n  permission_manage_issue_templates: \"Zarządzaj Szablonami\"\n  permission_edit_issue_templates: \"Edycja Szablonów\"\n  permission_show_issue_templates: \"Pokaż Szablony\"  \n  project_module_issue_templates: \"Szablony Zagadnień\"\n  label_isdefault_help_message: \"Zaznacz aby móc używać tego szablonu jako domyślnego dla danego typu zagadnień.\"\n  defaulf_template_loaded: \"Wczytano domyślny szablon do opisu zagadnienia. (Typ: %{tracker})\"\n  text_no_tracker_enabled: \"Nie skonfigurowano typów zagadnień dla tego projektu.\\nProszę je najpierw ustawić, ponieważ szablony są przypisane do typów zagadnień. \"\n  label_enabled_sharing: \"Włączone współdzielenie z drzewem podprojektów.\"\n  label_inherit_templates: \"Dziedzicz szablony\"\n  label_inherit_templates_help_message: \"Dziedzicz szablony z projektu nadrzędnego. (Tylko szablony projektu nadrzędnego, które mają włączoną funkcję współdzielenia z drzewem podprojektów są pokazane.)\"\n  label_inherited_templates: \"Dziedziczone szablony\"\n  no_issue_templates_for_this_project: \"Brak zdefiniowanych szablonów zagadnień dla tego projektu.\"\n  link_to_index_edit_template: \"Lista szablonów zagadnień / edycja szablonów\"\n  erase_issue_subject_and_description: \"Czyść tytuł i tekst w opisie zagadnienia.\"\n  unused_tracker_at_this_project: \"INFO: Ten typ zagadnienia nie jest włączony dla tego projektu. Jeśli to konieczne proszę ponownie zdefiniować ustawienia projektu.\"\n  label_enabledshaing_help_message: \"Jeśli włączone, możliwe jest współdzielenie szablonu z podprojektami. (Musisz także włączyć szablony dziedziczone w podprojekcie.)\"\n  label_should_replaced: \"Nadpisuj tytuł i opis zagadnienia\"\n  label_should_replaced_help_message: \"Jeśli włączone, wpisany wcześniej tytuł i opis zagadnienia będą czyszczone i zastępowane tekstem z szablonu. (Domyślnie wyłączone, tekst jest dopisywany.)\"\n  global_issue_templates: \"Globalne Szablony Zagadnień\"\n  no_issue_templates_for_this_redmine: \"Brak zdefiniowanych globalnych szablonów zagadnień.\"\n  only_admin_can_associate_global_template: \"Tylko administrator może przypisywać globalne szablony do projektów.\"\n  text_no_tracker_enabled_for_global: \"Brak zdefiniowanych typów zagadnień.\\nProszę je najpierw ustawić, ponieważ szablony są przypisane do typów zagadnień.\"\n"
  },
  {
    "path": "config/locales/pt-BR.yml",
    "content": "# Brazilian strings go here for Rails i18n\npt-BR:\n  issue_templates: Modelos de tarefas\n  issue_template: Modelo de tarefa\n  issue_template_note: notas\n  label_enabled: Habilitado\n  label_disabled: Desabilitado\n  label_help_message: Sobre modelos\n  label_show_help_message: Visualizar mensagem de ajuda ao Criar/Atualizar tarefa. \n  about_help_message: Cada projeto pode customizar mensagem de ajuda para os modelos.\n  close_help: Fechar mensagem de ajuda.\n  about_template_help_message: Poder visualizar instruções sobre modelos de tarefas neste projeto.\n  label_enabled_help_message: Opção para ativar este modelo. Se deseja salvar este modelo como rascunho, desative esta opção.\n  label_list_templates: \"Lista de modelos\"\n  label_new_templates: \"Incluir modelo\"\n  issue_template_name: \"Nome do modelo\"\n  issue_description: \"Corpo da tarefa\"\n  issue_title: \"Título da tarefa\"\n  label_applied_for_issue: \"Campos aplicados para tarefa: \"\n  help_for_issue_title: \"Se definido o título da tarefa, este será aplicado à tarefa ao selecionar o modelo.\"\n  help_for_this_field: \"Ajuda sobre este campo.\"\n  permission_manage_issue_templates: \"Gerenciar Modelos\"\n  permission_edit_issue_templates: \"Editar Modelos\"\n  permission_show_issue_templates: \"Visualizar Modelos\"  \n  project_module_issue_templates: \"Modelos de Tarefas\"\n  label_isdefault_help_message: \"Se esta opção estiver ativa este será o modelo padrão para este tipo de tarefa.\"\n  defaulf_template_loaded: \"Modelo padrão carregado na área da descrição. (Tipo: %{tracker})\"\n  text_no_tracker_enabled: \"Não há tipos configurados para este projeto.\\nPor favor configure os tipos pois os modelos são associados a eles. \"\n  label_enabled_sharing: \"Habilitar compartilhamento com a árvore de projetos.\"\n  label_inherit_templates: \"Herdar modelos\"\n  label_inherit_templates_help_message: \"Herda modelos do projeto pai. (Apenas os modelos do projeto pai listados são os marcados com compartilhamento habilitado com a árvore de projetos.)\"\n  label_inherited_templates: \"Modelos herdados\"\n  no_issue_templates_for_this_project: \"Não há modelos de tarefa definidos para este projeto.\"\n  link_to_index_edit_template: \"Lista de modelos de tarefa / editar modelos\"\n  erase_issue_subject_and_description: \"Limpar assunto e descrição.\"\n  unused_tracker_at_this_project: \"NOTA: Este tipo não está habilitado para uso neste projeto. Por favor redefina as configurações do modelo se necessário.\"\n  label_enabledshaing_help_message: \"Se habilitado, este modelo pode ser compartilhado com projetos descendentes. (Você também deve ativar a opção de herdar modelos no projeto filho.)\"\n  label_should_replaced: \"Substituir assunto e descrição\"\n  label_should_replaced_help_message: \"Se habilitado assunto e descrição são excluídos e substituídos pelos textos do modelo. (Por padrão os textos são adicionados.)\"\n  global_issue_templates: \"Modelos de Tarefa Globais\"\n  no_issue_templates_for_this_redmine: \"Não há modelos de tarefa globais definidos neste redmine.\"\n  only_admin_can_associate_global_template: \"Somente administradores podem associar modelos globais a este projeto.\"\n  text_no_tracker_enabled_for_global: \"Nenhum tipo foi definido ainda.\\nPor favor defina os tipos, pois os modelos são atribuídos a estes.\"\n  display_and_filter_issue_templates_in_dialog: \"Visualizar conteúdo do template\"\n  label_filter_template: \"Filtrar modelos\"\n  label_msg_confirm_to_replace: \"Você quer substituir o assunto e a descrição?\"\n  label_apply_global_template_to_all_projects: \"Aplica modelos de problemas globais a todos os projetos.\"\n  note_apply_global_template_to_all_projects_setting_enabled: \"Este modelo de problema global é aplicado a todos os projetos por configuração de plug-in.\"\n  project_list_associated_this_template: \"Lista de projetos:  (aplicado: %{applied} of %{all})\"\n  note_project_local_template_override_global_template: \"Se existe um modelo local de projeto, substitua modelos globais e quaisquer modelos globais não são exibidos na tela criar tarefa.\"\n  help_project_local_template_override_global_template: \"Se esta opção for ativada, todos os modelos de passagens globais serão aplicados a todos os projetos. Se um modelos específico do projeto por tipo tarefa estiver definido, ele se substituirá e o template global está oculto na tela de criação de nova tarefa.\"\n  warning_project_local_template_override_global_template: \"Tenha cuidado ao registrar o template de tarefa global, que contém conteúdo confidencial para o qual deseja prestar atenção. Caso esta opção seja ativada, todos os modelos globais serão aplicados a todos os projetos.\"\n  revert_before_applying_template: \"Reverter\"\n  template_remove_confirm: \"Tem certeza de remover esse template？ %{count} subprojetos usam este template.\"\n  label_number_of_subprojects_use_this_template: \"%{count} subprojetos usam este template.\"\n  enabled_template_cannot_destroy: \"Apenas o template desativado pode ser destruído. Verifique se outros subprojetos usam esse template ou não e desativá-lo antes de excluir.\"\n  orphaned_templates: \"Modelos órfãos do tipo tarefa\"\n  orphaned_template: \"Modelos órfãos do tipo tarefa\"\n"
  },
  {
    "path": "config/locales/pt.yml",
    "content": "# Brazilian strings go here for Rails i18n\npt:\n  issue_templates: Modelos de tarefas\n  issue_template: Modelo de tarefas\n  issue_template_note: notas\n  label_enabled: Habilitado\n  label_disabled: Desabilitado\n  label_help_message: Sobre modelos\n  label_show_help_message: Visualizar mensagem de ajuda ao Criar/Atualizar tarefa. \n  about_help_message: Cada projeto pode customizar mensagem de ajuda para os modelos.\n  close_help: Fechar mensagem de ajuda.\n  about_template_help_message: Poder visualizar instruções sobre modelos de tarefas neste projeto.\n  label_enabled_help_message: Opção para ativar este modelo. Se deseja salvar este modelo como rascunho, desative esta opção.\n  label_list_templates: \"Lista de modelos\"\n  label_new_templates: \"Incluir modelo\"\n  issue_template_name: \"Nome do modelo\"\n  issue_description: \"Corpo da tarefa\"\n  issue_title: \"Título da tarefa\"\n  label_applied_for_issue: \"Campos aplicados para tarefa: \"\n  help_for_issue_title: \"Se definido o título da tarefa, este será aplicado à tarefa ao selecionar o modelo.\"\n  help_for_this_field: \"Ajuda sobre este campo.\"\n  permission_manage_issue_templates: \"Gerenciar Modelos\"\n  permission_edit_issue_templates: \"Editar Modelos\"\n  permission_show_issue_templates: \"Visualizar Modelos\"  \n  project_module_issue_templates: \"Modelos de Tarefas\"\n  label_isdefault_help_message: \"Se esta opção estiver ativa este será o modelo padrão para este tipo de tarefa.\"\n  defaulf_template_loaded: \"Modelo padrão carregado na área da descrição. (Tipo: %{tracker})\"\n  text_no_tracker_enabled: \"Não há tipos configurados para este projeto.\\nPor favor configure os tipos pois os modelos são associados a eles. \"\n  label_enabled_sharing: \"Habilitar compartilhamento com a árvore de projetos.\"\n  label_inherit_templates: \"Herdar modelos\"\n  label_inherit_templates_help_message: \"Herda modelos do projeto pai. (Apenas os modelos do projeto pai listados são os marcados com compartilhamento habilitado com a árvore de projetos.)\"\n  label_inherited_templates: \"Modelos herdados\"\n  no_issue_templates_for_this_project: \"Não há modelos de tarefa definidos para este projeto.\"\n  link_to_index_edit_template: \"Lista de modelos de tarefa / editar modelos\"\n  erase_issue_subject_and_description: \"Limpar assunto e descrição.\"\n  unused_tracker_at_this_project: \"NOTA: Este tipo não está habilitado para uso neste projeto. Por favor redefina as configurações do modelo se necessário.\"\n  label_enabledshaing_help_message: \"Se habilitado, este modelo pode ser compartilhado com projetos descendentes. (Você também deve ativar a opção de herdar modelos no projeto filho.)\"\n  label_should_replaced: \"Substituir assunto e descrição\"\n  label_should_replaced_help_message: \"Se habilitado assunto e descrição são excluídos e substituídos pelos textos do modelo. (Por padrão os textos são adicionados.)\"\n  global_issue_templates: \"Modelos de Tarefa Globais\"\n  no_issue_templates_for_this_redmine: \"Não há modelos de tarefa globais definidos neste redmine.\"\n  only_admin_can_associate_global_template: \"Somente administradores podem associar modelos globais a este projeto.\"\n  text_no_tracker_enabled_for_global: \"Nenhum tipo foi definido ainda.\\nPor favor defina os tipos, pois os modelos são atribuídos a estes.\"\n"
  },
  {
    "path": "config/locales/ru.yml",
    "content": "# Russian strings go here for Rails i18n\nru:\n  issue_templates: Шаблоны\n  issue_template: Шаблон задачи\n  issue_template_note: Заметка\n  label_enabled: Вкл.\n  label_disabled: Выкл.\n  label_help_message: Подсказка по шаблонам\n  label_show_help_message: Показывать подсказку по шаблонам при создаии/редактировании задачи.\n  about_help_message: У каждого проекта может быть своя подсказа по шаблонам\n  close_help: Закрыть подсказку\n  about_template_help_message: Вы можете посмотреть подсказку по работе с шаблонами для данного проекта\n  label_enabled_help_message: Если параметр установлен, шаблон доступен для использования в задаче. Отключите, если хотите сохранить шаблон как черновик.\n  label_list_templates: \"Список шаблонов\"\n  label_new_templates: \"Добавить шаблон\"\n  issue_template_name: \"Название шаблона\"\n  issue_description: \"Шаблон текста задачи\"\n  issue_title: \"Заголовок задачи\"\n  label_applied_for_issue: \"Заполняемые поля задачи: \"\n  help_for_issue_title: \"Если установлено значение для 'Заголовок задачи', то оно будет автоматически вставляться в Тему задачи при выборе шаблона.\"\n  help_for_this_field: \"Справка по данному полю\"\n  permission_manage_issue_templates: \"Управление шаблонами\"\n  permission_edit_issue_templates: \"Редактировать шаблоны\"\n  permission_show_issue_templates: \"Показывать шаблоны\"\n  project_module_issue_templates: \"Использовать шаблоны\"\n  label_isdefault_help_message: \"Если параметр установлен, шаблон будет подставляться автоматически при создании новой задачи для соответствующего трекера.\"\n  defaulf_template_loaded: \"В поле описания задачи подставлен шаблон по умолчанию (Трекер: %{tracker})\"\n  text_no_tracker_enabled: \"Для проекта не настроен ни один трекер.\\nПожалуйста, настройте трекеры, так как шаблоны должны быть ассоциированы с трекерами.\"\n  label_enabled_sharing: \"Разрешить использование шаблона в дочерних проектах.\"\n  label_inherit_templates: \"Унаследовать шаблоны родительского проекта\"\n  label_inherit_templates_help_message: \"Наследует шаблоны, настроенные для родительского проекта. Унаследованы будут только те шаблоны, для которых это разрешено в параметрах шаблона (настройка Разрешить использование шаблона во всем дереве проектов).\"\n  label_inherited_templates: \"Унаследованные шаблоны\"\n  no_issue_templates_for_this_project: \"Для данного проекта не настроены шаблоны задач.\"\n  link_to_index_edit_template: \"Список шаблонов задач / редактирование шаблонов\"\n  erase_issue_subject_and_description: \"Очистить тему и описание задачи.\"\n  unused_tracker_at_this_project: \"ВНИМАНИЕ: Данный трекер не используется в текущем проекте. Пожалуйста перенастройте шаблон при необходимости.\"\n  label_enabledshaing_help_message: \"Если параметр установлен, данный шаблон может быть унаследован дочерними проектами. (Для работы данной функции необходимо включить наследование в настройках шаблонов дочернего проекта.)\"\n  label_should_replaced: \"Заменять тему и описание\"\n  label_should_replaced_help_message: \"Если параметр установлен, текст темы и описания будет очищен и заменен текстом из шаблона. （По умолчанию параметр отключен, и текст добавляется к существующему, а не заменяется.)\"\n  global_issue_templates: \"Глобальные шаблоны задач\"\n  no_issue_templates_for_this_redmine: \"Глобальные шаблоны задач, доступные для всех проектов Redmine, не настроены.\"\n  only_admin_can_associate_global_template: \"Подключить глобальные шаблоны задач к данному проекту может только администратор Redmine.\"\n  text_no_tracker_enabled_for_global: \"Не настроен ни один трекер.\\nПожалуйста, настройте трекеры, так как шаблоны должны быть ассоциированы с трекерами.\"\n  display_and_filter_issue_templates_in_dialog: \"Подобрать шаблон\"\n  label_filter_template: \"Подобрать шаблон\"\n  label_apply_global_template_to_all_projects: \"Применить глобальный шаблон ко всем проектам\"\n  label_use_template_when_edit: \"Использовать шаблон при редактировании\"\n  note_template: \"Шаблон комментариев\"\n  orphaned_template: \"Потерянные шаблоны\"\n  project_list_associated_this_template: \"Проекты с этим шаблоном\"\n  help_project_local_template_override_global_template: \"Если эта опция активирована, то глобальные шаблоны будут назначены на все проекты, если проект имеет свой шаблон, то глобальный шаблон будет спрятан при создании новой задачи.\"\n  warning_project_local_template_override_global_template: \"Пожалуйста будте осторожны, т.к. глобальные шаблоны могут содержать конфиденциальную информацию и они назначаются на все проекты.\"\n  warning_enable_builtin_fields: \"Внимание эта функция экспериментальная, используйте на свой страх и риск.\"\n  help_enable_builtin_fields: \"При включении будет показана форма, позволяющая выставить шаблоны для встроенных или пользовтельских полей. Пожалуйста зарегистрируейте настройки в формате JSON.\"\n  no_note_templates_for_this_project: \"Для проекта еще не назначены шаблоны комментариев.\"\n"
  },
  {
    "path": "config/locales/sr-YU.yml",
    "content": "# English strings go here for Rails i18n\nsr:\n  issue_templates: Šabloni problema\n  issue_template: Šablon problema\n  issue_template_note: nota\n  label_enabled: Aktivno\n  label_disabled: Neaktivno\n  label_help_message: O šablonu\n  label_show_help_message: Prikaži poruku za pomoć prilikom kreiranja ili ažuriranja problema.\n  about_help_message: Za svaki projekat se može prilagoditi poruka za pomoć za upotrebu šablona.\n  close_help: Zatvori poruku za pomoć.\n  about_template_help_message: Možete videti instrukcije o korišćenju šablona na ovom projektu.\n  label_enabled_help_message: Aktivira šablon. Ukoliko i dalje razvijate ovaj šablon, ostavite ga deaktiviranim dok nije završen.\n  label_list_templates: \"Lista šablona\"\n  label_new_templates: \"Dodaj šablon\"\n  issue_template_name: \"Ime šablona\"\n  issue_description: \"Opis\"\n  issue_title: \"Predmet\"\n  label_applied_for_issue: \"Polja problema za koja se šablon odnosi\"\n  help_for_issue_title: \"Ukoliko je definisan predmet problema on će takođe biti primenjen prilikom selekcije šablona.\"\n  help_for_this_field: \"Pomoć za ovo polje\"\n  permission_manage_issue_templates: \"Upravljanje šablonima\"\n  permission_edit_issue_templates: \"Ažuriraj šablon\"\n  permission_show_issue_templates: \"Prikaži šablon\"\n  project_module_issue_templates: \"Šabloni problema\"\n  label_isdefault_help_message: \"Ukoliko je aktivirano, ovaj šablon će biti podrazumevani (default) za dato praćenje (tracker) problema.\"\n  defaulf_template_loaded: \"Učitan je podrazumevani šablon za ovo praćenje problema u polje za opis. (Praćenje: %{tracker})\"\n  text_no_tracker_enabled: \"Još uvek nisu konfigurisani pratioci (tracker) za ovaj projekat.\"\n  label_enabled_sharing: \"Omogući deljenje sa stablom projekta\"\n  label_enabledshaing_help_message: \"Aktiviraj da bi subprojekti nasledili šablone.\"\n  label_inherit_templates: \"Nasledi šablon\"\n  label_inherit_templates_help_message: \"Nasledi šablon od majke projekta\"\n  label_inherited_templates: \"Nasleđeni šabloni\"\n  no_issue_templates_for_this_project: \"Nema definisanih šablona za ovaj projekat.\"\n  link_to_index_edit_template: \"Lista šablona problema / ažuriraj šablone.\"\n  erase_issue_subject_and_description: \"Obriši naslov i opis\"\n  unused_tracker_at_this_project: \"NOTA: Ovo praćenje problema (tracker) se ne koristi u ovom projektu.\""
  },
  {
    "path": "config/locales/zh-TW.yml",
    "content": "# Tranditional Chinese strings go here for Rails i18n\nzh-TW:\n  issue_templates: \"問題樣板\"\n  issue_template: \"問題樣板\"\n  issue_template_note: \"註釋\"\n  label_enabled: \"啟用\"\n  label_disabled: \"停用\"\n  label_help_message: \"關於樣板\"\n  label_show_help_message: \"建立/修改問題時顯示提示訊息。\"\n  about_help_message: \"每個專案都可以為這個樣板定義提示訊息。\"\n  close_help: \"關閉提示訊息。\"\n  about_template_help_message: \"你可以看到當前問題的樣板幫助訊息。\"\n  label_enabled_help_message: \"該確認框用以啟用當前的樣板。若你只想把目前的樣板先當成草稿使用，請不要勾選。\"\n  label_list_templates: \"樣板列表\"\n  label_new_templates: \"新建樣板\"\n  issue_template_name: \"樣板名稱\"\n  issue_description: \"樣板内容\"\n  issue_title: \"問題標題\"\n  label_applied_for_issue: \"該問題所使用的欄位內容\"\n  help_for_issue_title: \"如果在這邊有設定值，則使用該樣板時回自動帶入。\" \n  help_for_this_field: \"本欄位說明。\"\n  permission_manage_issue_templates: \"管理樣板\"\n  permission_edit_issue_templates: \"編輯樣板\"\n  permission_show_issue_templates: \"顯示樣板\"  \n  project_module_issue_templates: \"問題樣板\"\n  label_isdefault_help_message: \"勾選此選項則該問題類型會使用此樣板當作預設值\"\n  defaulf_template_loaded: \"載入樣板資訊至概述欄位中（追蹤標籤： %{tracker}）\"\n  text_no_tracker_enabled: \"本專案的追蹤標簽中沒有任何一個設定了問題樣板。\\n 請在使用前先設定他們\"\n  label_enabled_sharing: \"在專案樹狀結構中分享\"\n  label_inherit_templates: \"繼承樣板\"\n  label_inherit_templates_help_message: \" 從父專案繼承問題樣板(父專案中只有那些有勾選分享的才會出現在此處)。\"\n  label_inherited_templates: \"繼承樣板\"\n  no_issue_templates_for_this_project: \"此專案沒有定義任何的問題樣板\"\n  link_to_index_edit_template: \"問題樣板列表/ 編輯樣板\"\n  erase_issue_subject_and_description: \"清除主旨以及概述。\"\n  unused_tracker_at_this_project: \"備註：這個追蹤標簽並沒有被指派給這個專案使用。必要的話請重新設定樣板\"\n  label_enabledshaing_help_message: \"如果設定值為 True，這個樣板就可以分享給子專案使用（你還是得在子專案中把繼承而來的問題樣板啟用）。\"\n  label_should_replaced: \"取代標題以及描述\"\n  label_should_replaced_help_message: \"如果設定值為 True，當前的標題以及描述會被清除，且被樣板的文字所取代(預設是 False, 把文字附加在後面)。\" \n  global_issue_templates: \"全域問題樣板\"\n  no_issue_templates_for_this_redmine: \"網站目前沒有全域的問題樣板！\"\n  only_admin_can_associate_global_template: \"只有 Redmine 管理員可以在這個專案中關聯全域樣板。\"\n  text_no_tracker_enabled_for_global: \"尚未定義追蹤標籤。\\n請先分配模板適用的追蹤標籤。\"\n  display_and_filter_issue_templates_in_dialog: \"預覽樣板內容\"\n  label_filter_template: \"篩選樣板\"\n  label_msg_confirm_to_replace: \"確定要取代主旨和說明嗎？\"\n  label_apply_global_template_to_all_projects: \"套用全域問題樣板到所有專案。\"\n  note_apply_global_template_to_all_projects_setting_enabled: \"基於外掛設定，這個全域問題樣板被套用到所有專案。\"\n  project_list_associated_this_template: \"專案列表：  （已套用 %{all} 個中的 %{applied} 個）\"\n  note_project_local_template_override_global_template: \"如果專案有自己的樣板，覆蓋全域樣板且新增問題時不顯示全域樣板選項。\"\n  help_project_local_template_override_global_template: \"當啟用這個選項時，所有的全域問題樣板會被套用到所有專案。如果特定專案有針對每個追蹤標籤設定樣板，它將會覆蓋全域樣板，且新增問題時不會顯示全域樣板。\"\n  warning_project_local_template_override_global_template: \"註冊包含機密內容的全域問題樣板時，請特別注意：一旦啟用了這個選項，所有的全域樣板會被套用到所有專案。\"\n  revert_before_applying_template: \"還原\"\n  template_remove_confirm: \"確定要刪除這個樣板嗎？目前有 %{count} 個子問題使用這個樣板。\"\n  label_number_of_subprojects_use_this_template: \"%{count} 個子專案使用這個樣板。\"\n  enabled_template_cannot_destroy: \"只有已停用的樣板可以被刪除。請先確認其他子問題是否有使用這個樣板，如果沒有則可以先停用它再來刪除。\"\n  orphaned_templates: \"追蹤標籤中被孤立的樣板\"\n  orphaned_template: \"追蹤標籤中被孤立的樣板\"\n  label_template_applied: \"問題樣板已套用。你可以按「還原」連結來還原。\"\n  label_hide_confirm_dialog_in_the_future: \"未來直接覆寫，不再詢問。\"\n  label_template_for_note: \"筆記樣板\"\n  label_use_template_when_edit: \"編輯問題時使用樣板\"\n  note_template: \"筆記樣板\"\n  no_note_templates_for_this_project: \"這個專案沒有任何回應樣板。\"\n  label_memo_help_message: \"請建立一個筆記來說明為何套用這個樣板。\"\n  note_template_name: \"筆記樣板名稱\"\n  note_description: \"回應內容\"\n  field_template_visibility: 樣板可見度\n  note_templates:\n    visibility:\n      mine: 只有我\n      roles: 只有這些角色\n      open: 任何人\n  please_select_at_least_one_role: \"請至少選擇一個角色。\"\n"
  },
  {
    "path": "config/locales/zh.yml",
    "content": "# Simplified Chinese strings go here for Rails i18n, based on file ja.yml\nzh:\n  issue_templates: ISSUE模板管理\n  issue_template: ISSUE模板管理\n  issue_template_note: 批注\n  label_enabled: 启用\n  label_disabled: 禁用\n  label_help_message: 关于ISSUE模板\n  label_show_help_message: 当创建/修改问题时显示对应的帮助信息。\n  about_help_message: 每个项目都可以自定义ISSUE模板帮助信息。\n  close_help: 关闭帮助信息。\n  about_template_help_message: 您可以查看当前项目ISSUE模板的帮助指南。\n  label_enabled_help_message: 该复选框用于激活当前ISSUE模板。若您只想将ISSUE模板保存为草稿，请取消该复选框的勾选。\n  label_list_templates: \"ISSUE模板列表\"\n  label_new_templates: \"新建ISSUE模板\"\n  issue_template_name: \"ISSUE模板名称\"\n  issue_description: \"ISSUE模板内容\"\n  issue_title: \"ISSUE主题\"\n  label_applied_for_issue: \"应用于该ISSUE的字段：\"\n  help_for_issue_title: \"若在ISSUE模板中已定义了主题，则在使用该ISSUE模板时，将自动替换为对应的主题信息。\"\n  help_for_this_field: \"当前字段帮助信息\"\n  permission_manage_issue_templates: \"管理ISSUE模板\"\n  permission_edit_issue_templates: \"编辑ISSUE模板\"\n  permission_show_issue_templates: \"显示ISSUE模板\"\n  project_module_issue_templates: \"ISSUE模板管理\"\n  label_isdefault_help_message: \"勾选后，设置当前ISSUE模板为指定跟踪类型对应的默认模板。\"\n  defaulf_template_loaded: \"在描述区域内加载模板默认信息。 (跟踪类型：%{tracker})\"\n  text_no_tracker_enabled: \"当前项目中尚未配置跟踪类型。\\n请在使用ISSUE模板前，先配置项目跟踪类型。\"\n  label_enabled_sharing: \"启用向下继承（在当前项目的子项目中使用该ISSUE模板）\"\n  label_inherit_templates: \"继承ISSUE模板\"\n  label_inherit_templates_help_message: \"从父项目中继承ISSUE模板。(仅限在父项目中使用，且标记为向下继承的ISSUE模板。)\"\n  label_inherited_templates: \"继承ISSUE模板\"\n  no_issue_templates_for_this_project: \"当前项目中未定义ISSUE模板信息。\"\n  link_to_index_edit_template: \"ISSUE模板列表 / 编辑ISSUE模板\"\n  erase_issue_subject_and_description: \"点击清除主题及描述信息。\"\n  unused_tracker_at_this_project: \"注意：当前项目中未定义可用的跟踪类型。请根据实际需要，重新配置ISSUE模板。\"\n  label_enabledshaing_help_message: \"若选中，则当前ISSUE模板可以向下继承，与子项目共享使用。(您需在子项目中激活ISSUE模板继承选项便可使用。)\"\n  label_should_replaced: \"替换主题及描述信息\"\n  label_should_replaced_help_message: \"若选中，现有主题及描述信息将被自动清除，并替换为ISSUE模板中定义的内容。（默认不选中，则在现有内容后扩展模板内定义的信息。)\"\n  global_issue_templates: \"全局ISSUE模板管理\"\n  no_issue_templates_for_this_redmine: \"当前未定义全局ISSUE模板。请联系Redmine系统管理员。\"\n  only_admin_can_associate_global_template: \"只有Redmine系统管理员才能在当前项目中关联全局ISSUE模板。\"\n  text_no_tracker_enabled_for_global: \"未指定跟踪类型。\\n在使用ISSUE模板前，请先指定模板适用的跟踪类型。\"\n  display_and_filter_issue_templates_in_dialog: \"模板过滤器\"\n  label_filter_template: \"模板过滤器\"\n  label_msg_confirm_to_replace: \"确认替换主题及描述信息？\"\n  label_apply_global_template_to_all_projects: \"将全局问题模板应用于全部项目。\"\n  note_apply_global_template_to_all_projects_setting_enabled: \"该全局问题模板通过插件设置配置后，应用于所有项目。\"\n  project_list_associated_this_template: \"项目列表： (已应用于全部 %{all} 个项目中的 %{applied} 个)\"\n  note_project_local_template_override_global_template: \"如果存在项目本地模板，则覆盖全局模板，且在该项目内创建问题时，不显示任何全局模板。\"\n  help_project_local_template_override_global_template: \"如果启用此选项，则问题的全局模板将应用于所有项目。 如果设置了每个跟踪器的项目特定模板，则会覆盖对应的全局模板，并在创建新问题时，隐藏全局模板。\"\n  warning_project_local_template_override_global_template: \"注册全局问题模板时，务必注意模板信息中的特定项目的机密信息。 一旦启用此选项，则所有全局模板将应用于所有项目。\"\n  revert_before_applying_template: \"回退\"\n  template_remove_confirm: \"您确定要删除此模板吗？ 当前有 %{count} 个项目正在使用此模板。\"\n  label_number_of_subprojects_use_this_template: \"%{count} 个项目正在使用此模板 \"\n  enabled_template_cannot_destroy: \"已启用的模板不能删除。检查您正在使用的模板是否在其他项目中存在，并在删除之前将其禁用。\"\n  orphaned_templates: \"基于跟踪的个性化模板\"\n  orphaned_template: \"基于跟踪的个性化模板\"\n"
  },
  {
    "path": "config/routes.rb",
    "content": "#\n# TODO: Clean up routing.\n#\nRails.application.routes.draw do\n  concern :tamplate_common do\n    get 'orphaned_templates', on: :collection\n  end\n\n  concern :previewable do\n    post 'preview', on: :collection\n  end\n\n  resources :global_issue_templates, except: [:edit], concerns: %i[tamplate_common previewable]\n\n  # for project issue template\n  resources :projects, only: [] do\n    resources :issue_templates, except: [:edit], concerns: [:tamplate_common] do\n      post 'set_pulldown', on: :collection\n      get 'list_templates', on: :collection\n    end\n\n    resources :issue_templates_settings, only: [:edit], concerns: [:previewable] do\n      patch 'edit', on: :collection\n    end\n\n    get 'issue_templates_settings', to: 'issue_templates_settings#index'\n\n    resources :note_templates, except: [:edit]\n  end\n\n  resources :issue_templates, only: %i[load preview load_selectable_fields], concerns: [:previewable] do\n    post 'load', on: :collection\n    get 'load_selectable_fields', on: :collection\n  end\n\n  # for note temlate\n  resources :note_templates, only: %i[load preview list_templates] do\n    post 'load', on: :collection\n    get 'list_templates', on: :collection\n  end\n\n  # for global note temlate\n  resources :global_note_templates, except: [:edit], concerns: %i[previewable]\nend\n"
  },
  {
    "path": "db/migrate/0001_create_issue_templates.rb",
    "content": "class CreateIssueTemplates < ActiveRecord::Migration[4.2]\n  def self.up\n    create_table :issue_templates do |t|\n      t.column :title, :string, null: false\n      t.column :project_id, :integer\n      t.column :tracker_id, :integer, null: false\n      t.column :author_id, :integer, null: false\n      t.column :note, :string\n      t.column :description, :text\n      t.column :enabled, :boolean\n      t.column :created_on, :timestamp\n      t.column :updated_on, :timestamp\n    end\n    add_index :issue_templates, :author_id\n    add_index :issue_templates, :project_id\n    add_index :issue_templates, :tracker_id\n  end\n\n  def self.down\n    remove_index :issue_templates, :author_id\n    remove_index :issue_templates, :project_id\n    remove_index :issue_templates, :tracker_id\n    drop_table :issue_templates\n  end\nend\n"
  },
  {
    "path": "db/migrate/0002_create_issue_template_settings.rb",
    "content": "class CreateIssueTemplateSettings < ActiveRecord::Migration[4.2]\n  def self.up\n    create_table :issue_template_settings do |t|\n      t.column :project_id, :integer\n\n      t.column :help_message, :text\n\n      t.column :enabled, :boolean\n    end\n  end\n\n  def self.down\n    drop_table :issue_template_settings\n  end\nend\n"
  },
  {
    "path": "db/migrate/0003_add_issue_title_to_issue_templates.rb",
    "content": "class AddIssueTitleToIssueTemplates < ActiveRecord::Migration[4.2]\n  def self.up\n    add_column :issue_templates, :issue_title, :string\n\n    IssueTemplate.reset_column_information\n    issue_templates = IssueTemplate.all\n    issue_templates.each do |t|\n      t.issue_title = t.title\n      t.save\n    end\n  end\n\n  def self.down\n    remove_column :issue_templates, :issue_title\n  end\nend\n"
  },
  {
    "path": "db/migrate/0004_add_position_to_issue_templates.rb",
    "content": "class AddPositionToIssueTemplates < ActiveRecord::Migration[4.2]\n  def self.up\n    add_column :issue_templates, :position, :integer, default: 1\n\n    IssueTemplate.reset_column_information\n\n    issue_templates = IssueTemplate.all\n    say_with_time('Update each template to set default position.') do\n      issue_templates.each_with_index { |t, i| t.update_attribute(:position, i + 1) }\n    end\n  end\n\n  def self.down\n    remove_column :issue_templates, :position\n  end\nend\n"
  },
  {
    "path": "db/migrate/20121208150810_add_is_default_to_issue_templates.rb",
    "content": "class AddIsDefaultToIssueTemplates < ActiveRecord::Migration[4.2]\n  def self.up\n    add_column :issue_templates, :is_default, :boolean, default: false\n  end\n\n  def self.down\n    remove_column :issue_templates, :is_default\n  end\nend\n"
  },
  {
    "path": "db/migrate/20130630141710_add_enabled_sharing_to_issue_templates.rb",
    "content": "class AddEnabledSharingToIssueTemplates < ActiveRecord::Migration[4.2]\n  def self.up\n    add_column :issue_templates, :enabled_sharing, :boolean, default: false\n  end\n\n  def self.down\n    remove_column :issue_templates, :enabled_sharing\n  end\nend\n"
  },
  {
    "path": "db/migrate/20130701024625_add_inherit_templates_to_issue_template_settings.rb",
    "content": "class AddInheritTemplatesToIssueTemplateSettings < ActiveRecord::Migration[4.2]\n  def self.up\n    add_column :issue_template_settings, :inherit_templates, :boolean, default: false, null: false\n  end\n\n  def self.down\n    remove_column :issue_template_settings, :inherit_templates\n  end\nend\n"
  },
  {
    "path": "db/migrate/2014020191500_add_should_replaced_to_issue_template_settings.rb",
    "content": "class AddShouldReplacedToIssueTemplateSettings < ActiveRecord::Migration[4.2]\n  def self.up\n    add_column :issue_template_settings, :should_replaced, :boolean, default: false\n  end\n\n  def self.down\n    remove_column :issue_template_settings, :should_replaced\n  end\nend\n"
  },
  {
    "path": "db/migrate/20140307024626_create_global_issue_templates.rb",
    "content": "class CreateGlobalIssueTemplates < ActiveRecord::Migration[4.2]\n  def change\n    create_table :global_issue_templates do |t|\n      t.string :title\n      t.string :issue_title\n      t.integer :tracker_id\n      t.integer :author_id\n      t.string :note\n      t.text :description\n      t.boolean :enabled\n      t.integer :position\n      t.boolean :is_default\n      t.timestamp :created_on\n      t.timestamp :updated_on\n    end\n    add_index :global_issue_templates, :author_id\n    add_index :global_issue_templates, :tracker_id\n  end\n\n  def self.down\n    remove_index :global_issue_templates, :author_id\n    remove_index :global_issue_templates, :tracker_id\n    drop_table :global_issue_templates\n  end\nend\n"
  },
  {
    "path": "db/migrate/20140312054531_create_global_issue_templates_projects.rb",
    "content": "class CreateGlobalIssueTemplatesProjects < ActiveRecord::Migration[4.2]\n  def self.up\n    create_table :global_issue_templates_projects, id: false do |t|\n      t.integer :project_id\n      t.integer :global_issue_template_id\n    end\n  end\n\n  def self.down\n    drop_table :global_issue_templates_projects\n  end\nend\n"
  },
  {
    "path": "db/migrate/20140330155030_remove_is_default_from_global_issue_templates.rb",
    "content": "class RemoveIsDefaultFromGlobalIssueTemplates < ActiveRecord::Migration[4.2]\n  def self.up\n    remove_column :global_issue_templates, :is_default\n  end\n\n  def self.down\n  end\nend\n"
  },
  {
    "path": "db/migrate/20160727222420_add_checklist_json_to_issue_templates.rb",
    "content": "class AddChecklistJsonToIssueTemplates < ActiveRecord::Migration[4.2]\n  def self.up\n    add_column :issue_templates, :checklist_json, :text\n  end\n\n  def self.down\n    remove_column :issue_templates, :checklist_json\n  end\nend\n"
  },
  {
    "path": "db/migrate/20160828190000_add_checklist_json_to_global_issue_templates.rb",
    "content": "class AddChecklistJsonToGlobalIssueTemplates < ActiveRecord::Migration[4.2]\n  def self.up\n    add_column :global_issue_templates, :checklist_json, :text\n  end\n\n  def self.down\n    remove_column :global_issue_templates, :checklist_json\n  end\nend\n"
  },
  {
    "path": "db/migrate/20160829001500_change_issue_template_enabled_column.rb",
    "content": "class ChangeIssueTemplateEnabledColumn < ActiveRecord::Migration[4.2]\n  def self.up\n    change_column :issue_templates, :enabled, :boolean, default: false, null: false\n  end\n\n  def self.down\n    change_column :issue_templates, :enabled, :boolean\n  end\nend\n"
  },
  {
    "path": "db/migrate/20160829001530_change_global_issue_template_enabled_column.rb",
    "content": "class ChangeGlobalIssueTemplateEnabledColumn < ActiveRecord::Migration[4.2]\n  def self.up\n    change_column :global_issue_templates, :enabled, :boolean, default: false, null: false\n  end\n\n  def self.down\n    change_column :global_issue_templates, :enabled, :boolean\n  end\nend\n"
  },
  {
    "path": "db/migrate/20170317082100_add_is_default_to_global_issue_templates.rb",
    "content": "class AddIsDefaultToGlobalIssueTemplates < ActiveRecord::Migration[4.2]\n  def self.up\n    add_column :global_issue_templates, :is_default, :boolean, default: false, null: false\n  end\n\n  def self.down\n    remove_column :global_issue_templates, :is_default\n  end\nend\n"
  },
  {
    "path": "db/migrate/20181104065200_add_unique_key_to_global_issue_templates_projects.rb",
    "content": "class AddUniqueKeyToGlobalIssueTemplatesProjects < ActiveRecord::Migration[4.2]\n  def self.up\n    add_index :global_issue_templates_projects,\n              [:project_id, :global_issue_template_id], unique: true,\n              name: 'projects_global_issue_templates'\n  end\n\n  def self.down\n    remove_index :global_issue_templates_projects, name: 'projects_global_issue_templates'\n  end\nend\n"
  },
  {
    "path": "db/migrate/20190303082102_create_note_templates.rb",
    "content": "class CreateNoteTemplates < ActiveRecord::Migration[5.1]\n  def up\n    create_table :note_templates do |t|\n      t.string :name\n      t.string :description\n      t.string :memo\n      t.integer :project_id\n      t.integer :tracker_id\n      t.integer :author_id\n      t.boolean :enabled\n      t.integer :position\n      t.timestamps\n    end\n    add_index :note_templates, :author_id\n    add_index :note_templates, :project_id\n    add_index :note_templates, :tracker_id\n    add_index :note_templates, :enabled\n  end\n\n  def down\n    remove_index :note_templates, :author_id\n    remove_index :note_templates, :project_id\n    remove_index :note_templates, :tracker_id\n    remove_index :note_templates, :enabled\n    drop_table :note_templates\n  end\nend\n"
  },
  {
    "path": "db/migrate/20190714171020_create_note_visible_roles.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateNoteVisibleRoles < ActiveRecord::Migration[5.1]\n  def up\n    create_table :note_visible_roles do |t|\n      t.integer :note_template_id\n      t.integer :role_id\n      t.timestamps\n    end\n    add_index :note_visible_roles, :note_template_id\n    add_index :note_visible_roles, :role_id\n  end\n\n  def down\n    remove_index :note_visible_roles, :role_id\n    remove_index :note_visible_roles, :note_template_id\n    drop_table :note_visible_roles\n  end\nend\n"
  },
  {
    "path": "db/migrate/20190714211530_add_visibility_to_note_templates.rb",
    "content": "# frozen_string_literal: true\n\nclass AddVisibilityToNoteTemplates < ActiveRecord::Migration[5.1]\n  def self.up\n    add_column :note_templates, :visibility, :integer, default: 2\n  end\n\n  def self.down\n    remove_column :note_templates, :visibility\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200101204020_add_related_link_to_issue_templates.rb",
    "content": "# frozen_string_literal: true\n\nclass AddRelatedLinkToIssueTemplates < ActiveRecord::Migration[5.2]\n  def self.up\n    add_column :issue_templates, :related_link, :text\n  end\n\n  def self.down\n    remove_column :issue_templates, :related_link\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200101204220_add_related_link_to_global_issue_templates.rb",
    "content": "# frozen_string_literal: true\n\nclass AddRelatedLinkToGlobalIssueTemplates < ActiveRecord::Migration[5.2]\n  def self.up\n    add_column :global_issue_templates, :related_link, :text\n  end\n\n  def self.down\n    remove_column :global_issue_templates, :related_link\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200102204815_add_link_title_to_issue_templates.rb",
    "content": "# frozen_string_literal: true\n\nclass AddLinkTitleToIssueTemplates < ActiveRecord::Migration[5.2]\n  def self.up\n    add_column :issue_templates, :link_title, :text\n  end\n\n  def self.down\n    remove_column :issue_templates, :link_title\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200102205044_add_link_title_to_global_issue_templates.rb",
    "content": "# frozen_string_literal: true\n\nclass AddLinkTitleToGlobalIssueTemplates < ActiveRecord::Migration[5.2]\n  def self.up\n    add_column :global_issue_templates, :link_title, :text\n  end\n\n  def self.down\n    remove_column :global_issue_templates, :link_title\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200103213630_add_builtin_fields_json_to_issue_templates.rb",
    "content": "class AddBuiltinFieldsJsonToIssueTemplates < ActiveRecord::Migration[5.2]\n  def self.up\n    add_column :issue_templates, :builtin_fields_json, :text\n  end\n\n  def self.down\n    remove_column :issue_templates, :builtin_fields_json\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200115073600_add_builtin_fields_json_to_global_issue_templates.rb",
    "content": "class AddBuiltinFieldsJsonToGlobalIssueTemplates < ActiveRecord::Migration[5.2]\n  def self.up\n    add_column :global_issue_templates, :builtin_fields_json, :text\n  end\n\n  def self.down\n    remove_column :global_issue_templates, :builtin_fields_json\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200314132500_change_column_note_template_description.rb",
    "content": "class ChangeColumnNoteTemplateDescription < ActiveRecord::Migration[5.2]\n  def self.up\n    change_column :note_templates, :description, :text\n  end\n\n  def down\n     change_column :note_templates, :description, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200405115700_create_global_note_templates.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateGlobalNoteTemplates < ActiveRecord::Migration[5.1]\n  def up\n    create_table :global_note_templates do |t|\n      t.string :name\n      t.text :description\n      t.string :memo\n      t.integer :tracker_id\n      t.integer :author_id\n      t.boolean :enabled\n      t.integer :position\n      t.integer :visibility, default: 2\n      t.timestamps\n    end\n    add_index :global_note_templates, :author_id\n    add_index :global_note_templates, :tracker_id\n    add_index :global_note_templates, :enabled\n  end\n\n  def down\n    remove_index :global_note_templates, :author_id\n    remove_index :global_note_templates, :tracker_id\n    remove_index :global_note_templates, :enabled\n    drop_table :global_note_templates\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200405120700_create_global_note_visible_roles.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateGlobalNoteVisibleRoles < ActiveRecord::Migration[5.1]\n  def up\n    create_table :global_note_visible_roles do |t|\n      t.integer :global_note_template_id\n      t.integer :role_id\n      t.timestamps\n    end\n    add_index :global_note_visible_roles, :global_note_template_id\n    add_index :global_note_visible_roles, :role_id\n  end\n\n  def down\n    remove_index :global_note_visible_roles, :role_id\n    remove_index :global_note_visible_roles, :global_note_template_id\n    drop_table :global_note_visible_roles\n  end\nend\n"
  },
  {
    "path": "db/migrate/20200418114157_create_join_table_global_note_template_project.rb",
    "content": "class CreateJoinTableGlobalNoteTemplateProject < ActiveRecord::Migration[5.2]\n  def change\n    create_join_table :global_note_templates, :projects, table_name: :global_note_template_projects do |t|\n      # t.index [:global_note_template_id, :project_id]\n      # t.index [:project_id, :global_note_template_id]\n    end\n  end\nend\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '3.2'\nservices:\n  # start service for redmine with plugin\n  # 1. $ docker-compose build --force-rm --no-cache\n  # 2. $ docker-compose up -d web\n  #\n  #\n  web:\n    build:\n      context: .\n    image: redmine_sqlite3\n    container_name: redmine_sqlite3\n    command: >\n      bash -c \"bundle &&\n           bundle exec rake db:migrate &&\n           bundle exec rake redmine:plugins:migrate &&\n           bundle exec rake generate_secret_token &&\n           bundle exec rails s -p 3000 -b '0.0.0.0'\"\n    environment:\n      RAILS_ENV: development\n    volumes:\n      - .:/tmp/redmine/plugins/redmine_issue_templates\n      - ./.data:/tmp/data\n    ports:\n      - \"3000:3000\"\n  mysql:\n    image: mysql\n    environment:\n      MYSQL_ROOT_PASSWORD: pasword\n    ports:\n      - \"3306:3306\"\n"
  },
  {
    "path": "goodcheck.yml",
    "content": "rules:\n  - id: akiko.redmine.user_password\n    pattern: 'FactoryBot.create(:user, :password_same_login, login:' \n    message: |\n      FactoryBotで trait: \":password_same_login\" を使ってログイン名とパスワードを同じユーザを作ってテストする場合は、ログイン名（ = パスワード）の長さは8以上になるようにして下さい。\n\n      \"admin\" や \"manager\" では8文字未満のため失敗します。(Status GreenでもCircleCIのログも確認してね！)\n    glob:\n      - \"**/*_spec.rb\"\n\n  - id: akiko.redmine.spec.FactoryBotは省略しない\n    pattern: \" create(:\"\n    message: |\n      FactoryBotを使う場合は、FactorryBot.create(:symbol, .... ) のようにFactoryBotを省略しないで下さい。\n\n      慣れていないと、ActiveRecordのcreate() メソッドと混乱しやすいので。\n    glob:\n      - \"**/*_spec.rb\"\n\n\n\n\n"
  },
  {
    "path": "init.rb",
    "content": "# frozen_string_literal: true\n\n# Redmine Issue Template Plugin\n#\n# This is a plugin for Redmine to generate and use issue templates\n# for each project to assist issue creation.\n# Created by Akiko Takano.\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (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\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\nrequire 'redmine'\nrequire 'issue_templates/issues_hook'\nrequire 'issue_templates/journals_hook'\n\n# NOTE: Keep error message for a while to support Redmine3.x users.\ndef issue_template_version_message(original_message = nil)\n  <<-\"USAGE\"\n\n  ==========================\n  #{original_message}\n\n  If you use Redmine3.x, please use Redmine Issue Templates version 0.2.x or clone via\n  'v0.2.x-support-Redmine3' branch.\n  You can download older version from here: https://github.com/akiko-pusu/redmine_issue_templates/releases\n  ==========================\n  USAGE\nend\n\ndef template_menu_allowed?\n  proc { |p| User.current.allowed_to?({ controller: 'issue_templates', action: 'show' }, p) }\nend\n\nRedmine::Plugin.register :redmine_issue_templates do\n  begin\n    name 'Redmine Issue Templates plugin'\n    author 'Akiko Takano'\n    description 'Plugin to generate and use issue templates for each project to assist issue creation.'\n    version '1.1.0'\n    author_url 'http://twitter.com/akiko_pusu'\n    requires_redmine version_or_higher: '4.0'\n    url 'https://github.com/akiko-pusu/redmine_issue_templates'\n\n    settings partial: 'settings/redmine_issue_templates',\n             default: {\n               apply_global_template_to_all_projects: 'false',\n               apply_template_when_edit_issue: 'false',\n               enable_builtin_fields: 'false'\n             }\n\n    menu :admin_menu, :redmine_issue_templates, { controller: 'global_issue_templates', action: 'index' },\n         caption: :global_issue_templates, html: { class: 'icon icon-global_issue_templates' }\n\n    menu :project_menu, :issue_templates, { controller: 'issue_templates', action: 'index' },\n         caption: :issue_templates, param: :project_id,\n         after: :settings, if: template_menu_allowed?\n\n    project_module :issue_templates do\n      permission :edit_issue_templates, issue_templates: %i[new create edit update destroy move], note_templates: %i[new create edit update destroy move]\n      permission :show_issue_templates, issue_templates: %i[index show load set_pulldown list_templates orphaned_templates],\n                                        note_templates: %i[index show load list_templates]\n      permission :manage_issue_templates, { issue_templates_settings: %i[index edit] }, require: :member\n    end\n  rescue ::Redmine::PluginRequirementError => e\n    raise ::Redmine::PluginRequirementError.new(issue_template_version_message(e.message)) # rubocop:disable Style/RaiseArgs\n  end\nend\n"
  },
  {
    "path": "lang/en.yml",
    "content": "# English strings go here\r\nmy_label: \"My label\"\r\n"
  },
  {
    "path": "lib/issue_templates/issues_hook.rb",
    "content": "# To change this template, choose Tools | Templates\n# and open the template in the editor.\nmodule IssueTemplates\n  class IssuesHook < Redmine::Hook::ViewListener\n    include IssuesHelper\n\n    CONTROLLERS = %(\n      'IssuesController' 'IssueTemplatesController' 'ProjectsController' 'IssueTemplatesSettingsController'\n      'GlobalIssueTemplatesController' 'SettingsController' 'NoteTemplatesController'\n      'GlobalNoteTemplatesController'\n    ).freeze\n\n    ACTIONS = %('new' 'update_form' 'create', 'show').freeze\n\n    def view_layouts_base_html_head(context = {})\n      o = stylesheet_link_tag('issue_templates', plugin: 'redmine_issue_templates')\n      o << javascript_include_tag('issue_templates', plugin: 'redmine_issue_templates') if need_template_js?(context[:controller])\n      o\n    end\n\n    def view_issues_form_details_top(context = {})\n      issue = context[:issue]\n      parameters = context[:request].parameters\n      return if existing_issue?(issue)\n      return if copied_issue?(parameters)\n\n      project = context[:project]\n      project_id = issue.project_id.present? ? issue.project_id : project.id\n      return unless create_action?(parameters[:action]) && project_id.present?\n\n      context[:controller].send(\n        :render_to_string,\n        partial: 'issue_templates/issue_select_form',\n        locals: locals_params(issue, project_id, parameters[:form_update_triggered_by])\n      )\n    end\n\n    render_on :view_issues_sidebar_planning_bottom, partial: 'issue_templates/issue_template_link'\n\n    private\n\n    def existing_issue?(issue)\n      return false if apply_template_when_edit_issue?\n\n      issue.id.present? || issue.tracker_id.blank?\n    end\n\n    def copied_issue?(parameters)\n      return false if apply_template_when_edit_issue?\n\n      copy_from = parameters[:copy_from]\n      copy_from.present?\n    end\n\n    def create_action?(action)\n      return true if apply_template_when_edit_issue?\n\n      ACTIONS.include?(action)\n    end\n\n    def setting(project_id)\n      IssueTemplateSetting.find_or_create(project_id)\n    end\n\n    def need_template_js?(controller)\n      CONTROLLERS.include?(controller.class.name)\n    end\n\n    def plugin_setting\n      Setting.plugin_redmine_issue_templates\n    end\n\n    def apply_all_projects?\n      plugin_setting['apply_global_template_to_all_projects'].to_s == 'true'\n    end\n\n    def apply_template_when_edit_issue?\n      plugin_setting['apply_template_when_edit_issue'].to_s == 'true'\n    end\n\n    def locals_params(issue, project_id, is_triggered_by)\n      { setting: setting(project_id),\n        issue: issue,\n        is_triggered_by: is_triggered_by,\n        project_id: project_id,\n        pulldown_url: pulldown_url(issue, project_id, is_triggered_by) }\n    end\n\n    def pulldown_url(issue, project_id, is_triggered_by)\n      pulldown_url = if issue.try(:id).present?\n                       url_for(controller: 'issue_templates',\n                               action: 'set_pulldown', project_id: project_id, is_triggered_by: is_triggered_by,\n                               is_update_issue: issue.try(:id).present?)\n                     else\n                       url_for(controller: 'issue_templates',\n                               action: 'set_pulldown', project_id: project_id, is_triggered_by: is_triggered_by)\n                     end\n      pulldown_url\n    end\n  end\nend\n"
  },
  {
    "path": "lib/issue_templates/journals_hook.rb",
    "content": "# frozen_string_literal: true\n\n# To change this template, choose Tools | Templates\n# and open the template in the editor.\nmodule IssueTemplates\n  class JournalsHook < Redmine::Hook::ViewListener\n    def view_journals_notes_form_after_notes(context = {})\n      journal = context[:journal]\n      issue = journal.issue\n      tracker_id = issue.try(:tracker_id)\n      templates = target_templates(context, tracker_id)\n      global_templates = global_note_templates(context, tracker_id)\n      return if templates.empty? && global_templates.empty?\n\n      context[:controller].send(\n        :render_to_string,\n        partial: 'issue_templates/note_form', locals: { type: 'template_edit_journal', templates: templates, issue: issue }\n      )\n    end\n\n    # Add journal with edit issue\n    def view_issues_edit_notes_bottom(context = {})\n      issue = context[:issue]\n      tracker_id = issue.try(:tracker_id)\n      templates = target_templates(context, tracker_id)\n      global_templates = global_note_templates(context, tracker_id)\n      return if templates.empty? && global_templates.empty?\n\n      context[:controller].send(\n        :render_to_string,\n        partial: 'issue_templates/note_form', locals: { type: 'template_issue_notes', templates: templates, issue: issue }\n      )\n    end\n\n    def target_templates(context, tracker_id)\n      (tracker_id, project_id) = tracker_project_ids(context, tracker_id)\n      NoteTemplate.visible_note_templates_condition(\n        user_id: User.current.id, project_id: project_id, tracker_id: tracker_id\n      )\n    end\n\n    def global_note_templates(context, tracker_id)\n      (tracker_id, project_id) = tracker_project_ids(context, tracker_id)\n      GlobalNoteTemplate.visible_note_templates_condition(\n        user_id: User.current.id, project_id: project_id, tracker_id: tracker_id\n      )\n    end\n\n    def tracker_project_ids(context, tracker_id)\n      project = context[:project]\n      project_id = project.present? ? project.id : issue.try(:project_id)\n      [tracker_id, project_id]\n    end\n  end\nend\n"
  },
  {
    "path": "lib/tasks/test.rake",
    "content": "require 'rake/testtask'\n\nnamespace :redmine_issue_templates do\n  desc 'Run test for redmine_issue_template plugin.'\n  task :test do |task_name|\n    next unless ENV['RAILS_ENV'] == 'test' && task_name.name == 'redmine_issue_templates:test'\n  end\n\n  Rake::TestTask.new(:test) do |t|\n    t.libs << 'lib'\n    t.pattern = 'plugins/redmine_issue_templates/test/**/*_test.rb'\n    t.verbose = false\n    t.warning = false\n  end\n\n  desc 'Run spec for redmine_issue_template plugin'\n  task :spec do |task_name|\n    next unless ENV['RAILS_ENV'] == 'test' && task_name.name == 'redmine_issue_templates:spec'\n\n    begin\n      require 'rspec/core'\n      path = 'plugins/redmine_issue_templates/spec/'\n      options = ['-I plugins/redmine_issue_templates/spec']\n      options << '--format'\n      options << 'documentation'\n      options << path\n      RSpec::Core::Runner.run(options)\n    rescue LoadError => ex\n      puts \"This task should be called only for redmine issue template spec. #{ex.message}\"\n    end\n  end\nend\n"
  },
  {
    "path": "lib/tasks/util.rake",
    "content": "namespace :redmine_issue_templates do\n  desc 'Apply inhelit template setting to child projects.'\n  task :apply_inhelit_template_to_child_projects, 'project_id'\n  task apply_inhelit_template_to_child_projects: :environment do |_t, args|\n    project_id = args.project_id\n    begin\n      IssueTemplateSetting.apply_template_to_child_projects(project_id)\n    rescue ActiveRecord::RecordNotFound\n      puts \"IssueTemplateSetting to project specified by #{project_id} does not exist.\"\n    end\n  end\n\n  desc 'Unapply inhelit template setting from child projects.'\n  task :unapply_inhelit_template_from_child_projects, 'project_id'\n  task unapply_inhelit_template_from_child_projects: :environment do |_t, args|\n    project_id = args.project_id\n    begin\n      IssueTemplateSetting.unapply_template_from_child_projects(project_id)\n    rescue ActiveRecord::RecordNotFound\n      puts \"IssueTemplateSetting to project specified by #{project_id} does not exist.\"\n    end\n  end\nend\n"
  },
  {
    "path": "script/circleci-setup.sh",
    "content": "#!/bin/sh\ncd /tmp/\ngit clone --depth 1 -b $REDMINE_BRANCH https://github.com/redmine/redmine redmine\n\n# switch target version of redmine\ncd /tmp/redmine\ncat << HERE >> config/database.yml\ntest:\n  adapter: mysql2\n  database: redmine_test\n  host: 127.0.0.1\n  username: root\n  password: \"\"\n  encoding: utf8mb4\n  sql_mode: false\nHERE\n\n# move redmine source to wercker source directory\necho\nmkdir -p /tmp/redmine/plugins/${CIRCLE_PROJECT_REPONAME}\n\n# Move Gemfile.local to Gemfile only for test\nmv ~/repo/Gemfile.local ~/repo/Gemfile\n\nmv ~/repo/* /tmp/redmine/plugins/${CIRCLE_PROJECT_REPONAME}/\nmv ~/repo/.* /tmp/redmine/plugins/${CIRCLE_PROJECT_REPONAME}/\nmv /tmp/redmine/* ~/repo/\nmv /tmp/redmine/.* ~/repo/\nls -la ~/repo/\n"
  },
  {
    "path": "spec/controllers/concerns/issue_templates_common_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../../spec_helper'\n\ndescribe 'IssueTemplatesCommon' do\n  before do\n    class FakesController < ApplicationController\n      include Concerns::IssueTemplatesCommon\n    end\n    allow_any_instance_of(FakesController).to receive(:action_name).and_return('fake_action')\n    User.current = FactoryBot.build(:user)\n  end\n  let(:mock_controller) { FakesController.new }\n\n  describe '#log_action' do\n    subject { mock_controller.log_action }\n\n    it do\n      expect(Rails.logger).to receive(:info).with(\"[FakesController] fake_action called by #{User.current.name}\").once\n      subject\n    end\n  end\nend\n"
  },
  {
    "path": "spec/controllers/global_issue_templates_controller_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\nrequire File.expand_path(File.dirname(__FILE__) + '/../support/controller_helper')\n\ndescribe GlobalIssueTemplatesController, type: :controller do\n  let(:count) { 4 }\n  let(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n  let(:projects) { FactoryBot.create_list(:project, count) }\n\n  before do\n    # Prevent to call User.deliver_security_notification when user is created.\n    expect_any_instance_of(User).to receive(:deliver_security_notification).and_return(true)\n    @request.session[:user_id] = user.id\n  end\n\n  include_context 'As admin'\n\n  describe 'GET #index' do\n    render_views\n    before do\n      get :index\n    end\n\n    context 'As Non Admin' do\n      let(:is_admin) { false }\n      include_examples 'Right response', 403\n    end\n\n    context 'As Admin' do\n      include_examples 'Right response', 200\n    end\n  end\n\n  describe 'GET #new' do\n    render_views\n    before do\n      FactoryBot.create_list(:project, count)\n      FactoryBot.create(:tracker, :with_default_status)\n      get :new\n    end\n    include_examples 'Right response', 200\n  end\n\n  describe 'POST #create' do\n    render_views\n    let(:create_params) do\n      { global_issue_template: { title: 'Global Template newtitle for creation test',\n                                 note: 'Global note for creation test',\n                                 description: 'Global Template description for creation test',\n                                 tracker_id: tracker.id, enabled: 1, author_id: user.id, project_ids: project_ids } }\n    end\n    let(:global_issue_template) { GlobalIssueTemplate.first }\n\n    before do\n      post :create, params: create_params\n    end\n\n    context 'POST without project ids' do\n      let(:project_ids) { [] }\n      include_examples 'Right response', 302\n      it do\n        expect(global_issue_template.projects.count).to eq 0\n      end\n    end\n\n    context 'POST with check all project ids' do\n      let(:project_ids) { projects.map(&:id) }\n      include_examples 'Right response', 302\n      it do\n        expect(global_issue_template.projects.count).to eq projects.count\n      end\n    end\n\n    context 'POST with invalid url' do\n      let(:project_ids) { [] }\n      let(:create_params) do\n        { global_issue_template:\n          { title: 'Global Template newtitle for creation test',\n            note: 'Global note for creation test',\n            description: 'Global Template description for creation test',\n            tracker_id: tracker.id,\n            enabled: 1,\n            author_id: user.id,\n            project_ids: project_ids }.merge(related_link: 'bad format url') }\n      end\n\n      include_examples 'Right response', 200\n      it do\n        expect(global_issue_template.present?).to be_falsy\n      end\n\n      context 'POST with valid url' do\n        let(:project_ids) { [] }\n        let(:create_params) do\n          { global_issue_template:\n            { title: 'Global Template newtitle for creation test',\n              note: 'Global note for creation test',\n              description: 'Global Template description for creation test',\n              tracker_id: tracker.id,\n              enabled: 1,\n              author_id: user.id,\n              project_ids: project_ids }.merge(related_link: 'http://example.com/sample/index.html') }\n        end\n\n        include_examples 'Right response', 302\n        it do\n          expect(global_issue_template.present?).to be_truthy\n        end\n      end\n    end\n  end\n\n  # PATCH GlobalIssueTemplatesController#edit\n  describe 'PUT #update' do\n    render_views\n    let(:global_issue_template) do\n      create(:global_issue_template_with_projects, tracker_id: tracker.id, projects_count: 3)\n    end\n    let(:edit_params) { { description: 'Update Test Global template', project_ids: [''] } }\n\n    it 'Before update template has the default value' do\n      expect(global_issue_template.projects.count).to eq 3\n      expect(global_issue_template.description).not_to eq edit_params[:description]\n    end\n\n    it 'After update number of projects should changed' do\n      put :update, params: { id: global_issue_template.id, global_issue_template: edit_params }\n      expect(global_issue_template.projects.count).to eq 0\n    end\n\n    context 'PUT with builtin_fields param' do\n      let(:update_params) do\n        edit_params.merge(builtin_fields: builtin_fields)\n      end\n\n      before do\n        Setting.send 'plugin_redmine_issue_templates=', 'enable_builtin_fields' => 'true'\n        put :update, params: { id: global_issue_template.id, global_issue_template: update_params }\n      end\n\n      context 'invalid format' do\n        let(:builtin_fields) { '12345' }\n\n        include_examples 'Right response', 200\n\n        it do\n          msg = flash[:error]\n          expect(msg.present?).to be_truthy\n          expect(msg).to eq 'Please enter a valid JSON fotmat string.'\n        end\n      end\n\n      context 'PUT with valid builtin_fields param' do\n        let(:builtin_fields) { '{ \"foo\": \"bar\" }' }\n        include_examples 'Right response', 302\n\n        it do\n          expect(flash[:error].present?).to be_falsy\n          expect(global_issue_template.reload.builtin_fields_json).to eq JSON.parse(builtin_fields)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/controllers/issue_templates_controller_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\nrequire File.expand_path(File.dirname(__FILE__) + '/../support/controller_helper')\n\nRSpec.configure do |c|\n  c.include ControllerHelper\nend\n\n#\n# Shared Example\n#\nshared_examples 'Right response for GET #index', type: :controller do\n  include_examples 'Right response', 200\nend\n\ndescribe IssueTemplatesController do\n  let(:count) { 4 }\n  let(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n  let(:project) { FactoryBot.create(:project) }\n\n  include_context 'As admin'\n  before do\n    # Prevent to call User.deliver_security_notification when user is created.\n    allow_any_instance_of(User).to receive(:deliver_security_notification).and_return(true)\n\n    Redmine::Plugin.register(:redmine_issue_templates) do\n      settings partial: 'settings/redmine_issue_templates',\n               default: { 'apply_global_template_to_all_projects' => 'false' }\n    end\n\n    Setting.rest_api_enabled = '1'\n    @request.session[:user_id] = user.id\n    FactoryBot.create(:enabled_module, project_id: project.id)\n    global_issue_templates = FactoryBot.create_list(:global_issue_template, count, tracker_id: tracker.id)\n    global_issue_templates.each { |template| template.projects << project }\n    FactoryBot.create(:issue_template, tracker_id: tracker.id, project_id: project.id)\n    project.trackers << tracker\n  end\n\n  after(:all) do\n    Redmine::Plugin.unregister(:redmine_issue_templates)\n  end\n\n  describe 'GET #index' do\n    render_views\n\n    before do\n      get :index, params: { project_id: project.id }\n    end\n    include_examples 'Right response for GET #index'\n  end\n\n  describe 'GET #index with format.json' do\n    render_views\n    context 'Without auth header' do\n      before do\n        clear_token\n        get :index, params: { project_id: project.id }, format: :json\n      end\n      include_examples 'Right response', 401\n      after do\n        clear_token\n      end\n    end\n\n    context 'With auth header' do\n      before do\n        auth_with_user user\n        get :index, params: { project_id: project.id }, format: :json\n      end\n      include_examples 'Right response for GET #index'\n      it { expect(response.header['Content-Type']).to match('application/json') }\n      it { expect(JSON.parse(response.body)).to have_key('global_issue_templates') }\n      after do\n        clear_token\n      end\n    end\n  end\n\n  describe 'GET #list_templates' do\n    context 'Plugin Setting apply_global_template_to_all_projects is not activated' do\n      before do\n        get :list_templates, params: { project_id: project.id, issue_tracker_id: tracker.id }\n      end\n\n      include_examples 'Right response', 200\n    end\n\n    context 'Plugin Setting apply_global_template_to_all_projects is activated' do\n      before do\n        Setting.send 'plugin_redmine_issue_templates=', 'apply_global_template_to_all_projects' => 'true'\n        get :list_templates, params: { project_id: project.id, issue_tracker_id: tracker.id }\n      end\n\n      include_examples 'Right response', 200\n    end\n  end\n\n  describe 'GET #list_templates with format.json' do\n    render_views\n    context 'Without auth header' do\n      before do\n        clear_token\n        get :list_templates, params: { project_id: project.id,\n                                       issue_tracker_id: tracker.id }, format: :json\n      end\n      include_examples 'Right response', 401\n      after do\n        clear_token\n      end\n    end\n\n    context 'With auth header' do\n      before do\n        auth_with_user user\n        get :list_templates, params: { project_id: project.id,\n                                       issue_tracker_id: tracker.id }, format: :json\n      end\n      include_examples 'Right response', 200\n      it { expect(response.header['Content-Type']).to match('application/json') }\n      it { expect(JSON.parse(response.body)).to have_key('global_issue_templates') }\n      after do\n        clear_token\n      end\n    end\n  end\n\n  # Spec for copy feature.\n  describe 'GET #new with existing template id' do\n    let(:original_template) { IssueTemplate.first }\n    before do\n      auth_with_user user\n      get :new, params: { project_id: project.id, copy_from: original_template.id }\n    end\n\n    include_examples 'Right response', 200\n    #\n    # TODO: This example should be request spec.\n    # it 'Render new form filled with copied template values' do\n    #  issue_template = assigns(:issue_template)\n    #  expect(issue_template.id).to be_nil\n    #  expect(issue_template.title).to eq \"copy_of_#{original_template.title}\"\n    # end\n  end\n\n  describe 'POST #create' do\n    render_views\n    let(:template_params) do\n      { title: 'Issue Template newtitle for creation test',\n        note: 'Note for creation test',\n        description: 'Issue Template description for creation test',\n        tracker_id: tracker.id, enabled: 1, author_id: user.id }\n    end\n\n    let(:create_params) do\n      { issue_template: template_params }\n    end\n\n    let(:issue_template) { IssueTemplate.last }\n\n    context 'POST with valid param' do\n      before do\n        post :create, params: create_params.merge(project_id: project.id)\n      end\n\n      include_examples 'Right response', 302\n      it do\n        expect(issue_template.project.id).to eq project.id\n      end\n    end\n\n    context 'POST with valid builtin_fields param when enable_builtin_fields = true' do\n      let(:builtin_fields) { '{ \"foo\": \"bar\" }' }\n      let(:create_params) do\n        { issue_template: template_params.merge(builtin_fields: builtin_fields) }\n      end\n\n      before do\n        Setting.send 'plugin_redmine_issue_templates=', 'enable_builtin_fields' => 'true'\n        post :create, params: create_params.merge(project_id: project.id)\n      end\n      include_examples 'Right response', 302\n      it do\n        expect(issue_template.builtin_fields_json).to eq JSON.parse(builtin_fields)\n      end\n    end\n\n    context 'POST with invalid builtin_fields param when enable_builtin_fields = falsewhen enable_builtin_fields = false' do\n      let(:builtin_fields) { '12345' }\n      let(:create_params) do\n        { issue_template: template_params.merge(builtin_fields: builtin_fields) }\n      end\n\n      before do\n        Setting.send 'plugin_redmine_issue_templates=', 'enable_builtin_fields' => 'false'\n        post :create, params: create_params.merge(project_id: project.id)\n      end\n      include_examples 'Right response', 302\n\n      it do\n        msg = flash[:error]\n        expect(msg.present?).to be_falsy\n      end\n    end\n  end\n\n  describe 'PUT #update' do\n    render_views\n    let(:template_params) do\n      { title: 'Issue Template updated title for update test',\n        description: 'Issue Template description for update test',\n        tracker_id: tracker.id, enabled: 1, author_id: user.id }\n    end\n\n    let(:issue_template) { IssueTemplate.last }\n\n    before do\n      Setting.send 'plugin_redmine_issue_templates=', 'enable_builtin_fields' => 'true'\n      put :update, params: update_params.merge(id: issue_template.id, project_id: project.id)\n    end\n\n    context 'PUT with invalid builtin_fields param' do\n      let(:builtin_fields) { '12345' }\n      let(:update_params) do\n        { issue_template: template_params.merge(builtin_fields: builtin_fields) }\n      end\n\n      include_examples 'Right response', 200\n\n      it do\n        msg = flash[:error]\n        expect(msg.present?).to be_truthy\n        expect(msg).to eq 'Please enter a valid JSON fotmat string.'\n      end\n    end\n\n    context 'PUT with valid builtin_fields param' do\n      let(:builtin_fields) { '{ \"foo\": \"bar\" }' }\n      let(:update_params) do\n        { issue_template: template_params.merge(builtin_fields: builtin_fields) }\n      end\n\n      include_examples 'Right response', 302\n\n      it do\n        expect(flash[:error].present?).to be_falsy\n        expect(issue_template.reload.title).to eq 'Issue Template updated title for update test'\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/controllers/settings_controller_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\nrequire File.expand_path(File.dirname(__FILE__) + '/../support/controller_helper')\n\ndescribe SettingsController, type: :controller do\n  include_context 'As admin'\n  before do\n    Redmine::Plugin.register(:redmine_issue_templates) do\n      settings partial: 'settings/redmine_issue_templates',\n               default: { 'apply_global_template_to_all_projects' => 'false' }\n    end\n    @request.session[:user_id] = user.id\n  end\n\n  after(:all) do\n    Redmine::Plugin.unregister(:redmine_issue_templates)\n  end\n\n  describe '#GET plugin' do\n    render_views\n    before do\n      Setting.send 'plugin_redmine_issue_templates=', 'apply_global_template_to_all_projects' => 'false'\n      get :plugin, params: { id: 'redmine_issue_templates' }\n    end\n    include_examples 'Right response', 200\n    it 'Contains right plugin setting content' do\n      expect(response.body).to match(/id=\"settings_apply_global_template_to_all_projects\"/im)\n    end\n  end\n\n  describe '#POST plugin' do\n    render_views\n    before do\n      post :plugin, params: { id: 'redmine_issue_templates',\n                              settings: { apply_global_template_to_all_projects: true } }\n    end\n    include_examples 'Right response', 302\n    it 'Setting value is changed true' do\n      settings = Setting.plugin_redmine_issue_templates\n      expect(settings['apply_global_template_to_all_projects']).to be_truthy\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factories/enabled_modules.rb",
    "content": "FactoryBot.define do\n  factory :enabled_module do\n    project_id { 1 }\n    name { 'issue_templates' }\n  end\nend\n"
  },
  {
    "path": "spec/factories/global_issue_templates.rb",
    "content": "FactoryBot.define do\n  factory :global_issue_template do |t|\n    association :tracker\n    t.sequence(:title) { |n| \"global_template-title: #{n}\" }\n    t.sequence(:description) { |n| \"global_template-description: #{n}\" }\n    t.sequence(:note) { |n| \"global_template-note: #{n}\" }\n    t.sequence(:position) { |n| n }\n    t.enabled { true }\n    t.is_default { false }\n    t.author_id { 1 }\n\n    factory :global_issue_template_with_projects do\n      transient do\n        projects_count { 5 }\n      end\n\n      after(:create) do |global_issue_template, evaluator|\n        global_issue_template.projects = create_list(:project, evaluator.projects_count)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factories/global_note_templates.rb",
    "content": "FactoryBot.define do\n  factory :global_note_template do |t|\n    association :tracker\n    t.sequence(:name) { |n| \"global_template-title: #{n}\" }\n    t.sequence(:description) { |n| \"global_template-description: #{n}\" }\n    t.sequence(:memo) { |n| \"global_template-note: #{n}\" }\n    t.sequence(:position) { |n| n }\n    t.enabled { true }\n    t.author_id { 1 }\n    t.visibility { 2 } # open\n\n    factory :global_note_template_with_projects do\n      transient do\n        projects_count { 5 }\n      end\n\n      after(:create) do |global_note_template, evaluator|\n        global_note_template.projects = create_list(:project, evaluator.projects_count)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factories/issue_statuses.rb",
    "content": "FactoryBot.define do\n  factory :issue_status do\n    sequence(:name)     { |n| \"status-name: #{n}\" }\n    sequence(:position) { |n| n }\n    is_closed { false }\n  end\nend\n"
  },
  {
    "path": "spec/factories/issue_template_settings.rb",
    "content": "FactoryBot.define do\n  factory :issue_template_setting do |t|\n    association :project\n    t.sequence(:help_message) { |n| \"Project-#{n}: temlpate help\" }\n    t.enabled { true }\n    t.inherit_templates { false }\n    t.should_replaced { false }\n  end\nend\n"
  },
  {
    "path": "spec/factories/issue_templates.rb",
    "content": "FactoryBot.define do\n  factory :issue_template do |t|\n    association :project\n    association :tracker\n    t.sequence(:title) { |n| \"template-title: #{n}\" }\n    t.sequence(:issue_title) { |n| \"template-issue_title: #{n}\" }\n    t.sequence(:description) { |n| \"template-description: #{n}\" }\n    t.sequence(:note) { |n| \"template-note: #{n}\" }\n    t.sequence(:position) { |n| n }\n    t.enabled { true }\n    t.enabled_sharing { true }\n    t.author_id { 1 }\n  end\nend\n"
  },
  {
    "path": "spec/factories/projects.rb",
    "content": "FactoryBot.define do\n  factory :project do\n    sequence(:name) { |n| \"project-name: #{n}\" }\n    sequence(:description) { |n| \"project-description: #{n}\" }\n    sequence(:identifier) { |n| \"project-#{n}\" }\n    homepage { 'http://ecookbook.somenet.foo/' }\n    is_public { true }\n\n    trait :with_enabled_modules do\n      after(:build) do |tracker|\n        status = FactoryBot.create(:issue_status)\n        tracker.default_status_id = status.id\n      end\n    end\n\n    factory :project_with_enabled_modules do\n      after(:create) do |project, _evaluator|\n        FactoryBot.create(:enabled_module, project_id: project.id)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factories/role.rb",
    "content": "# frozen_string_literal: true\n\nFactoryBot.define do\n  factory :role do\n    sequence(:name) { |n| \"Developer: #{n}\" }\n    builtin { 0 }\n    issues_visibility { 'default' }\n    users_visibility { 'all' }\n    position { 1 }\n    permissions { %i[\n      edit_project\n      manage_members\n      manage_versions\n      manage_categories\n      view_issues\n      add_issues\n      edit_issues\n      copy_issues\n      manage_issue_relations\n      manage_subtasks\n      add_issue_notes\n      delete_issues\n      view_issue_watchers\n      save_queries\n      view_gantt\n      view_calendar\n      log_time\n      view_time_entries\n      edit_own_time_entries\n      manage_news\n      comment_news\n      view_documents\n      add_documents\n      edit_documents\n      delete_documents\n      view_wiki_pages\n      view_wiki_edits\n      edit_wiki_pages\n      protect_wiki_pages\n      delete_wiki_pages\n      add_messages\n      edit_own_messages\n      delete_own_messages\n      manage_boards\n      view_files\n      manage_files\n      browse_repository\n      view_changesets\n    ] }\n\n    trait :manager_role do\n      name { 'Manager' }\n      issues_visibility { 'all' }\n      users_visibility { 'all' }\n      permissions { %i[\n        add_project\n        edit_project\n        close_project\n        select_project_modules\n        manage_members\n        manage_versions\n        manage_categories\n        view_issues\n        add_issues\n        edit_issues\n        manage_issue_relations\n        manage_subtasks\n        add_issue_notes\n        delete_issues\n        view_issue_watchers\n        set_issues_private\n        set_notes_private\n        view_private_notes\n        delete_issue_watchers\n        manage_public_queries\n        save_queries\n        view_gantt\n        view_calendar\n        log_time\n        view_time_entries\n        edit_own_time_entries\n        delete_time_entries\n        manage_news\n        comment_news\n        view_documents\n        add_documents\n        edit_documents\n        delete_documents\n        view_wiki_pages\n        view_wiki_edits\n        edit_wiki_pages\n        delete_wiki_pages_attachments\n        protect_wiki_pages\n        delete_wiki_pages\n        rename_wiki_pages\n        add_messages\n        edit_own_messages\n        delete_own_messages\n        manage_boards\n        view_files\n        manage_files\n        browse_repository\n        manage_repository\n        view_changesets\n        manage_related_issues\n        manage_project_activities\n      ] }\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factories/trackers.rb",
    "content": "FactoryBot.define do\n  factory :tracker do\n    sequence(:name)     { |n| \"tracker-name: #{n}\" }\n    sequence(:position) { |n| n }\n    default_status_id { 1 }\n    trait :with_default_status do\n      after(:build) do |tracker|\n        status = FactoryBot.create(:issue_status)\n        tracker.default_status_id = status.id\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factories/users.rb",
    "content": "# frozen_string_literal: true\n\nFactoryBot.define do\n  factory :user do |u|\n    # sequence -> exp. :login -> user1, user2.....\n    u.sequence(:login)     { |n| \"user#{n}\" }\n    u.sequence(:firstname) { |n| \"User#{n}\" }\n    u.sequence(:lastname)  { |n| \"Test#{n}\" }\n    u.sequence(:mail)      { |n| \"user#{n}@badge.example.com\" }\n    u.language             { 'en' }\n    # password = foo\n    u.hashed_password      { '8f659c8d7c072f189374edacfa90d6abbc26d8ed' }\n    u.salt                 { '7599f9963ec07b5a3b55b354407120c0' }\n\n    # login and password is the same. (Note: login length should be longer than 7.)\n    trait :password_same_login do\n      after(:create) do |user|\n        user.password = user.login\n        user.auth_source_id = nil\n        user.save\n      end\n    end\n\n    trait :as_group do\n      type { 'Group' }\n      lastname { \"Group#{n}\" }\n    end\n  end\nend\n"
  },
  {
    "path": "spec/features/admin_spec.rb",
    "content": "require_relative '../spec_helper'\nrequire_relative '../rails_helper'\nrequire_relative '../support/login_helper'\n\nRSpec.configure do |c|\n  c.include LoginHelper\nend\n\nfeature 'PluginSetting to apply Global issue templates to all the projects', js: true do\n  given(:user) { FactoryBot.create(:user, :password_same_login, login: 'admin', language: 'en') }\n\n  background(:all) do\n    Redmine::Plugin.register(:redmine_issue_templates) do\n      settings partial: 'settings/redmine_issue_templates',\n               default: { 'apply_global_template_to_all_projects' => 'false' }\n    end\n  end\n\n  background do\n    # Prevent to call User.deliver_security_notification when user is created.\n    allow_any_instance_of(User).to receive(:deliver_security_notification).and_return(true)\n\n    Setting.send 'plugin_redmine_issue_templates=', 'apply_global_template_to_all_projects' => 'false'\n    user.update_attribute(:admin, true)\n    log_user(user.login, user.login)\n    visit '/settings/plugin/redmine_issue_templates'\n  end\n\n  scenario 'Settings \"apply_global_template_to_all_projects\" is displayed.' do\n    expect(page).to have_content('Apply Global issue templates to all the projects.')\n    expect(page).to have_selector('#settings_apply_global_template_to_all_projects')\n  end\n\n  scenario 'Activate \"apply_global_template_to_all_projects\".' do\n    expect(page).to have_unchecked_field('settings_apply_global_template_to_all_projects')\n    check 'settings_apply_global_template_to_all_projects'\n    click_on 'Apply'\n    expect(page).to have_selector('#settings_apply_global_template_to_all_projects')\n    expect(page).to have_checked_field('settings_apply_global_template_to_all_projects')\n  end\nend\n"
  },
  {
    "path": "spec/features/drag_and_drop_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire File.expand_path(File.dirname(__FILE__) + '/../rails_helper')\nrequire File.expand_path(File.dirname(__FILE__) + '/../spec_helper')\nrequire File.expand_path(File.dirname(__FILE__) + '/../support/login_helper')\n\nfeature 'Templates can be reorder via drag and drop', js: true do\n  include LoginHelper\n  given(:user) { FactoryBot.create(:user, :password_same_login, login: 'manager', language: 'en', admin: false) }\n  given(:project) { create(:project_with_enabled_modules) }\n  given(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n  given(:role) { FactoryBot.create(:role, :manager_role) }\n  given(:table) { page.find('table.list.issues.table-sortable:first-of-type > tbody') }\n\n  background do\n    FactoryBot.create_list(:issue_template, 4, project_id: project.id, tracker_id: tracker.id)\n\n    project.trackers << tracker\n    assign_template_priv(role, add_permission: :show_issue_templates)\n    assign_template_priv(role, add_permission: :edit_issue_templates)\n    member = Member.new(project: project, user_id: user.id)\n    member.member_roles << MemberRole.new(role: role)\n    member.save\n  end\n\n  scenario 'Can drag and drop' do\n    visit_template_list(user)\n\n    first_target = table.find('tr:nth-child(1) > td.buttons > span')\n    last_target = table.find('tr:nth-child(4) > td.buttons > span')\n\n    # change id: 1, 2, 3, 4 to 4, 1, 2, 3\n    expect do\n      first_target.drag_to(last_target)\n      sleep 0.5\n    end.to change {\n             IssueTemplate.order(:id).pluck(:position).to_a\n           }.from([1, 2, 3, 4]).to([4, 1, 2, 3])\n\n    # change id: 4, 1, 2, 3 to 3, 1, 4, 2\n    second_target = table.find('tr:nth-child(2) > td.buttons > span')\n    last_target = table.find('tr:nth-child(4) > td.buttons > span')\n\n    expect do\n      second_target.drag_to(last_target)\n      sleep 0.5\n    end.to change {\n             IssueTemplate.order(:id).pluck(:position).to_a\n           }.from([4, 1, 2, 3]).to([3, 1, 4, 2])\n  end\n\n  private\n\n  def visit_template_list(user)\n    # TODO: If does not user update, authentication is failed. This is workaround.\n    user.update_attribute(:admin, false)\n    log_user(user.login, user.password)\n    visit \"/projects/#{project.identifier}/issue_templates\"\n  end\n\n  def offset_array(from, to)\n    from_location = element_position(from)\n    to_location = element_position(to)\n\n    [to_location[0] - from_location[0], to_location[1] - from_location[1]]\n  end\n\n  def element_position(element)\n    Capybara.evaluate_script <<-RUBY\n      function() {\n        var element = document.evaluate('#{element.path}', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;\n        var rect = element.getBoundingClientRect();\n        return [rect.left, rect.top];\n      }();\n    RUBY\n  end\nend\n"
  },
  {
    "path": "spec/features/issue_template_popup_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\nrequire_relative '../rails_helper'\nrequire_relative '../support/login_helper'\n\nRSpec.configure do |c|\n  c.include LoginHelper\nend\n\nfeature 'Confirm dialog before overwrite description', js: true do\n  background(:all) do\n    Redmine::Plugin.register(:redmine_issue_templates) do\n      settings partial: 'settings/redmine_issue_templates',\n               default: { 'apply_global_template_to_all_projects' => 'false' }\n    end\n  end\n\n  given(:user) { FactoryBot.create(:user, :password_same_login, login: 'manager', language: 'en', admin: false) }\n  given(:project) { create(:project_with_enabled_modules) }\n  given(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n  given(:role) { FactoryBot.create(:role, :manager_role) }\n  given(:issue_priority) { FactoryBot.create(:priority) }\n  given(:first_target) { page.find('#issue_template > optgroup > option:nth-child(1)') }\n  given(:second_target) { page.find('#issue_template > optgroup > option:nth-child(2)') }\n  given(:issue_subject) { page.find('#issue_subject') }\n  given(:issue_description) { page.find('#issue_description') }\n  given(:first_template) { IssueTemplate.first }\n  given(:second_template) { IssueTemplate.second }\n\n  given(:related_link) { page.find('#issue_template_related_link') }\n\n  background do\n    FactoryBot.create_list(:issue_template, 2, project_id: project.id, tracker_id: tracker.id,\n                                               related_link: 'http://example.com/template/wiki#usage')\n\n    project.trackers << tracker\n    assign_template_priv(role, add_permission: :show_issue_templates)\n    member = Member.new(project: project, user_id: user.id)\n    member.member_roles << MemberRole.new(role: role)\n    member.save\n  end\n\n  scenario 'Template pulldown is shown when new issue.' do\n    visit_new_issue(user)\n    expect(page).to have_selector('div#template_area select#issue_template')\n    expect(issue_description.value).to eq ''\n    expect(issue_subject.value).to eq ''\n  end\n\n  scenario 'Select template and content is updated' do\n    visit_new_issue(user)\n    first_target.select_option\n    wait_for_ajax\n    expect(issue_description.value).not_to eq ''\n    expect(issue_description.value).to eq first_template.description\n    expect(issue_subject.value).to eq first_template.issue_title\n\n    expect(related_link.text).to eq 'Related Link'\n    expect(related_link['href']).to eq 'http://example.com/template/wiki#usage'\n  end\n\n  context 'Has default template' do\n    before do\n      first_template.is_default = true\n      first_template.save\n    end\n\n    context 'Overwite option is not activated' do\n      scenario 'Template pulldown is shown when new issue and default is loaded.' do\n        visit_new_issue(user)\n        wait_for_ajax\n        expect(page).to have_selector('div#template_area select#issue_template')\n        expect(issue_description.value).not_to eq ''\n        expect(issue_subject.value).not_to eq ''\n        expect(issue_description.value).to eq first_template.description\n        expect(issue_subject.value).to eq first_template.issue_title\n      end\n\n      scenario 'Text appended.' do\n        visit_new_issue(user)\n        wait_for_ajax\n        expect(page).to have_selector('div#template_area select#issue_template')\n        second_target.select_option\n        wait_for_ajax\n        expect(page).not_to have_selector('#issue_template_confirm_to_replace_dialog')\n        expect(issue_description.value).not_to eq first_template.description\n        expect(issue_subject.value).not_to eq first_template.issue_title\n        expect(issue_subject.value).to eq \"#{first_template.issue_title} #{second_template.issue_title}\"\n        expect(issue_description.value).to eq \"#{first_template.description}\\n\\n#{second_template.description}\"\n      end\n\n      context 'Overwite option is activated' do\n        before do\n          setting = IssueTemplateSetting.find_or_create(project.id)\n          setting.update_attribute(:should_replaced, true)\n        end\n\n        scenario 'Conform window apperead.' do\n          visit_new_issue(user)\n          expect(page).to have_selector('div#template_area select#issue_template')\n          second_target.select_option\n          wait_for_ajax\n          expect(page).to have_selector('#issue_template_confirm_to_replace_dialog')\n          expect(issue_subject.value).not_to eq \"#{first_template.issue_title} #{second_template.issue_title}\"\n          expect(issue_description.value).not_to eq \"#{first_template.description}\\n\\n#{second_template.description}\"\n        end\n\n        scenario 'Conform window not apperead with using cookie.' do\n          visit_new_issue(user)\n\n          # set cookie\n          page.driver.browser.manage.add_cookie(name: 'issue_template_confirm_to_replace_hide_dialog', value: '1')\n          expect(page).to have_selector('div#template_area select#issue_template')\n          second_target.select_option\n          wait_for_ajax\n          expect(page).not_to have_selector('#issue_template_confirm_to_replace_dialog')\n        end\n      end\n    end\n  end\n\n  private\n\n  def visit_new_issue(user)\n    # TODO: If does not user update, authentication is failed. This is workaround.\n    user.update_attribute(:admin, false)\n    log_user(user.login, user.password)\n    visit \"/projects/#{project.identifier}/issues/new\"\n  end\nend\n"
  },
  {
    "path": "spec/features/issue_template_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\nrequire_relative '../rails_helper'\nrequire_relative '../support/login_helper'\n\nRSpec.configure do |c|\n  c.include LoginHelper\nend\n\nfeature 'IssueTemplate', js: true do\n  #\n  # TODO: Change not to use Redmine's fixture but to use Factory...\n  #\n  fixtures :projects,\n           :users,\n           :roles,\n           :members,\n           :member_roles,\n           :issues,\n           :issue_statuses,\n           :trackers,\n           :projects_trackers,\n           :enabled_modules,\n           :enumerations\n\n  given(:role) { Role.find(1) }\n  after do\n    page.execute_script 'window.close();'\n  end\n\n  feature 'Access Redmine top page', js: true do\n    context 'When anonymous ' do\n      scenario 'Link to Global issue template is not displayed.' do\n        visit '/admin'\n        expect(page).not_to have_selector('#admin-menu > ul > li > a.redmine-issue-templates')\n      end\n    end\n\n    context 'When Administrator' do\n      background do\n        log_user('admin', 'admin')\n        visit '/admin'\n      end\n\n      scenario 'Link to Global issue template is displayed.' do\n        expect(page).to have_selector('#admin-menu > ul > li > a.redmine-issue-templates')\n      end\n    end\n  end\n\n  feature 'view fook for issues_sidebar' do\n    given(:issue_template) { FactoryBot.create(:issue_template) }\n    given!(:enabled_module) { FactoryBot.create(:enabled_module) }\n    context 'When user has no priv to use issue template' do\n      background do\n        assign_template_priv(role, remove_permission: :show_issue_templates)\n        log_user('jsmith', 'jsmith')\n        visit '/projects/ecookbook/issues'\n      end\n\n      scenario 'Link to issue template list is not displayed.' do\n        expect(page).not_to have_selector('h3', text: I18n.t('issue_template'))\n      end\n    end\n\n    context 'When user has priv to use issue template' do\n      background do\n        assign_template_priv(role, add_permission: :show_issue_templates)\n        log_user('jsmith', 'jsmith')\n        visit '/projects/ecookbook/issues'\n      end\n\n      scenario 'Link to issue template list is displayed.' do\n        expect(page).to have_selector('h3', text: I18n.t('issue_template'))\n      end\n    end\n  end\n\n  feature 'create template' do\n    given!(:enabled_module) { FactoryBot.create(:enabled_module) }\n    given(:issue_template_title) { page.find('#issue_template_title') }\n    given(:issue_template_description) { page.find('#issue_template_description') }\n\n    context 'When user has priv to  issue template' do\n      given(:create_button) { page.find('#issue_template-form > input[type=\"submit\"]') }\n      given(:error_message) { page.find('#errorExplanation') }\n      background do\n        assign_template_priv(role, add_permission: :edit_issue_templates)\n        log_user('jsmith', 'jsmith')\n        visit '/projects/ecookbook/issue_templates/new'\n\n        issue_template_title.set('')\n        issue_template_description.set('Test for issue template description')\n        create_button.click\n        sleep(0.2)\n      end\n\n      scenario 'create template failed' do\n        expect(error_message).to have_content('Title cannot be blank')\n      end\n    end\n\n    # enable buildin-fields\n    context 'Setting \"enable_builtin_fields\" is true' do\n      background do\n        # enable_builtin_fields\n        Setting.send 'plugin_redmine_issue_templates=', 'enable_builtin_fields' => 'true'\n        assign_template_priv(role, add_permission: :edit_issue_templates)\n        log_user('jsmith', 'jsmith')\n        visit '/projects/ecookbook/issue_templates/new'\n      end\n\n      scenario 'form for builtin_fields are shown' do\n        select 'Bug', from: 'issue_template[tracker_id]'\n\n        wait_for_ajax\n        expect(page).to have_selector('div#json_generator')\n        expect(page).to have_selector('select#field_selector')\n\n        select 'Priority', from: 'field_selector'\n        expect(page).to have_select('Value', options: IssuePriority.active.pluck(:name))\n\n        select 'Watcher', from: 'field_selector'\n        expect(page).to have_select('Value', options:  ['Dave Lopper :3', 'John Smith :2'])\n      end\n    end\n  end\n\n  feature 'Template feature at new issue screen' do\n    given!(:issue_templates) do\n      FactoryBot.create_list(:issue_template, 2, project_id: 1, tracker_id: 1)\n    end\n\n    given!(:named_template) do\n      FactoryBot.create(:issue_template, project_id: 1, tracker_id: 1,\n                                         title: 'Sample Title for rspec', description: 'Sample description for rspec')\n    end\n    given!(:enabled_module) { FactoryBot.create(:enabled_module) }\n\n    background do\n      assign_template_priv(role, add_permission: :show_issue_templates)\n      log_user('jsmith', 'jsmith')\n      visit '/projects/ecookbook/issues/new'\n    end\n\n    scenario 'Template filter is enabled.' do\n      expect(page).to have_selector('div#template_area select#issue_template')\n    end\n\n    scenario 'Template pulldown is enabled.' do\n      expect(page).to have_selector('a#link_template_dialog')\n    end\n\n    context 'Click Template filter popup' do\n      given(:table) { page.find('div#filtered_templates_list table') }\n      given(:titlebar) { page.find('#issue_template_dialog_title') }\n      background do\n        page.find('#link_template_dialog').click\n        sleep(0.2)\n      end\n\n      scenario 'Template filter popup has template list' do\n        expect(table).to have_selector('tbody tr', count: 3)\n      end\n\n      scenario 'popup Template filter' do\n        expect(titlebar).to have_content('Issue template: Bug')\n      end\n\n      context 'Template filtered' do\n        given(:table) { page.find('div#filtered_templates_list table') }\n        given(:input) { page.find('#template_search_filter') }\n        background do\n          input.set('Sample Title for rspec')\n        end\n\n        scenario 'Filtered and should have only one template' do\n          expect(table).to have_selector('tbody tr', count: 1)\n        end\n\n        scenario 'Click filtered link and applied template' do\n          table.find('tbody > tr > td:nth-child(5) > i').click\n          sleep(0.2)\n          description = page.find('#issue_description')\n          expect(description.value).to match 'Sample description for rspec'\n        end\n      end\n    end\n\n    context 'have subproject' do\n      background do\n        template_setting = IssueTemplateSetting.find_or_create(1)\n        template_setting.inherit_templates = true\n        sub_project = Project.find(3)\n        sub_project.inherit_members = true\n        sub_project.enabled_modules << EnabledModule.new(name: 'issue_templates')\n        sub_project.save\n\n        FactoryBot.create(:issue_template, project_id: 3, tracker_id: 1, title: 'template for subproject')\n      end\n\n      scenario 'Select sub project then template for subproject is shown' do\n        sub_project = page.find('#issue_project_id > option[value=\"3\"]')\n\n        expect(page).to have_selector('#issue_template > optgroup > option', count: 3)\n        template_option = page.find('#issue_template > optgroup > option:nth-child(1)')\n        expect(template_option.text).to eq issue_templates.first.title\n\n        sub_project.select_option\n\n        wait_for_ajax\n        template_option = page.find('#issue_template > optgroup > option:nth-child(1)')\n        expect(template_option.text).to eq 'template for subproject'\n      end\n    end\n  end\n\n  feature 'Prevent to append the same template' do\n    given(:expected_title) { 'Sample Title for rspec' }\n    given(:expected_description) { 'Sample description for rspec' }\n\n    given!(:named_template) do\n      FactoryBot.create(:issue_template, project_id: 1, tracker_id: 1,\n                                         title: 'bug template',\n                                         issue_title: expected_title, description: expected_description)\n    end\n\n    given!(:issue_template_setting) do\n      FactoryBot.create(:issue_template_setting, project_id: 1, should_replaced: false)\n    end\n\n    given!(:enabled_module) { FactoryBot.create(:enabled_module) }\n    given(:issue_description) { page.find('#issue_description') }\n    given(:issue_subject) { page.find('#issue_subject') }\n    given(:table) { page.find('div#filtered_templates_list table') }\n\n    # visible template dialog\n    given(:template_dialog) { page.find('#issue_template_dialog', visible: false) }\n\n    background do\n      assign_template_priv(role, add_permission: :show_issue_templates)\n      log_user('jsmith', 'jsmith')\n      visit '/projects/ecookbook/issues/new'\n    end\n\n    context 'Issue has the same title and description with selected template' do\n      background do\n        issue_subject.set(expected_title)\n        issue_description.set(expected_description)\n        page.find('#link_template_dialog').click\n        sleep(0.2)\n        table.find('tbody > tr > td:nth-child(5) > i').click\n        sleep(0.2)\n      end\n\n      scenario 'Title and Description should not be modified' do\n        expect(issue_description.value).to eq expected_description\n        expect(issue_subject.value).to eq expected_title\n\n        # dialog should be closed\n        expect(template_dialog).not_to be_visible\n      end\n    end\n\n    context 'Issue has different title and description with selected template' do\n      background do\n        issue_subject.set('different subject')\n        issue_description.set('different description')\n        page.find('#link_template_dialog').click\n        sleep(0.2)\n        table.find('tbody > tr > td:nth-child(5) > i').click\n        sleep(0.2)\n      end\n\n      scenario 'Title and Description should be appended text' do\n        expect(issue_description.value).to eq \"different description\\n\\n#{expected_description}\"\n        expect(issue_subject.value).to eq \"different subject #{expected_title}\"\n\n        # dialog should be closed\n        expect(template_dialog).not_to be_visible\n      end\n    end\n  end\n\n  feature 'Enabled to revert just after template applied' do\n    given(:issue_description) { page.find('#issue_description') }\n    given(:issue_subject) { page.find('#issue_subject') }\n    given(:expected_title) { 'Sample Title for rspec' }\n    given(:expected_description) { 'Sample description for rspec' }\n\n    given!(:named_template) do\n      FactoryBot.create(:issue_template, project_id: 1, tracker_id: 1,\n                                         title: 'Sample Title for rspec',\n                                         issue_title: 'Sample Title for rspec', description: 'Sample description for rspec')\n    end\n    given!(:enabled_module) { FactoryBot.create(:enabled_module) }\n\n    background do\n      assign_template_priv(role, add_permission: :show_issue_templates)\n      log_user('jsmith', 'jsmith')\n      visit '/projects/ecookbook/issues/new'\n\n      issue_subject.set('Test for revert subject')\n      issue_description.set('Test for revert description')\n\n      select expected_title, from: 'issue_template'\n      sleep(0.2)\n    end\n\n    scenario 'Title and Description should be appended text' do\n      expect(issue_description.value).to eq \"Test for revert description\\n\\n#{expected_description}\"\n      expect(issue_subject.value).to eq \"Test for revert subject #{expected_title}\"\n    end\n\n    scenario 'Click Revert and reverted applied template' do\n      page.find('#revert_template').click\n      expect(issue_description.value).to eq 'Test for revert description'\n      expect(issue_subject.value).to eq 'Test for revert subject'\n    end\n  end\n\n  # builtin fields test\n  feature 'Can apply value to the builtin field' do\n    given(:priority_name) { IssuePriority.active.sample.name }\n    given(:builtin_fields_json_value) do\n      {\n        \"issue_priority_id\": priority_name,\n        \"issue_estimated_hours\": 5\n      }\n    end\n    given(:expected_title) { 'Sample Title for rspec' }\n    given!(:enabled_module) { FactoryBot.create(:enabled_module) }\n    given!(:issue_templates) do\n      FactoryBot.create(:issue_template, title: expected_title,\n                                         project_id: 1, tracker_id: 1, builtin_fields_json: builtin_fields_json_value)\n    end\n    background do\n      # enable_builtin_fields\n      Setting.send 'plugin_redmine_issue_templates=', 'enable_builtin_fields' => 'true'\n\n      assign_template_priv(role, add_permission: :show_issue_templates)\n      log_user('jsmith', 'jsmith')\n      visit '/projects/ecookbook/issues/new'\n\n      select expected_title, from: 'issue_template'\n      sleep(0.2)\n    end\n\n    scenario 'Builtin fields are filled' do\n      expect(page).to have_select('issue[priority_id]', selected: priority_name)\n      expect(page.find('#issue_estimated_hours').value).to eq '5'\n    end\n  end\nend\n"
  },
  {
    "path": "spec/features/update_issue_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\nrequire_relative '../rails_helper'\nrequire_relative '../support/login_helper'\n\nRSpec.configure do |c|\n  c.include LoginHelper\nend\n\nfeature 'Update issue', js: true do\n  given(:user) { FactoryBot.create(:user, :password_same_login, login: 'test-manager', language: 'en', admin: false) }\n  given(:project) { FactoryBot.create(:project_with_enabled_modules) }\n  given(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n  given(:role) { FactoryBot.create(:role, :manager_role) }\n  given(:status) { IssueStatus.create(name: 'open', is_closed: false) }\n  given(:issue_note) { page.find('textarea#issue_notes') }\n\n  background(:all) do\n    Redmine::Plugin.register(:redmine_issue_templates) do\n      settings partial: 'settings/redmine_issue_templates',\n               default: { 'apply_global_template_to_all_projects' => 'false', 'apply_template_when_edit_issue' => 'true' }\n    end\n  end\n\n  background do\n    FactoryBot.create_list(:issue_template, 2, project_id: project.id, tracker_id: tracker.id)\n\n    project.trackers << tracker\n    assign_template_priv(role, add_permission: :show_issue_templates)\n    member = Member.new(project: project, user_id: user.id)\n    member.member_roles << MemberRole.new(role: role)\n    member.save\n\n    priority = IssuePriority.create(\n      name: 'Low',\n      position: 1, is_default: false, type: 'IssuePriority', active: true, project_id: nil, parent_id: nil,\n      position_name: 'lowest'\n    )\n\n    issue = Issue.create(project_id: project.id, tracker_id: tracker.id,\n                         author_id: user.id,\n                         priority: priority,\n                         subject: 'test_create',\n                         status_id: status.id,\n                         description: 'IssueTest#test_create')\n    issue.save\n  end\n\n  scenario 'Click edit link with apply_template_when_edit_issue flag', js: true do\n    Setting.send 'plugin_redmine_issue_templates=', 'apply_template_when_edit_issue' => 'true'\n    visit_update_issue(user)\n    issue = Issue.last\n    visit \"/issues/#{issue.id}\"\n    page.find('#content > div:nth-child(1) > a.icon.icon-edit').click\n    sleep(0.2)\n    expect(page).to have_selector('div#template_area select#issue_template')\n  end\n\n  scenario 'Click edit link without apply_template_when_edit_issue flag', js: true do\n    Setting.send 'plugin_redmine_issue_templates=', 'apply_template_when_edit_issue' => 'false'\n    visit_update_issue(user)\n    issue = Issue.last\n    visit \"/issues/#{issue.id}\"\n    page.find('#content > div:nth-child(1) > a.icon.icon-edit').click\n    sleep(0.2)\n    expect(page).not_to have_selector('div#template_area select#issue_template')\n  end\n\n  context 'Have note template' do\n    given(:expected_note_description) { 'Note Template desctiption' }\n\n    before do\n      NoteTemplate.create(project_id: project.id, tracker_id: tracker.id,\n                          name: 'Note Template name', description: expected_note_description, enabled: true)\n    end\n\n    scenario 'Template for note exists' do\n      visit_update_issue(user)\n      issue = Issue.last\n      visit \"/issues/#{issue.id}\"\n      page.find('#content > div:nth-child(1) > a.icon.icon-edit').click\n      sleep(0.2)\n      expect(page).to have_selector('a#link_template_issue_notes_dialog')\n\n      page.find('a#link_template_issue_notes_dialog').click\n      wait_for_ajax\n\n      page.find('#template_issue_notes_dialog table tr:first-child > td:nth-child(3) > a.template-update-link').click\n      wait_for_ajax\n\n      expect(issue_note.value).to eq expected_note_description\n    end\n  end\n\n  context 'Have global note template' do\n    given(:expected_note_description) { 'Global Note Template desctiption' }\n    before do\n      Setting.send 'plugin_redmine_issue_templates=', 'apply_global_template_to_all_projects' => 'false'\n      GlobalNoteTemplate.create(tracker_id: tracker.id, name: 'Global Note Template name', visibility: 2,\n                                description: expected_note_description, enabled: true)\n    end\n\n    scenario 'No template for note' do\n      visit_update_issue(user)\n      issue = Issue.last\n      visit \"/issues/#{issue.id}\"\n      page.find('#content > div:nth-child(1) > a.icon.icon-edit').click\n      sleep(0.2)\n      expect(page).not_to have_selector('a#link_template_issue_notes_dialog')\n    end\n\n    context 'apply_global_template_to_all_projects is true' do\n      before do\n        Setting.send 'plugin_redmine_issue_templates=', 'apply_global_template_to_all_projects' => 'true'\n      end\n\n      scenario 'One Global template for note' do\n        visit_update_issue(user)\n        issue = Issue.last\n        visit \"/issues/#{issue.id}\"\n        page.find('#content > div:nth-child(1) > a.icon.icon-edit').click\n        sleep(0.2)\n        expect(page).to have_selector('a#link_template_issue_notes_dialog')\n\n        page.find('a#link_template_issue_notes_dialog').click\n\n        wait_for_ajax\n        template_rows = page.find('div#template_issue_notes_dialog table > tbody')\n\n        expect(page).to have_selector('div#template_issue_notes_dialog')\n        expect(template_rows).to have_selector('tr:first-child > td:nth-child(3) > a.template-global')\n\n        template_rows.find('tr:first-child > td:nth-child(3) > a.template-global.template-update-link').click\n        wait_for_ajax\n\n        expect(issue_note.value).to eq expected_note_description\n      end\n    end\n  end\n\n  private\n\n  def visit_update_issue(user)\n    user.update_attribute(:admin, false)\n    log_user(user.login, user.login)\n  end\nend\n"
  },
  {
    "path": "spec/helpers/issue_templates_helper_spec.rb",
    "content": "require_relative '../spec_helper'\n\ndescribe IssueTemplatesHelper do\n  describe '#project_tracker?' do\n    let(:trackers) { FactoryBot.create_list(:tracker, 2, :with_default_status) }\n    let(:project) { FactoryBot.create(:project) }\n    let(:tracker) { trackers.first }\n    subject { helper.project_tracker?(tracker, project) }\n\n    context 'Tracker is associated' do\n      before do\n        project.trackers << tracker\n      end\n      it { is_expected.to be_truthy }\n    end\n    context 'Tracker is not associated' do\n      before do\n        project.trackers << trackers.last\n      end\n      it { is_expected.to be_falsey }\n    end\n  end\n\n  describe '#non_project_tracker_msg' do\n    it { expect(helper.non_project_tracker_msg(true)).to eq '' }\n    it { expect(helper.non_project_tracker_msg(false)).to match('<font class=\"non_project_tracker\">') }\n  end\n\n  describe '#template_target_trackers' do\n    let(:trackers) { FactoryBot.create_list(:tracker, 2, :with_default_status) }\n    let(:project) { FactoryBot.create(:project) }\n    let(:tracker) { trackers.last }\n    let(:template) do\n      FactoryBot.create(:issue_template, tracker_id: tracker.id, project_id: project.id)\n    end\n    subject { helper.template_target_trackers(project, template) }\n    before do\n      project.trackers << trackers.first\n    end\n    it { expect(subject.include?([tracker.name, tracker.id])).to be_truthy }\n    it { expect(subject.length).to eq 2 }\n  end\n\n  describe '#options_for_template_pulldown' do\n    let(:options) do\n      option = Struct.new(:id, :name)\n      [].tap do |options|\n        (0..2).each do |id|\n          options << option.new(id, \"name-#{id}\")\n        end\n      end\n    end\n    subject { helper.options_for_template_pulldown(options) }\n    it { expect(subject).to match('<option id=\"0\" name=\"name-0\">name-0</option>') }\n  end\nend\n"
  },
  {
    "path": "spec/models/global_issue_template_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\n\ndescribe GlobalIssueTemplate do\n  describe '#valid?' do\n    let(:instance) { GlobalIssueTemplate.new(tracker_id: tracker.id, title: 'sample') }\n    let(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n    subject { instance.valid? }\n\n    it 'related_link in invalid format' do\n      instance.related_link = 'non url format string'\n      is_expected.to be_falsey\n      expect(instance.errors.messages.key?(:related_link)).to be_truthy\n    end\n\n    it 'related_link in valid format' do\n      instance.related_link = 'https://valid.example.com/links.html'\n      is_expected.to be_truthy\n    end\n  end\n\n  describe '#builtin_fields_json' do\n    let(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n    let(:global_issue_template) do\n      create(:global_issue_template, tracker_id: tracker.id)\n    end\n    subject { global_issue_template.update(builtin_fields_json: object) }\n\n    context 'Data is a valid hash' do\n      let(:object) { { 'key': 'value', 'foo': 'bar' } }\n      it { is_expected.to be_truthy }\n    end\n\n    context 'Data is not a valid hash' do\n      let(:object) { [1, 2, 3] }\n      it { expect { subject }.to raise_error(ActiveRecord::SerializationTypeMismatch) }\n    end\n  end\nend\n"
  },
  {
    "path": "spec/models/global_note_template_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\n\ndescribe GlobalNoteTemplate do\n  let(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n  let!(:note_template) { FactoryBot.create(:global_note_template, tracker_id: tracker.id, position: 1) }\n  let!(:note_template2) { FactoryBot.create(:global_note_template, tracker_id: tracker.id, position: 2) }\n  let!(:note_template3) { FactoryBot.create(:global_note_template, tracker_id: tracker.id, position: 3) }\n\n  it 'Instance of GlobalNoteTemplate' do\n    expect(note_template).to be_an_instance_of(GlobalNoteTemplate)\n  end\n\n  describe 'scope: .sorted' do\n    it 'do sort by position correctly' do\n      expect([note_template, note_template2, note_template3]).to eq GlobalNoteTemplate.sorted\n      expect(GlobalNoteTemplate.sorted.first).to eq note_template\n    end\n\n    it 'do sort by position correctly after update' do\n      note_template.update(position: GlobalNoteTemplate.count)\n      expect(GlobalNoteTemplate.sorted).to eq [note_template2, note_template3, note_template]\n    end\n  end\nend\n"
  },
  {
    "path": "spec/models/issue_template_setting_spec.rb",
    "content": "require_relative '../spec_helper'\n\ndescribe IssueTemplateSetting do\n  let(:project) { FactoryBot.create(:project) }\n  let(:independent_projects) { FactoryBot.create_list(:project, 2) }\n  let(:subject) do\n    FactoryBot.create(:issue_template_setting,\n                       project_id: project.id)\n  end\n  let(:child_projects) { Project.where(parent_id: project.id) }\n\n  shared_examples 'expected for apply/unapply template' do\n    context 'When no project id' do\n      let(:param) {}\n      it 'Raise Exception if no argument' do\n        expect { subject }.to raise_error(ArgumentError)\n      end\n    end\n\n    context 'When invalid project id' do\n      let(:param) { 0 }\n      it 'Raise  NotFound Exception if not specified valid project' do\n        expect { subject }.to raise_error(ActiveRecord::RecordNotFound)\n      end\n    end\n\n    context 'When valid project id' do\n      let(:param) { project.id }\n      before do\n        FactoryBot.create(:issue_template_setting, project_id: project.id)\n      end\n\n      it 'instance method is called' do\n        expect_any_instance_of(IssueTemplateSetting).to receive(:update_inherit_template_of_child_projects)\n        subject\n      end\n    end\n  end\n\n  describe '.apply_template_to_child_projects' do\n    let(:subject) { IssueTemplateSetting.apply_template_to_child_projects(param) }\n    it_behaves_like 'expected for apply/unapply template'\n  end\n\n  describe '.unapply_template_from_child_projects' do\n    let(:subject) { IssueTemplateSetting.unapply_template_from_child_projects(param) }\n    it_behaves_like 'expected for apply/unapply template'\n  end\n\n  describe '#child_projects' do\n    context 'no child projects' do\n      it 'return zero count' do\n        expect(subject.child_projects.count).to eq 0\n      end\n    end\n\n    context 'has child projects' do\n      before do\n        FactoryBot.create_list(:project, 2, parent_id: project.id)\n      end\n      it 'return right number of all the child projects' do\n        expect(subject.child_projects.count).to eq 2\n      end\n\n      context 'has descendent projects' do\n        before do\n          FactoryBot.create_list(:project, 2, parent_id: child_projects.last.id)\n        end\n\n        it 'return right number of all the descendent projects' do\n          expect(subject.child_projects.count).to eq 4\n        end\n\n        it('return zero count after breaking off relationship') do\n          expect(subject.child_projects.count).to eq 4\n          child_projects.each do |c|\n            c.set_parent!(nil)\n          end\n          subject.project.reload\n          expect(subject.child_projects.count).to eq 0\n        end\n      end\n    end\n  end\n\n  describe '#apply_template_to_child_projects' do\n    let(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n    let!(:enabled_module) { FactoryBot.create(:enabled_module, project_id: project.id) }\n    let!(:issue_templates) do\n      FactoryBot.create_list(:issue_template, 4, project_id: project.id, tracker_id: tracker.id, enabled_sharing: true)\n    end\n    let(:child_project_template_settings) do\n      IssueTemplateSetting.where(project_id: child_projects.ids)\n    end\n\n    before do\n      FactoryBot.create_list(:project, 4, parent_id: project.id)\n      # change to enabled issue template module\n      child_projects.each do |c|\n        FactoryBot.create(:enabled_module, project_id: c.id)\n        IssueTemplateSetting.find_or_create(c.id)\n        c.trackers = [tracker]\n        c.save\n      end\n      subject.apply_template_to_child_projects\n    end\n\n    it \"child project inhetits parent's template\" do\n      expect(child_project_template_settings.first.inherit_templates).to be_truthy\n    end\n\n    it 'child project can use inherit template' do\n      expect(child_project_template_settings.first.get_inherit_templates.count).to eq 4\n    end\n\n    it 'All the child projects setting should be true' do\n      expect(child_project_template_settings.pluck(:inherit_templates).include?(false)).to be_falsey\n    end\n\n    it 'All the child projects setting should be false after unapplied' do\n      subject.unapply_template_from_child_projects\n      values_inherit_templates = child_project_template_settings.pluck(:inherit_templates)\n      expect(values_inherit_templates.include?(false)).to be_truthy\n      expect(values_inherit_templates.uniq.count).to eq 1\n    end\n  end\nend\n"
  },
  {
    "path": "spec/models/issue_template_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\n\ndescribe IssueTemplate do\n  let(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n  let(:project) { FactoryBot.create(:project) }\n  let(:issue_template) { FactoryBot.create(:issue_template, tracker_id: tracker.id, project_id: project.id) }\n  let(:issue_template2) { FactoryBot.create(:issue_template, tracker_id: tracker.id, project_id: project.id) }\n  it 'Instance of IssueTemplate' do\n    expect(issue_template).to be_an_instance_of(IssueTemplate)\n  end\n\n  describe 'scope .orphaned' do\n    subject { IssueTemplate.orphaned.count }\n    before do\n      # Remove related tracker\n      issue_template.tracker.delete\n    end\n    it { is_expected.to eq 1 }\n  end\n\n  describe 'scope: .sorted' do\n    it 'do sort by position correctly' do\n      expect([issue_template, issue_template2]).to eq [issue_template2, issue_template].sort\n      expect(IssueTemplate.sorted.first).to eq issue_template\n    end\n\n    it 'do sort by position correctly after update' do\n      issue_template.update(position: issue_template2.position + 100)\n      expect(IssueTemplate.sorted.first).to eq issue_template2\n    end\n  end\n\n  describe '#destroy' do\n    subject { issue_template.destroy }\n    context 'Template is enabled' do\n      before do\n        issue_template.enabled = true\n        issue_template.save\n      end\n      it 'Failed to remove with invalid message' do\n        expect(Rails.logger).to receive(:info).with(/\\[Destroy\\] IssueTemplate: /).never\n        subject\n        expect(issue_template.errors.present?).to be_truthy\n      end\n    end\n    context 'Template is disabled' do\n      before { issue_template.enabled = false }\n      it 'Removed and log message is generated' do\n        expect(Rails.logger).to receive(:info).with(/\\[Destroy\\] IssueTemplate: /).once\n        subject\n        expect(issue_template.errors.present?).to be_falsey\n      end\n    end\n  end\n\n  describe '#valid?' do\n    let(:instance) { described_class.new(tracker_id: tracker.id, project_id: project.id, title: 'sample') }\n    subject { instance.valid? }\n\n    it 'related_link in invalid format' do\n      instance.related_link = 'non url format string'\n      is_expected.to be_falsey\n      expect(instance.errors.messages.key?(:related_link)).to be_truthy\n    end\n\n    it 'related_link in valid format' do\n      instance.related_link = 'https://valid.example.com/links.html'\n      is_expected.to be_truthy\n    end\n  end\n\n  describe '#builtin_fields_json' do\n    subject { issue_template.update(builtin_fields_json: object) }\n\n    context 'Data is a valid hash' do\n      let(:object) { { 'key': 'value', 'foo': 'bar' } }\n      it { is_expected.to be_truthy }\n    end\n\n    context 'Data is not a valid hash' do\n      let(:object) { [1, 2, 3] }\n      it { expect { subject }.to raise_error(ActiveRecord::SerializationTypeMismatch) }\n    end\n  end\nend\n"
  },
  {
    "path": "spec/models/note_visible_role_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\n\ndescribe NoteVisibleRole do\n  let(:instance) { described_class.new }\n  it 'Instance of NoteVisibleRole' do\n    expect(instance).to be_an_instance_of(NoteVisibleRole)\n  end\nend\n"
  },
  {
    "path": "spec/rails_helper.rb",
    "content": "# frozen_string_literal: true\n\n# This file is copied to spec/ when you run 'rails generate rspec:install'\nENV['RAILS_ENV'] ||= 'test'\nrequire File.expand_path('../../../config/environment', __dir__)\n\nabort('The Rails environment is running in production mode!') if Rails.env.production?\nrequire 'spec_helper'\nrequire 'rspec/rails'\n\nActiveRecord::Migration.maintain_test_schema!\n\nRSpec.configure do |config|\n  config.fixture_path = \"#{::Rails.root}/test/fixtures\"\n  config.include FactoryBot::Syntax::Methods\n\n  config.before :suite do\n    require 'selenium-webdriver'\n    if ENV['DRIVER'] == 'headless'\n      Capybara.register_driver :headless_chrome do |app|\n        capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(\n          #\n          # NOTE: When using Chrome headress, default window size is 800x600.\n          # In case window size is not specified, Redmine renderes its contents with responsive mode.\n          #\n          chromeOptions: { args: %w[headless disable-gpu window-size=1280,800] }\n        )\n        options = Selenium::WebDriver::Chrome::Options.new\n        options.add_option('w3c', false)\n        Capybara::Selenium::Driver.new(\n          app,\n          browser: :chrome,\n          desired_capabilities: capabilities,\n          options: options\n        )\n      end\n    else\n      Capybara.register_driver :headless_chrome do |app|\n        capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(\n          chromeOptions: { args: %w[window-size=1280,800] }\n        )\n        options = Selenium::WebDriver::Chrome::Options.new\n        options.add_option('w3c', false)\n        Capybara::Selenium::Driver.new(\n          app,\n          browser: :chrome,\n          desired_capabilities: capabilities,\n          options: options\n        )\n      end\n    end\n  end\n\n  config.before :each, type: :feature do\n    Capybara.javascript_driver = :headless_chrome\n    Capybara.current_driver = :headless_chrome\n    Capybara.default_max_wait_time = 30\n  end\n\n  config.include Capybara::DSL\n  config.use_transactional_fixtures = false\n  config.infer_spec_type_from_file_location!\n\n  config.filter_rails_from_backtrace!\n\n  require 'database_cleaner'\n  config.before(:suite) do\n    DatabaseCleaner.strategy = :truncation\n    DatabaseCleaner.clean_with(:truncation)\n  end\n\n  config.before(:each) do\n    DatabaseCleaner.start\n  end\n\n  config.after(:each) do\n    DatabaseCleaner.clean\n  end\nend\n"
  },
  {
    "path": "spec/requests/global_note_templates_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\nrequire File.expand_path(File.dirname(__FILE__) + '/../support/controller_helper')\n\nRSpec.configure do |c|\n  c.include ControllerHelper\nend\n\nRSpec.describe 'Global Note Template', type: :request do\n  let(:user) { FactoryBot.create(:user, :password_same_login, login: 'test-manager', language: 'en', admin: true) }\n  let(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n  let(:target_template_name) { 'Global Note template name' }\n  let(:target_template) { GlobalNoteTemplate.last }\n\n  before do\n    # do nothing\n  end\n\n  it 'show global note template list' do\n    login_request(user.login, user.login)\n    get '/global_note_templates'\n    expect(response.status).to eq 200\n\n    get '/global_note_templates/new'\n    expect(response.status).to eq 200\n  end\n\n  it 'create global note template and load' do\n    login_request(user.login, user.login)\n    post '/global_note_templates',\n         params: { global_note_template:\n           { tracker_id: tracker.id, name: target_template_name,\n             description: 'Global Note template description', memo: 'Test memo', enabled: 1 } }\n    expect(response).to have_http_status(302)\n\n    post '/note_templates/load', params: { note_template: { note_template_id: target_template.id, template_type: 'global' } }\n    json = JSON.parse(response.body)\n    expect(target_template.name).to eq(json['note_template']['name'])\n  end\nend\n"
  },
  {
    "path": "spec/requests/note_templates_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire_relative '../spec_helper'\nrequire File.expand_path(File.dirname(__FILE__) + '/../support/controller_helper')\n\nRSpec.configure do |c|\n  c.include ControllerHelper\nend\n\nRSpec.describe 'Note Template', type: :request do\n  let(:user) { FactoryBot.create(:user, :password_same_login, login: 'test-manager', language: 'en', admin: false) }\n  let(:project) { FactoryBot.create(:project_with_enabled_modules) }\n  let(:tracker) { FactoryBot.create(:tracker, :with_default_status) }\n  let(:role) { FactoryBot.create(:role, :manager_role) }\n  let(:target_template) { NoteTemplate.last }\n\n  before do\n    project.trackers << tracker\n    assign_template_priv(role, add_permission: :show_issue_templates)\n    assign_template_priv(role, add_permission: :edit_issue_templates)\n    member = Member.new(project: project, user_id: user.id)\n    member.member_roles << MemberRole.new(role: role)\n    member.save\n  end\n\n  it 'show note template list' do\n    login_request(user.login, user.login)\n    get \"/projects/#{project.identifier}/note_templates\"\n    expect(response.status).to eq 200\n\n    get \"/projects/#{project.identifier}/note_templates/new\"\n    expect(response.status).to eq 200\n  end\n\n  it 'create note template and load' do\n    login_request(user.login, user.login)\n    post \"/projects/#{project.identifier}/note_templates\",\n         params: { note_template:\n           { tracker_id: tracker.id, name: 'Note template name',\n             description: 'Note template description', memo: 'Test memo', enabled: 1 } }\n    expect(response).to have_http_status(302)\n\n    post '/note_templates/load', params: { note_template: { note_template_id: target_template.id } }\n    json = JSON.parse(response.body)\n    expect(target_template.name).to eq(json['note_template']['name'])\n  end\nend\n"
  },
  {
    "path": "spec/spec_helper.rb",
    "content": "require File.expand_path('../../../../config/environment', __FILE__)\nrequire 'rspec/rails'\nrequire 'simplecov'\nrequire 'factory_bot_rails'\nrequire 'database_cleaner'\n\nSimpleCov.coverage_dir('coverage/redmine_issue_templates_spec')\nSimpleCov.start 'rails'\n\nRSpec.configure do |config|\n  config.fixture_path = \"#{::Rails.root}/test/fixtures\"\n  config.use_transactional_fixtures = false\n  config.infer_spec_type_from_file_location!\n  config.include FactoryBot::Syntax::Methods\n  FactoryBot.definition_file_paths = [File.expand_path('../factories', __FILE__)]\n  FactoryBot.find_definitions\n  config.before(:all) do\n    FactoryBot.reload\n  end\n\n  require 'database_cleaner'\n  config.before(:suite) do\n    DatabaseCleaner.strategy = :truncation\n    DatabaseCleaner.clean_with(:truncation)\n  end\n\n  config.before(:each) do\n    DatabaseCleaner.start\n  end\n\n  config.after(:each) do\n    DatabaseCleaner.clean\n  end\nend\n"
  },
  {
    "path": "spec/support/controller_helper.rb",
    "content": "module ControllerHelper\n  # AuthHeader with api key (Ref.http://www.redmine.org/projects/redmine/wiki/Rest_api)\n  def auth_with_user(user)\n    request.headers['X-Redmine-API-Key'] = user.api_key.to_s\n  end\n\n  def clear_token\n    request.headers['X-Redmine-API-Key'] = nil\n  end\n\n  def login_request(login, password)\n    post '/login', params: { username: login, password: password }\n  end\n\n  def assign_template_priv(role, add_permission: nil, remove_permission: nil)\n    return if add_permission.blank? && remove_permission.blank?\n\n    role.add_permission! add_permission if add_permission.present?\n    role.remove_permission! remove_permission if remove_permission.present?\n  end\n\n  shared_context 'As admin' do\n    let(:user) { FactoryBot.create(:user, status: 1, admin: is_admin) }\n    let(:is_admin) { true }\n  end\n\n  shared_context 'Project and Tracler exists' do\n    let(:count) { 4 }\n    let(:trackers) { FactoryBot.create_list(:tracker, 2, :with_default_status) }\n    let(:projects) { FactoryBot.create_list(:project, count) }\n  end\n\n  shared_examples 'Right response' do |status_code|\n    it { expect(response.status).to eq status_code }\n  end\nend\n"
  },
  {
    "path": "spec/support/login_helper.rb",
    "content": "# frozen_string_literal: true\n\nmodule LoginHelper\n  def log_user(login, password)\n    visit '/login'\n\n    within('#login-form form') do\n      fill_in 'username', with: login\n      fill_in 'password', with: password\n      find('input[name=login]').click\n    end\n  end\n\n  def assign_template_priv(role, add_permission: nil, remove_permission: nil)\n    return if add_permission.blank? && remove_permission.blank?\n\n    role.add_permission! add_permission if add_permission.present?\n    role.remove_permission! remove_permission if remove_permission.present?\n  end\n\n  def wait_for_ajax\n    Timeout.timeout(Capybara.default_max_wait_time) do\n      loop until finished_all_ajax_requests?\n    end\n  end\n\n  def finished_all_ajax_requests?\n    page.evaluate_script('jQuery.active').zero?\n  end\nend\n"
  },
  {
    "path": "test/fixtures/global_issue_templates.yml",
    "content": "# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html\r\none:\r\n  id: 1\r\n  \r\n  tracker_id: 1\r\n  \r\n  author_id: 1\r\n\r\n  title: global_title1\r\n\r\n  description: \"global description1\"\r\n\r\n  note: note1\r\n  \r\n  enabled: true\r\n\r\n  position: 1\r\n\r\ntwo:\r\n  id: 2\r\n\r\n  tracker_id: 3\r\n  \r\n  author_id: 1\r\n\r\n  title: titel2\r\n\r\n  description: \"global description2\"\r\n\r\n  note: note2\r\n  \r\n  enabled: false\r\n\r\n  position: 1\r\n  \r\nthree:\r\n  id: 3\r\n\r\n  tracker_id: 2\r\n  \r\n  author_id: 1\r\n\r\n  title: titel3\r\n\r\n  description: \"global description3\"\r\n\r\n  note: note3\r\n  \r\n  enabled: true\r\n\r\n  position: 1\r\n\r\nfour:\r\n  id: 4\r\n\r\n  tracker_id: 1\r\n\r\n  author_id: 1\r\n\r\n  title: titel4\r\n\r\n  description: \"global description4\"\r\n\r\n  note: note4\r\n\r\n  enabled: true\r\n\r\n  position: 2\r\n\r\nfive:\r\n  id: 5\r\n\r\n  tracker_id: 1\r\n\r\n  author_id: 1\r\n\r\n  title: titel5\r\n\r\n  description: \"global description5\"\r\n\r\n  note: note5\r\n\r\n  enabled: true\r\n\r\n  position: 3\r\n"
  },
  {
    "path": "test/fixtures/global_issue_templates_projects.yml",
    "content": "global_issue_templates_projects_001:\r\n  project_id: 1\r\n  global_issue_template_id: 1\r\nglobal_issue_templates_projects_002:\r\n  project_id: 3\r\n  global_issue_template_id: 1"
  },
  {
    "path": "test/fixtures/issue_template_settings.yml",
    "content": "# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html\r\none:\r\n  id: 1\r\n\r\n  project_id: 1\r\n\r\n  help_message: MyText\r\n\r\n  enabled: true\r\n\r\n  inherit_templates: false\r\n\r\ntwo:\r\n  id: 2\r\n\r\n  project_id: 2\r\n\r\n  help_message: MyText\r\n\r\n  enabled: false\r\n\r\n  inherit_templates: false\r\n\r\nthree:\r\n  id: 3\r\n\r\n  project_id: 3\r\n\r\n  help_message: Project3 help\r\n\r\n  enabled: true\r\n\r\n  inherit_templates: false\r\n\r\n"
  },
  {
    "path": "test/fixtures/issue_templates.yml",
    "content": "# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html\r\none:\r\n  id: 1\r\n\r\n  project_id: 1\r\n  \r\n  tracker_id: 1\r\n  \r\n  author_id: 1\r\n\r\n  title: title1\r\n\r\n  description: description1\r\n\r\n  note: note1\r\n  \r\n  enabled: true\r\n  \r\n  position: 1\r\n\r\n  enabled_sharing: true\r\n\r\ntwo:\r\n  id: 2\r\n\r\n  project_id: 1\r\n\r\n  tracker_id: 3\r\n  \r\n  author_id: 1\r\n\r\n  title: titel2\r\n\r\n  description: description2\r\n\r\n  note: note2\r\n  \r\n  enabled: false\r\n\r\n  position: 1\r\n\r\n  enabled_sharing: false\r\n  \r\nthree:\r\n  id: 3\r\n\r\n  project_id: 1\r\n\r\n  tracker_id: 2\r\n  \r\n  author_id: 1\r\n\r\n  title: titel3\r\n\r\n  description: description3\r\n\r\n  note: note3\r\n  \r\n  enabled: true\r\n\r\n  position: 1\r\n  \r\nfour:\r\n  id: 4\r\n\r\n  project_id: 1\r\n\r\n  tracker_id: 1\r\n  \r\n  author_id: 2\r\n\r\n  title: titel4\r\n\r\n  description: description4\r\n\r\n  note: note4\r\n  \r\n  enabled: true   \r\n\r\n  position: 2\r\n\r\nfive:\r\n  id: 5\r\n\r\n  project_id: 1\r\n  \r\n  tracker_id: 1\r\n  \r\n  author_id: 1\r\n\r\n  title: title5\r\n\r\n  description: description5\r\n\r\n  note: note5\r\n  \r\n  enabled: false\r\n\r\n  position: 3\r\n\r\nsix:\r\n  id: 6\r\n\r\n  project_id: 3\r\n\r\n  tracker_id: 1\r\n\r\n  author_id: 1\r\n\r\n  title: title6\r\n\r\n  description: description6\r\n\r\n  note: note5\r\n\r\n  enabled: true\r\n\r\n  position: 3\r\n"
  },
  {
    "path": "test/functional/global_issue_templates_controller_test.rb",
    "content": "require File.expand_path('../test_helper', __dir__)\nrequire 'minitest/autorun'\n\nclass GlobalIssueTemplatesControllerTest < Redmine::ControllerTest\n  fixtures :projects, :users, :trackers,\n           :global_issue_templates,\n           :global_issue_templates_projects\n\n  include Redmine::I18n\n\n  def setup\n    @request.session[:user_id] = 1 # Admin\n    @request.env['HTTP_REFERER'] = '/'\n    # Enabled Template module\n    @project = Project.find(1)\n    @project.enabled_modules << EnabledModule.new(name: 'issue_templates')\n    @project.save!\n  end\n\n  def test_get_index\n    get :index\n    assert_response :success\n  end\n\n  def test_update_template\n    put :update, params: { id: 2, global_issue_template:\n      { description: 'Update Test Global template2' } }\n    assert_response :redirect # show\n    global_issue_template = GlobalIssueTemplate.find(2)\n    assert_redirected_to controller: 'global_issue_templates',\n                         action: 'show', id: global_issue_template.id\n    assert_equal 'Update Test Global template2', global_issue_template.description\n  end\n\n  def test_update_template_with_empty_title\n    put :update, params: { id: 2, global_issue_template:\n      { title: '' } }\n    assert_response :success\n    global_issue_template = GlobalIssueTemplate.find(2)\n    assert_not_equal '', global_issue_template.title\n\n    # render :show\n    assert_select 'h2.global_issue_template', \"#{l(:global_issue_templates)}: ##{global_issue_template.id}\"\n    # Error message should be displayed.\n    assert_select 'div#errorExplanation', { count: 1, text: /Title cannot be blank/ }, @response.body.to_s\n  end\n\n  def test_destroy_template\n    post :destroy, params: { id: 2 }\n    assert_redirected_to controller: 'global_issue_templates',\n                         action: 'index'\n    assert_raise(ActiveRecord::RecordNotFound) { GlobalIssueTemplate.find(2) }\n  end\n\n  def test_new_template\n    get :new\n    assert_response :success\n  end\n\n  def test_create_template\n    num = GlobalIssueTemplate.count\n    post :create, params: { global_issue_template: { title: 'Global Template newtitle for creation test', note: 'Global note for creation test',\n                                                     description: 'Global Template description for creation test',\n                                                     tracker_id: 1, enabled: 1, author_id: 1 } }\n\n    template = GlobalIssueTemplate.order('id DESC').first\n    assert_response :redirect\n\n    assert_equal(num + 1, GlobalIssueTemplate.count)\n\n    assert_not_nil template\n    assert_equal('Global Template newtitle for creation test', template.title)\n    assert_equal('Global note for creation test', template.note)\n    assert_equal('Global Template description for creation test', template.description)\n    assert_equal(1, template.tracker.id)\n    assert_equal(1, template.author.id)\n  end\n\n  def test_create_template_fail\n    num = GlobalIssueTemplate.count\n\n    # when title blank, validation bloks to save.\n    post :create, params: { global_issue_template: { title: '', note: 'note',\n                                                     description: 'description', tracker_id: 1, enabled: 1,\n                                                     author_id: 1 } }\n\n    assert_response :success\n    assert_equal(num, GlobalIssueTemplate.count)\n\n    # render :new\n    assert_select 'h2', text: \"#{l(:issue_templates)} / #{l(:button_add)}\"\n    # Error message should be displayed.\n    assert_select 'div#errorExplanation', { count: 1, text: /Title cannot be blank/ }, @response.body.to_s\n  end\n\n  def test_preview_template\n    get :preview, params: { global_issue_template: { description: 'h1. Global Test data.' } }\n    assert_select 'h1', /Global Test data\\./, @response.body.to_s\n  end\nend\n"
  },
  {
    "path": "test/functional/issue_templates_controller_test.rb",
    "content": "require File.expand_path('../test_helper', __dir__)\nrequire 'minitest/autorun'\n\nclass IssueTemplatesControllerTest < Redmine::ControllerTest\n  fixtures :projects, :users, :roles, :trackers, :members, :member_roles, :enabled_modules,\n           :issue_templates,\n           :projects_trackers\n\n  include Redmine::I18n\n\n  def setup\n    @request.session[:user_id] = 2\n    @request.env['HTTP_REFERER'] = '/'\n    # Enabled Template module\n    @project = Project.find(1)\n    @project.enabled_modules << EnabledModule.new(name: 'issue_templates')\n    @project.save!\n\n    # Set default permission: show template\n    Role.find(1).add_permission! :show_issue_templates\n  end\n\n  def test_get_index_with_non_existing_project\n    # set non existing project\n    get :index, params: { project_id: 100 }\n    assert_response 404\n  end\n\n  def test_get_index_without_show_permission\n    Role.find(1).remove_permission! :show_issue_templates\n    get :index, params: { project_id: 1 }\n    assert_response 403\n  end\n\n  def test_get_index_with_normal\n    get :index, params: { project_id: 1 }\n    assert_response :success\n  end\n\n  def test_show_with_non_existing_template\n    get :show, params: { id: 100, project_id: 1 }\n    assert_response 404\n  end\n\n  def test_show_return_json_hash\n    get :load, params: { project_id: 1, template_id: 1 }\n    assert_response :success\n    assert_equal 'description1', json_response['issue_template']['description']\n  end\n\n  def test_show_return_json_hash_of_global\n    get :load, params: { project_id: 1, template_id: 1, template_type: 'global' }\n    assert_response :success\n    assert_equal 'global description1', json_response['global_issue_template']['description']\n  end\n\n  def test_show_render_pulldown\n    get :set_pulldown, params: { project_id: 1, issue_tracker_id: 1 }\n    tracker = Tracker.find(1)\n    assert_response :success\n    assert_select \"optgroup[label=#{tracker.name}]\"\n  end\n\n  def test_new_template\n    edit_permission\n\n    get :new, params: { project_id: 1, author_id: 2 }\n    assert_response :success\n  end\n\n  def test_create_template\n    edit_permission\n\n    num = IssueTemplate.count\n    post :create, params: {\n      issue_template: { title: 'newtitle', note: 'note',\n                        description: 'description', tracker_id: 1, enabled: 1, author_id: 3 },\n      project_id: 1\n    }\n\n    template = IssueTemplate.last\n    assert_response :redirect\n\n    assert_equal(num + 1, IssueTemplate.count)\n\n    assert_not_nil template\n    assert_equal('newtitle', template.title)\n    assert_equal('note', template.note)\n    assert_equal('description', template.description)\n    assert_equal(1, template.project.id)\n    assert_equal(1, template.tracker.id)\n    assert_equal(2, template.author.id)\n\n    assert_nil(template.checklist_json)\n    assert_equal([], template.checklist)\n  end\n\n  def test_create_template_with_empty_title\n    edit_permission\n\n    num = IssueTemplate.count\n\n    # when title blank, validation bloks to save.\n    post :create, params: { issue_template:\n      { title: '', note: 'note', description: 'description', tracker_id: 1, enabled: 1, author_id: 1 }, project_id: 1 }\n\n    assert_response :success\n    assert_equal(num, IssueTemplate.count)\n\n    # render :new\n    assert_select 'h2', text: \"#{l(:issue_templates)} / #{l(:button_add)}\"\n    # Error message should be displayed.\n    assert_select 'div#errorExplanation', { count: 1, text: /Title cannot be blank/ }, @response.body.to_s\n  end\n\n  def test_preview_template\n    edit_permission\n\n    get :preview, params: { issue_template: { description: 'h1. Test data.' } }\n    assert_select 'h1', /Test data\\./, @response.body.to_s\n  end\n\n  def test_update_template\n    edit_permission\n\n    put :update, params: { id: 2,\n                           issue_template: { description: 'Update Test template2' },\n                           project_id: 1 }\n    project = Project.find 1\n    assert_response :redirect # show\n    issue_template = IssueTemplate.find(2)\n    assert_redirected_to controller: 'issue_templates',\n                         action: 'show', id: issue_template.id, project_id: project\n    assert_equal 'Update Test template2', issue_template.description\n  end\n\n  def test_update_template_with_empty_title\n    edit_permission\n    num = IssueTemplate.count\n\n    # when title blank, validation bloks to save.\n    put :update, params: { id: 2,\n                           issue_template: { title: '' },\n                           project_id: 1 }\n\n    assert_response :success\n    assert_equal(num, IssueTemplate.count)\n\n    # render :show\n    assert_select 'h2.issue_template', \"#{l(:issue_templates)}: #2\"\n    assert_select 'div#edit-issue_template'\n    # Error message should be displayed.\n    assert_select 'div#errorExplanation', { count: 1, text: /Title cannot be blank/ }, @response.body.to_s\n  end\n\n  def test_delete_template_fail_if_enabled\n    edit_permission\n\n    post :destroy, params: { id: 1, project_id: 1 }\n    project = Project.find 1\n    assert_redirected_to controller: 'issue_templates',\n                         action: 'show', project_id: project, id: 1\n    assert_match(/Only disabled template can be destroyed/, flash[:error])\n  end\n\n  def test_delete_template_success_if_disabled\n    edit_permission\n\n    template = IssueTemplate.find(1)\n    template.enabled = false\n    template.save\n    post :destroy, params: { id: 1, project_id: 1 }\n    project = Project.find 1\n    assert_redirected_to controller: 'issue_templates',\n                         action: 'index', project_id: project\n    assert_raise(ActiveRecord::RecordNotFound) { IssueTemplate.find(1) }\n  end\n\n  def test_edit_template_failed_with_project_id_and_safe_attributes\n    edit_permission\n\n    put :update, params: { id: 2,\n                           issue_template: { description: 'Update Test template2',\n                                             project_id: 2, author_id: 2 },\n                           project_id: 1 }\n    project = Project.find 1\n    assert_response :redirect # show\n    issue_template = IssueTemplate.find(2)\n    assert_redirected_to controller: 'issue_templates',\n                         action: 'show', id: issue_template.id, project_id: project\n    assert_equal 'Update Test template2', issue_template.description\n    assert_equal(1, issue_template.project.id)\n    assert_equal(1, issue_template.author.id)\n  end\n\n  def test_child_project_index\n    child_project_setup\n\n    get :index, params: { project_id: 1 }\n    assert_response :success\n    assert_select 'h2', text: l(:issue_template).to_s, count: 1\n    assert !@response.body.match(%r{<h3>#{l(:label_inherited_templates)}</h3>})\n\n    get :index, params: { project_id: 3 }\n    assert_response :success\n    assert_select 'h2', text: l(:issue_template).to_s, count: 1\n    assert !@response.body.match(%r{<h3>#{l(:label_inherited_templates)}</h3>})\n  end\n\n  def test_child_project_index_with_inherit_templates\n    child_project_setup\n\n    setting = IssueTemplateSetting.find(3)\n    setting.inherit_templates = true\n    setting.save!\n\n    get :index, params: { project_id: 3 }\n    assert_response :success\n    assert_select 'h2', text: l(:issue_template).to_s, count: 1\n  end\n\n  def test_child_project_render_pulldown_with_parent_template\n    child_project_setup\n\n    setting = IssueTemplateSetting.find(3)\n    setting.inherit_templates = true\n    setting.save!\n    tracker = Tracker.find(1)\n    get :set_pulldown, params: { project_id: 3, issue_tracker_id: 1 }\n    assert_select \"optgroup[label='#{tracker.name}']\"\n    assert_select 'option[value=\"1\"]'\n    assert_select 'option[class=\"global\"]'\n  end\n\n  def json_response\n    ActiveSupport::JSON.decode @response.body\n  end\n\n  def child_project_setup\n    @project = Project.find(3)\n    @project.enabled_modules << EnabledModule.new(name: 'issue_templates')\n    @project.save!\n\n    # do as Admin\n    @request.session[:user_id] = 1\n  end\n\n  def edit_permission\n    Role.find(1).add_permission! :edit_issue_templates\n  end\nend\n"
  },
  {
    "path": "test/functional/issue_templates_settings_controller_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire File.expand_path('../test_helper', __dir__)\n\nclass IssueTemplatesSettingsControllerTest < Redmine::ControllerTest\n  fixtures :projects,\n           :users,\n           :roles,\n           :members,\n           :member_roles,\n           :enabled_modules,\n           :issue_templates\n\n  def setup\n    # Enabled Template module\n    enabled_module = EnabledModule.new\n    enabled_module.project_id = 1\n    enabled_module.name = 'issue_templates'\n    enabled_module.save\n\n    # set default user to 2 (as member)\n    @request.session[:user_id] = 2\n    Role.find(1).add_permission! :manage_issue_templates\n\n    @project = Project.find(1)\n  end\n\n  def test_update_without_permission\n    Role.find(1).remove_permission! :manage_issue_templates\n    post :edit, params: { project_id: @project,\n                          settings: { enabled: '1', help_message: 'Hoo', inherit_templates: true },\n                          setting_id: 1, tab: 'issue_templates' }\n    assert_response 403\n  end\n\n  def test_update_with_permission_and_non_project\n    post :edit, params: { project_id: 'dummy',\n                          settings: { enabled: '1', help_message: 'Hoo', inherit_templates: true },\n                          setting_id: 1 }\n    assert_response 404\n  end\n\n  def test_update_with_permission_and_redirect\n    post :edit, params: { project_id: @project,\n                          settings: { enabled: '1', help_message: 'Hoo', inherit_templates: true },\n                          setting_id: 1 }\n    assert_response :redirect\n    assert_redirected_to controller: 'issue_templates_settings',\n                         action: 'index', project_id: @project\n  end\n\n  def test_preview_template_setting\n    post :preview, params: { settings: { help_message: 'h1. Preview test.',\n                                         enabled: '1' },\n                             project_id: @project }\n    assert_select 'h1', /Preview test\\./, @response.body.to_s\n  end\n\n  def test_create_template_setting\n    IssueTemplateSetting.delete_all\n\n    post :edit, params: { project_id: @project,\n                          settings: { enabled: '1', help_message: 'Hoo', inherit_templates: true },\n                          setting_id: 1 }\n    assert_response :redirect\n    assert_redirected_to controller: 'issue_templates_settings',\n                         action: 'index', project_id: @project\n  end\nend\n"
  },
  {
    "path": "test/functional/issues_controller_test.rb",
    "content": "require File.expand_path(File.dirname(__FILE__) + '/../test_helper')\nrequire 'issues_controller'\n\n# Test for view hooks.\nclass IssuesControllerTest < Redmine::ControllerTest\n  fixtures :projects,\n           :users,\n           :roles,\n           :members,\n           :member_roles,\n           :issues,\n           :issue_statuses,\n           :versions,\n           :trackers,\n           :projects_trackers,\n           :issue_categories,\n           :enabled_modules,\n           :enumerations,\n           :attachments,\n           :workflows,\n           :custom_fields,\n           :custom_values,\n           :custom_fields_trackers,\n           :time_entries,\n           :journals,\n           :journal_details,\n           :issue_templates\n\n  def setup\n    User.current = nil\n    enabled_module = EnabledModule.new\n    enabled_module.project_id = 1\n    enabled_module.name = 'issue_templates'\n    enabled_module.save\n    roles = Role.all\n    roles.each do |role|\n      role.permissions << :show_issue_templates\n      role.remove_permission! :edit_issue_templates\n      role.save\n    end\n    @request.session[:user_id] = 2\n    @project = Project.find(1)\n  end\n\n  def test_index_without_project\n    get :index\n    assert_response :success\n    assert_select 'h3', count: 0, text: I18n.t('issue_template')\n  end\n\n  def test_index\n    get :index, params: { project_id: @project.id }\n    assert_response :success\n    assert_select 'div#template_area select#issue_template', false,\n                  'Action index should not contain template select pulldown.'\n    assert_select 'h3', text: I18n.t('issue_template')\n    assert_select 'a', { href: \"/projects/#{@project}/issue_templates/new\" }, false\n  end\n\n  def test_index_with_edit_permission\n    Role.find(1).add_permission! :edit_issue_templates\n    get :index, params: { project_id: @project.id }\n    assert_select 'h3', text: I18n.t('issue_template')\n    assert_select 'a', href: \"/projects/#{@project}/issue_templates/new\"\n  end\n\n  def test_new\n    get :new, params: { project_id: 1 }\n    assert_response :success\n    assert_select 'div#template_area select#issue_template'\n  end\n\n  # NOTE: When copy, template area should not be displayed.\n  def test_copy\n    get :new, params: { project_id: 1, copy_from: 1 }\n    assert_response :success\n    assert_select 'div#template_area', false\n  end\n\n  def test_new_without_project\n    get :new\n    assert_response :success\n    assert_select 'div#template_area select#issue_template', true\n  end\nend\n"
  },
  {
    "path": "test/functional/projects_controller_test.rb",
    "content": "require File.expand_path(File.dirname(__FILE__) + '/../test_helper')\nrequire 'projects_controller'\n\nclass ProjectsControllerTest < Redmine::ControllerTest\n  fixtures :projects, :users, :roles, :members, :member_roles,\n           :trackers, :projects_trackers, :enabled_modules\n  def setup\n    # as project admin\n    @request.session[:user_id] = 2\n    Role.find(1).add_permission! :show_issue_templates\n    # Enabled Template module\n    @project = Project.find(1)\n    @project.enabled_modules << EnabledModule.new(name: 'issue_templates')\n    @project.save!\n  end\n\n  def test_settings\n    get :show, params: { id: 1 }\n    assert_response :success\n    assert_select '#main-menu > ul > li > a.issue-templates'\n  end\nend\n"
  },
  {
    "path": "test/integration/layout_test.rb",
    "content": "require File.expand_path(File.dirname(__FILE__) + '/../test_helper')\n\nclass LayoutTest < Redmine::IntegrationTest\n  fixtures :projects, :trackers, :issue_statuses, :issues,\n           :enumerations, :users,\n           :projects_trackers,\n           :roles,\n           :member_roles,\n           :members,\n           :enabled_modules,\n           :workflows,\n           :issue_templates\n\n  def test_issue_template_not_visible_when_module_off\n    # module -> disabled\n    log_user('admin', 'admin')\n    post '/projects/ecookbook/modules',\n         params: { enabled_module_names: ['issue_tracking'], commit: 'Save', id: 'ecookbook' }\n\n    get '/projects/ecookbook/issues'\n    assert_response :success\n    assert_select 'h3', count: 0, text: I18n.t('issue_template')\n\n    get '/projects/ecookbook/issues/new'\n    assert_select 'div#template_area select#issue_template', 0\n  end\n\n  def test_issue_template_visible_when_module_on\n    # module -> enabled\n    log_user('admin', 'admin')\n    post '/projects/ecookbook/modules',\n         params: { enabled_module_names: %w[issue_tracking issue_templates],\n                   commit: 'Save', id: 'ecookbook' }\n\n    get '/projects/ecookbook/issues'\n    assert_response :success\n  end\nend\n"
  },
  {
    "path": "test/test_helper.rb",
    "content": "begin\n  require 'simplecov'\n  require 'simplecov-rcov'\nrescue LoadError => ex\n  puts <<-\"EOS\"\n  This test should be called only for redmine issue template test.\n    Test exit with LoadError --  #{ex.message}\n  Please move redmine_issue_templates/Gemfile.local to redmine_issue_templates/Gemfile\n  and run bundle install if you want to to run tests.\n  EOS\n  exit\nend\n\nif ENV['JENKINS'] == 'true'\n  SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter\n  true\nelse\n  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([SimpleCov::Formatter::HTMLFormatter])\nend\n\nSimpleCov.coverage_dir('coverage/redmine_issue_templates_test')\nSimpleCov.start do\n  add_filter do |source_file|\n    # report this plugin only.\n    !source_file.filename.include?('plugins/redmine_issue_templates') || !source_file.filename.end_with?('.rb')\n  end\nend\n\nrequire File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper')\nActiveRecord::FixtureSet.create_fixtures(File.dirname(__FILE__) + '/fixtures/',\n                                         %i[issue_templates issue_template_settings\n                                            global_issue_templates global_issue_templates_projects])\n"
  },
  {
    "path": "test/unit/global_issue_templates_test.rb",
    "content": "require File.expand_path('../test_helper', __dir__)\n\nclass GlobalIssueTemplatesTest < ActiveSupport::TestCase\n  fixtures :global_issue_templates, :users, :trackers\n\n  def setup\n    @global_issue_template = GlobalIssueTemplate.find(1)\n  end\n\n  def test_truth\n    assert_kind_of GlobalIssueTemplate, @global_issue_template\n  end\n\n  def test_template_enabled\n    enabled = @global_issue_template.enabled?\n    assert_equal true, enabled, @global_issue_template.enabled?\n\n    @global_issue_template.enabled = false\n    @global_issue_template.save!\n    enabled = @global_issue_template.enabled?\n    assert_equal false, enabled, @global_issue_template.enabled?\n  end\n\n  def test_sort_by_position\n    a = GlobalIssueTemplate.new(title: 'Template4', position: 2, tracker_id: 1)\n    b = GlobalIssueTemplate.new(title: 'Template5', position: 1, tracker_id: 1)\n    assert_equal [b, a], [a, b].sort\n  end\nend\n"
  },
  {
    "path": "test/unit/issue_template_setting_test.rb",
    "content": "require File.expand_path(File.dirname(__FILE__) + '/../test_helper')\n\nclass IssueTemplateSettingTest < ActiveSupport::TestCase\n  fixtures :issue_template_settings, :projects\n\n  def setup\n    @issue_template_setting = IssueTemplateSetting.find(1)\n  end\n\n  def test_truth\n    assert_kind_of IssueTemplateSetting, @issue_template_setting\n  end\n\n  def test_help_message_enabled\n    enable_help = @issue_template_setting.enable_help?\n    assert_equal(true, enable_help)\n    assert_equal(false, !enable_help)\n  end\n\n  def test_duplicate_project_setting\n    templ = IssueTemplateSetting.find_or_create(3)\n    templ.attributes = { enabled: true, help_message: 'Help!' }\n    assert templ.save!, 'Failed to save.'\n\n    # test which has the same proect id\n    templ2 = IssueTemplateSetting.new\n    templ2.attributes = { project_id: 1, enabled: true, help_message: 'Help!' }\n    assert !templ2.save, 'Dupricate project should be denied.'\n  end\n\n  def test_help_message_disabled\n    # load disabled template setting\n    issue_template_setting = IssueTemplateSetting.find(2)\n    enable_help = issue_template_setting.enable_help?\n    assert_equal(false, enable_help)\n  end\n\n  def test_find_template_setting\n    # for Project 6\n    issue_template_setting = IssueTemplateSetting.find_or_create(6)\n    assert_kind_of IssueTemplateSetting, issue_template_setting\n  end\nend\n"
  },
  {
    "path": "test/unit/issue_template_test.rb",
    "content": "require File.expand_path(File.dirname(__FILE__) + '/../test_helper')\n\nclass IssueTemplateTest < ActiveSupport::TestCase\n  fixtures :issue_templates, :projects, :users, :trackers\n\n  def setup\n    @issue_template = IssueTemplate.find(1)\n  end\n\n  def test_truth\n    assert_kind_of IssueTemplate, @issue_template\n  end\n\n  def test_template_enabled\n    enabled = @issue_template.enabled?\n    assert_equal true, enabled, @issue_template.enabled?\n\n    @issue_template.enabled = false\n    @issue_template.save!\n    enabled = @issue_template.enabled?\n    assert_equal false, enabled, @issue_template.enabled?\n  end\n\n  def test_sort_by_position\n    a = IssueTemplate.new(title: 'Template1', position: 2, project_id: 1, tracker_id: 1)\n    b = IssueTemplate.new(title: 'Template2', position: 1, project_id: 1, tracker_id: 1)\n    assert_equal [b, a], [a, b].sort\n  end\n\n  def test_is_default\n    # Reset default data\n    IssueTemplate.update_all(is_default: false)\n    assert !@issue_template.is_default?\n\n    @issue_template.is_default = true\n    @issue_template.save!\n    assert @issue_template.is_default?\n\n    templates = IssueTemplate.search_by_project(1).search_by_tracker(1).not_default\n    templates.each do |template|\n      assert !template.is_default?\n    end\n  end\nend\n"
  },
  {
    "path": "test/unit/note_template_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire File.expand_path(File.dirname(__FILE__) + '/../test_helper')\n\nclass NoteTemplateTest < ActiveSupport::TestCase\n  fixtures :projects, :users, :trackers, :roles\n\n  def setup\n    tracker = Tracker.first\n    params = {\n      author: User.first, project: Project.first,\n      tracker: tracker\n    }.merge(\n      name: \"Note Template name for Tracker #{tracker.name}.\",\n      description: \"Note Template description for Tracker #{tracker.name}.\",\n      memo: \"Note Template memo for Tracker #{tracker.name}.\",\n      enabled: true\n    )\n    @template = NoteTemplate.create(params)\n  end\n\n  def teardown; end\n\n  def test_truth\n    assert_kind_of NoteTemplate, @template\n  end\n\n  def test_template_enabled\n    enabled = @template.enabled?\n    assert_equal true, enabled, @template.enabled?\n\n    @template.enabled = false\n    @template.save!\n    enabled = @template.enabled?\n    assert_equal false, enabled, @template.enabled?\n  end\n\n  def test_sort_by_position\n    a = NoteTemplate.new(name: 'Template1', position: 2, project_id: 1, tracker_id: 1)\n    b = NoteTemplate.new(name: 'Template2', position: 1, project_id: 1, tracker_id: 1)\n    assert_equal [b, a], [a, b].sort\n  end\n\n  def test_visibility_with_success\n    NoteTemplate.delete_all\n    NoteTemplate.create(name: 'Template1', position: 2, project_id: 1, tracker_id: 1,\n                        visibility: 'roles', role_ids: [Role.first.id])\n    a = NoteTemplate.first\n    assert_equal a.visibility_before_type_cast, 1\n\n    a.visibility = 'mine'\n    a.save\n    assert_equal a.visibility_before_type_cast, 0\n  end\n\n  def test_visibility_without_role_ids\n    NoteTemplate.delete_all\n\n    # When enable validation: Raise ActiveRecord::RecordInvalid\n    e = assert_raises ActiveRecord::RecordInvalid do\n      NoteTemplate.create!(name: 'Template1', position: 2, project_id: 1, tracker_id: 1,\n                           visibility: 'roles')\n    end\n\n    # Check error message.\n    assert_equal 'Validation failed: Role ids cannot be blank', e.message\n  end\n\n  def test_visibility_from_mine_to_roles\n    NoteTemplate.delete_all\n    NoteTemplate.create(name: 'Template1', position: 2, project_id: 1, tracker_id: 1,\n                        visibility: 'mine')\n    a = NoteTemplate.first\n    a.visibility = 'roles'\n\n    # When skip validation: Raise: NoteTemplate::NoteTemplateError: Please select at least one role.\n    e = assert_raises NoteTemplate::NoteTemplateError do\n      a.save(validate: false)\n    end\n\n    # Check error message.\n    assert_equal 'Please select at least one role.', e.message\n  end\nend\n"
  }
]