Full Code of tabbyz/chibineko for AI

master 334d18690a05 cached
206 files
229.6 KB
71.0k tokens
130 symbols
1 requests
Download .txt
Showing preview only (298K chars total). Download the full file or copy to clipboard to get everything.
Repository: tabbyz/chibineko
Branch: master
Commit: 334d18690a05
Files: 206
Total size: 229.6 KB

Directory structure:
gitextract_t1ykuj_k/

├── .gitignore
├── .rspec
├── Gemfile
├── LICENSE
├── README.md
├── Rakefile
├── app/
│   ├── assets/
│   │   ├── images/
│   │   │   └── .keep
│   │   ├── javascripts/
│   │   │   ├── application.coffee
│   │   │   ├── dashboards.coffee
│   │   │   ├── data_table.coffee
│   │   │   ├── move_tests.coffee
│   │   │   ├── projects.coffee
│   │   │   ├── static_pages.coffee
│   │   │   ├── team_users.coffee
│   │   │   ├── teams.coffee
│   │   │   ├── test_preview.coffee
│   │   │   ├── tests.coffee
│   │   │   └── validation.coffee
│   │   └── stylesheets/
│   │       ├── application.scss
│   │       ├── bootstrap_overrides.scss
│   │       ├── color.scss
│   │       ├── common.scss
│   │       ├── data_table.scss
│   │       ├── layouts/
│   │       │   ├── navbar.scss
│   │       │   ├── sidebar.scss
│   │       │   └── style.scss
│   │       ├── static_pages/
│   │       │   ├── terms.scss
│   │       │   └── top.scss
│   │       ├── teams/
│   │       │   └── team_users.scss
│   │       ├── tests/
│   │       │   ├── edit_result_label.scss
│   │       │   ├── form.scss
│   │       │   ├── move.scss
│   │       │   ├── show.scss
│   │       │   └── testcase.scss
│   │       ├── toastr_overrides.scss
│   │       └── vendor/
│   │           ├── best_in_place.scss
│   │           ├── bootgrid.scss
│   │           └── ladda.scss
│   ├── controllers/
│   │   ├── application_controller.rb
│   │   ├── concerns/
│   │   │   └── .keep
│   │   ├── dashboard_controller.rb
│   │   ├── projects_controller.rb
│   │   ├── static_pages_controller.rb
│   │   ├── team_users_controller.rb
│   │   ├── teams_controller.rb
│   │   ├── testcases_controller.rb
│   │   ├── tests_controller.rb
│   │   ├── user_settings_controller.rb
│   │   └── users/
│   │       └── registrations_controller.rb
│   ├── helpers/
│   │   ├── application_helper.rb
│   │   ├── dashboard_helper.rb
│   │   ├── projects_helper.rb
│   │   ├── static_pages_helper.rb
│   │   ├── team_users_helper.rb
│   │   ├── teams_helper.rb
│   │   └── tests_helper.rb
│   ├── mailers/
│   │   └── .keep
│   ├── models/
│   │   ├── .keep
│   │   ├── concerns/
│   │   │   └── .keep
│   │   ├── project.rb
│   │   ├── team.rb
│   │   ├── team_user.rb
│   │   ├── test.rb
│   │   ├── testcase.rb
│   │   └── user.rb
│   └── views/
│       ├── dashboard/
│       │   ├── _navbar.html.slim
│       │   └── index.html.slim
│       ├── devise/
│       │   ├── confirmations/
│       │   │   └── new.html.slim
│       │   ├── mailer/
│       │   │   ├── confirmation_instructions.en.html.slim
│       │   │   ├── confirmation_instructions.ja.html.slim
│       │   │   ├── password_change.html.erb
│       │   │   ├── reset_password_instructions.en.html.slim
│       │   │   └── reset_password_instructions.ja.html.slim
│       │   ├── passwords/
│       │   │   └── new.html.slim
│       │   ├── registrations/
│       │   │   └── new.html.slim
│       │   ├── sessions/
│       │   │   └── new.html.slim
│       │   └── shared/
│       │       └── _links.html.erb
│       ├── layouts/
│       │   ├── _dashboard_sidebar.html.slim
│       │   ├── _logo.html.slim
│       │   ├── _main_menu.html.slim
│       │   ├── _navbar.html.slim
│       │   ├── _root_sidebar.html.slim
│       │   ├── _sign_in_link.html.slim
│       │   ├── _sign_out_link.html.slim
│       │   ├── _sign_up_link.html.slim
│       │   ├── _team_sidebar.html.slim
│       │   └── application.html.slim
│       ├── projects/
│       │   ├── _navbar.html.slim
│       │   ├── _new.html.slim
│       │   ├── _save.js.erb
│       │   ├── _settings.html.slim
│       │   ├── create.js.erb
│       │   ├── new.js.erb
│       │   ├── settings.js.erb
│       │   ├── show.html.slim
│       │   └── update.js.erb
│       ├── static_pages/
│       │   ├── terms.html.slim
│       │   └── top.html.slim
│       ├── team_users/
│       │   ├── _index.html.slim
│       │   ├── _save.js.erb
│       │   ├── create.js.erb
│       │   ├── destroy.js.erb
│       │   └── index.js.erb
│       ├── teams/
│       │   ├── _new.html.slim
│       │   ├── _save.js.erb
│       │   ├── _settings.html.slim
│       │   ├── create.js.erb
│       │   ├── new.js.erb
│       │   ├── settings.js.erb
│       │   ├── show.html.slim
│       │   └── update.js.erb
│       ├── tests/
│       │   ├── _alert.html.slim
│       │   ├── _cheatsheet.en.html.slim
│       │   ├── _cheatsheet.ja.html.slim
│       │   ├── _description.html.slim
│       │   ├── _form.html.slim
│       │   ├── _move.html.slim
│       │   ├── _navbar.html.slim
│       │   ├── _result_label.html.slim
│       │   ├── _table_toolbar.html.slim
│       │   ├── _testcase.html.slim
│       │   ├── bulk_destroy.js.erb
│       │   ├── bulk_move.js.erb
│       │   ├── create.js.erb
│       │   ├── description.js.erb
│       │   ├── edit.html.slim
│       │   ├── move.js.erb
│       │   ├── new.html.slim
│       │   ├── result_label.js.erb
│       │   ├── show.csv.ruby
│       │   ├── show.html.slim
│       │   ├── update.js.erb
│       │   └── update_result_label.js.erb
│       └── user_settings/
│           ├── _modal.html.slim
│           ├── edit.js.erb
│           └── update.js.erb
├── bin/
│   ├── bundle
│   ├── rails
│   ├── rake
│   └── setup
├── circle.yml
├── config/
│   ├── application.rb
│   ├── boot.rb
│   ├── database.yml
│   ├── environment.rb
│   ├── environments/
│   │   ├── development.rb
│   │   ├── production.rb
│   │   └── test.rb
│   ├── i18n-js.yml
│   ├── initializers/
│   │   ├── action_mailer.rb
│   │   ├── assets.rb
│   │   ├── backtrace_silencers.rb
│   │   ├── cookies_serializer.rb
│   │   ├── devise.rb
│   │   ├── filter_parameter_logging.rb
│   │   ├── inflections.rb
│   │   ├── mime_types.rb
│   │   ├── session_store.rb
│   │   ├── time_formats.rb
│   │   └── wrap_parameters.rb
│   ├── locales/
│   │   ├── devise.en.yml
│   │   ├── devise.ja.yml
│   │   ├── devise_view.en.yml
│   │   ├── devise_view.ja.yml
│   │   ├── en.yml
│   │   ├── ja.yml
│   │   ├── js.en.yml
│   │   ├── js.ja.yml
│   │   ├── terms.en.yml
│   │   └── terms.ja.yml
│   ├── mailer.yml.example
│   ├── routes.rb
│   └── secrets.yml
├── config.ru
├── db/
│   ├── migrate/
│   │   ├── 20151224022612_devise_create_users.rb
│   │   ├── 20151224030646_create_teams.rb
│   │   ├── 20151225045046_create_projects.rb
│   │   ├── 20151225141534_create_tests.rb
│   │   ├── 20151226051709_create_testcases.rb
│   │   ├── 20160103121144_add_column_to_user.rb
│   │   ├── 20160109162956_create_team_users.rb
│   │   └── 20160319072222_add_created_at_index_to_test.rb
│   ├── schema.rb
│   └── seeds.rb
├── lib/
│   ├── assets/
│   │   └── .keep
│   └── tasks/
│       └── .keep
├── log/
│   └── .keep
├── public/
│   ├── 404.en.html
│   ├── 404.ja.html
│   ├── 422.en.html
│   ├── 422.ja.html
│   ├── 500.en.html
│   ├── 500.ja.html
│   ├── error.css
│   ├── javascripts/
│   │   └── translations.js
│   ├── maintenance.html
│   └── robots.txt
├── spec/
│   ├── factories/
│   │   ├── testcases.rb
│   │   └── tests.rb
│   ├── models/
│   │   ├── test_spec.rb
│   │   └── testcase_spec.rb
│   ├── rails_helper.rb
│   └── spec_helper.rb
└── vendor/
    └── assets/
        ├── javascripts/
        │   ├── .keep
        │   └── jquery.readyselector.js
        └── stylesheets/
            └── .keep

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Ignore bundler config.
/.bundle
/vendor/bundle

# Ignore mailer config.
/config/mailer.yml

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal

# Ignore all logfiles and tempfiles.
/log/*.log
/tmp

# Ignore other unneeded files.
doc/
*.swp
*~
.project
.DS_Store
.idea
.secret

================================================
FILE: .rspec
================================================
--color
--require spec_helper


================================================
FILE: Gemfile
================================================
source 'https://rubygems.org'

ruby '2.3.0'

gem 'rails', '4.2.4'
gem 'slim-rails', '~> 3.0.0'
gem 'sass-rails', '~> 5.0'

# JavaScript
gem 'i18n-js', '~> 2.1.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1', '>= 4.1.1'
gem 'therubyracer', platforms: :ruby
gem 'jquery-rails'
gem 'jbuilder', '~> 2.4', '>= 2.4.1'
gem 'gon', '~> 6.0', '>= 6.0.1'

# Other
gem 'bootstrap-sass', '~> 3.3', '>= 3.3.6'
gem 'font-awesome-rails', '~> 4.5', '>= 4.5.0.1'
gem 'bcrypt', '~> 3.1', '>= 3.1.11'
gem 'devise', '~> 3.5', '>= 3.5.6'
gem 'best_in_place', '~> 3.1'
gem 'rails_autolink', '~> 1.1', '>= 1.1.6'
gem 'http_accept_language', '~> 2.0', '>= 2.0.5'
gem 'browser-timezone-rails', github: 'kbaum/browser-timezone-rails'
gem 'turnout', '~> 2.2', '>= 2.2.1'
gem 'actionview-encoded_mail_to', '~> 1.0', '>= 1.0.7'
gem 'momentjs-rails', '~> 2.11'
gem 'kaminari', '~> 0.16.3'

group :development, :test do
  gem 'byebug'
  gem 'web-console', '~> 3.0'
  gem 'spring'
  gem 'bullet'
  gem 'rspec-rails'
  gem 'factory_girl_rails'
  gem 'shoulda-matchers'
end

group :development do
  gem 'sqlite3'
  gem "letter_opener_web"
end

group :production do
  gem 'rails_12factor'
  gem 'pg'
end


================================================
FILE: LICENSE
================================================
Copyright 2016 SHIFT, Inc. All rights reserved.

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2016 SHIFT, Inc. All rights reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

================================================
FILE: README.md
================================================
# Chibineko
[![CircleCI](https://circleci.com/gh/tabbyz/chibineko.svg?style=shield)](https://circleci.com/gh/tabbyz/chibineko)
[![License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)

**Chibineko** is a simple test supporting tool specializing in the management of manual tests.  
It is hosted on [https://chibineko.jp](https://chibineko.jp).


## Screenshot
### Top page
![screenshot_top](https://cloud.githubusercontent.com/assets/15026812/13838533/3930fb0a-ec58-11e5-87d2-07a22a808347.png)

### Execute a test
![screenshot_execute_test](https://cloud.githubusercontent.com/assets/15026812/13838537/3ac1d7fa-ec58-11e5-8d04-5e0a50cfb08e.png)

### Create a test
![screenshot_create_test](https://cloud.githubusercontent.com/assets/15026812/13838540/3cb37fd2-ec58-11e5-92b3-1aa43d3cb41e.png)


## Quick Start
### Install Chibineko on Heroku

Clone the repo

```console
$ git clone git@github.com:tabbyz/chibineko.git
$ cd chibineko
```

Create a app at Heroku

```console
$ heroku create NAME_FOR_YOUR_APP
```

Push an app to Heroku

```console
$ git push heroku master
```

Initialization of database

```console
$ heroku run rake db:migrate
$ heroku run rake db:seed
```

Set the environment variable

```console
$ heroku config:add SECRET_KEY_BASE=`rake secret`
```

Open your Chibineko and sign in with your credentials

```console
$ heroku open
```

Your username is `test@example.com` and your password is `test` as well.


### Configure Email

You must have email settings to the user registration.

Create a configuration file

```console
$ cp config/mailer.yml.example config/mailer.yml
```

```yaml
# For example, if you want to use Gmail as the SMTP server.

production:
  default_url_options:
    host: "example.com"
  delivery_method: :smtp
  smtp_settings:
    enable_starttls_auto: true
    address: "smtp.gmail.com"
    port: 587
    domain: "example.com"
    authentication: "plain"
    user_name: "<yourname>@gmail.com"
    password: "<yourpassword>"
```

Remove it from `.gitignore`

```yaml
config/mailer.yml  # Remove
```

To commit the changes

```console
$ git add .
$ git commit -m "Configure Email"
```

Push an app to Heroku

```console
$ git push heroku master
```


## Contributing
1. Fork it
1. Create your feature branch (`git checkout -b my-new-feature`)
1. Commit your changes (`git commit -am 'Add some feature'`)
1. Push to the branch (`git push origin my-new-feature`)
1. Create new Pull Request


## License
See [LICENSE](LICENSE).  
© SHIFT, Inc. All Rights Reserved.


================================================
FILE: Rakefile
================================================
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require File.expand_path('../config/application', __FILE__)

Rails.application.load_tasks


================================================
FILE: app/assets/images/.keep
================================================


================================================
FILE: app/assets/javascripts/application.coffee
================================================
#= require jquery
#= require jquery_ujs
#= require jquery.cookie
#= require jstz
#= require browser_timezone_rails/set_time_zone
#= require bootstrap-sprockets
#= require best_in_place
#= require Sortable.min
#= require toastr.min
#= require ladda/spin.min
#= require ladda/ladda.min
#= require ladda/ladda.jquery.min
#= require jquery.overlay.min
#= require jquery.bootgrid.min
#= require perfect-scrollbar.jquery.min
#= require moment
#= require moment/ja
#= require jquery.readyselector
#= require i18n
#= require i18n/translations
#= require_tree .

$(document).ready ->
  $("[data-toggle='popover']").popover({ container: "body" })
  $("[data-toggle='tooltip']").tooltip({ container: "body" })
  $(".dropdown-toggle").dropdown()
  $(".best_in_place").best_in_place()
  $(".carousel").carousel()
  $(".hover-scroll").perfectScrollbar()

  $(document).on "shown.bs.modal", (e) ->
    $("[autofocus]", e.target).focus()

  $(document).on "click", ".collapse-btn", (e) ->
    if $(this).hasClass("collapsed")
      $(this).text(I18n.t("js.common.collapse.expand"))
    else
      $(this).text(I18n.t("js.common.collapse.close"))

================================================
FILE: app/assets/javascripts/dashboards.coffee
================================================


================================================
FILE: app/assets/javascripts/data_table.coffee
================================================
$(document).ready ->
  # Bootgrid settings
  $(".data-table").on("initialized.rs.jquery.bootgrid", (e) ->
    $(".table-toolbar").hide().appendTo(".actionBar")
  ).on("loaded.rs.jquery.bootgrid", (e) ->
    $(".table-toolbar").hide()
  ).on("selected.rs.jquery.bootgrid deselected.rs.jquery.bootgrid", (e, rows) ->
    count = $(".bootgrid-table tr.active").length
    if count == 0
      $(".table-toolbar").hide()
    else
      $(".table-toolbar").show()
      $(".table-toolbar .selected-count").text("#{count} #{I18n.t('js.tests.toolbar.selected')}")
  ).bootgrid
    columnSelection: false,
    rowCount: -1,
    selection: true,
    multiSelect: true,
    converters: {
      date: {
        from: (value) -> return moment(value)
        to: (value) -> return moment(value).locale(I18n.locale).format("ll")
      },
    },
    formatters: {
      title: (column, row) -> return "<a href='/t/#{row.slug.trim()}'>#{row.title}</a>"
    },
    labels: {
      loading: I18n.t("js.bootgrid.loading"),
      noResults: I18n.t("js.bootgrid.no_results"),
      search: I18n.t("js.bootgrid.search"),
    },
    templates: {
      infos: "",
      select: "<input name='select[]' type={{ctx.type}} class='select-box' value={{ctx.value}}>"
    }

  # Bulk destroy action
  $(document).on "click", ".bulk-destroy-btn", ->
    if !confirm(I18n.t("js.common.messages.delete_confirm"))
      return false

    tests = []
    for e in $(".bootgrid-table tr.active")
      tests.push $(e).data("row-id")
    
    $.ajax
      url: "/t/bulk_destroy"
      type: 'PATCH'
      dataType: 'script'
      data: $.param({
        tests: tests
      })

  # Bulk move action
  $(document).on "click", ".bulk-move-btn", ->
    project = $(this).data("project-id")
    tests = []
    for e in $(".bootgrid-table tr.active")
      tests.push $(e).data("row-id")
    
    $.ajax
      url: "/t/bulk_move"
      type: 'PATCH'
      dataType: 'script'
      data: $.param({
        tests: tests,
        project: project
      })

================================================
FILE: app/assets/javascripts/move_tests.coffee
================================================
$(".tests.show").ready ->
  
  $(document).on "click", ".move-test-modal .clickable", ->
    $(".project-list .clickable.active").removeClass("active")
    $(this).addClass("active")

    project_id = $(this).attr("data-project-id")
    $(".selected-id-field").val(project_id)

================================================
FILE: app/assets/javascripts/projects.coffee
================================================


================================================
FILE: app/assets/javascripts/static_pages.coffee
================================================
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/


================================================
FILE: app/assets/javascripts/team_users.coffee
================================================
$(".projects, .teams, .tests").ready ->
# ==================================================
# Function
# ==================================================
  preSearchUser = null
  searchUser = (team, email) ->
    clearTimeout(preSearchUser)
    preSearchUser = setTimeout (-> 
      ajaxSearchUser(team, email)
    ), 500


  ajaxSearchUser = (team, email) ->
    btn = $(".ladda-button").ladda()
    label = btn.find(".ladda-label")
    
    $.ajax
      url: "/teams/#{team}/team_users/ajax_search_user"
      type: 'GET'
      dataType: 'json'
      data: $.param({
        email: email
      })
      beforeSend: (jqXHR, settings) ->
        label.text(I18n.t("js.team_sidebar.edit_members.search_user"))
        btn.ladda("start")
      error: (jqXHR, textStatus, errorThrown) ->
        console.log "AJAX Error: #{textStatus}"
        btn.ladda("stop")
        label.text(I18n.t("js.team_sidebar.edit_members.unknown_error"))
        btn.prop("disabled", true)
      success: (data, textStatus, jqXHR) ->
        if data
          label.text(I18n.t("js.team_sidebar.edit_members.add_user"))
          btn.ladda("stop")
          btn.prop("disabled", false)
        else
          label.text(I18n.t("js.team_sidebar.edit_members.not_found"))
          btn.ladda("stop")
          btn.prop("disabled", true)


# ==================================================
# Event
# ==================================================
  $(document).on "keyup", "#new_team_user #email", ->
    email = $(this).val()
    team = $("#team_name").val()
    searchUser(team, email)

================================================
FILE: app/assets/javascripts/teams.coffee
================================================


================================================
FILE: app/assets/javascripts/test_preview.coffee
================================================
$(".tests.new, .tests.edit").ready ->
# ==================================================
# Function
# ==================================================
  caseTag = (markdown) ->
    tag = ""
    array = markdown.split(/\r\n|\r|\n/)
    for line in array
      line = escapeHtml(line)
      switch caseType(line)
        when "heading"
          lv = caseHeadingLevel(line)
          body = caseBody(line)
          
          if tag == ""
            tag += "<div class='testcase-group'>"
          else if lv == 1
            tag += "</div><div class='testcase-group'>" if lv == 1
          
          tag += """
            <div class="tr heading heading-level-#{lv}">
              <div class="td body">
                #{body}
              </div>
            </div>
          """
        when "testcase"
          tag += "<div class='testcase-group'>" if tag == ""
            
          body = caseBody(line)
          tag += """
            <div class="tr testcase">
              <div class="td number"></div>
              <div class="td body">
                #{body}
              </div>
            </div>
          """

    tag = "<div class='testcase-list'>" + tag + "</div></div>"
    

  caseHeadingLevel = (text) ->
    return -1 if text == ""

    text = text.trim()
    if text.substr(0, 1) == "#"
      text.match(/^#*/)[0].length
    else
      0


  caseType = (text) ->
    switch caseHeadingLevel(text)
      when -1 then "blank"
      when 0 then "testcase"
      else "heading"


  caseBody = (text) ->
    switch caseType(text)
      when "heading"
        text.match(/^(#*)(.*)/)[2]
      when "testcase"
        r = text.match(/(.*)(,\s?\[.*\])/)
        if r then r[1] else text


  preUpdatePreview = null
  updatePreview = () ->
    clearTimeout(preUpdatePreview)
    preUpdatePreview = setTimeout (-> 
      e = $("#test_markdown")
      if e.length
        if markdown = e.val()
          tag = caseTag(markdown)
          $(".test-preview-content").empty()
          $(".test-preview-content").append(tag)
          $(".test-preview-content").show()
          $(".test-cheatsheet").hide()
        else
          $(".test-preview-content").hide()
          $(".test-cheatsheet").show()
    ), 200

  escapeHtml = (text) ->
    text.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")


# ==================================================
# Event
# ==================================================
  updatePreview()

  $(document).on "keyup", "#test_markdown", ->
    updatePreview()

  # $(document).on "scroll", "#test_markdown", ->  # TODO: Doesn't work
  $("#test_markdown").scroll ->
    syncScroll($(this))

  $("#test_markdown").overlay( {
    match: /^#.*|\n#.*/g,
    css: {"background-color": "#DDD"}
  })

  # Leave this page
  $("#test_markdown").change ->
    $(window).on "beforeunload", ->
      return I18n.t("js.tests.new.messages.unsaved_changes")

  $("input[type=submit]").click ->
    $(window).off("beforeunload")


# TODO: To local methods
@syncScroll = (e) ->
  source = e
  target = $(".test-preview-content")
  sourceScrollMax = source.get(0).scrollHeight - source.get(0).offsetHeight
  targetScrollMax = target.get(0).scrollHeight - target.get(0).offsetHeight
  scrollRatio = source.scrollTop()/ sourceScrollMax
  target.scrollTop(targetScrollMax * scrollRatio)

================================================
FILE: app/assets/javascripts/tests.coffee
================================================
$(".tests.show").ready ->
# ==================================================
# Function
# ==================================================
  countAll = () ->
    $(".result-btn").size()


  countLabel = (label) ->
    count = 0
    for e in $(".result-btn")
      count += 1 if $(e).text() == label
    count


  updateProgressBar = () ->
    transition = "width 0.5s ease"
    count = countAll()

    for text in gon.resultLabelTexts
      color = gon.resultLabels[text]
      ratio = countLabel(text) / count * 100
      $(".progress-animation .progress-bar[data-result-text='#{text}']").css({
        width: "#{ratio}%",
        WebkitTransition: transition,
        MozTransition: transition,
        MsTransition: transition,
        OTransition: transition,
        transition: transition
      })


  updateProgressCount = () ->
    tag = """
    <table class='tableX table-condensedX progress-count-list'>
    <tbody>
    """
    total = countAll()

    for text in gon.resultLabelTexts
      count = countLabel(text)
      ratio = (count / total * 100).toFixed(1)
      color = gon.resultLabels[text]
      tag += """
      <tr>
        <td><span class='label color-#{color}'>#{text}</span></td>
        <td><strong>#{count}</strong></td>
        <td>(#{ratio}%)</td>
      </tr>
      """

    tag += """
    <tr class='count-total'>
      <td>#{I18n.t("js.tests.navbar.total")}</td>
      <td><strong>#{total}</strong></td>
      <td></td>
    </tr>
    </tbody>
    </table>
    """

    $(".progress-count").attr("data-content", tag)


  removeColorClass = (element) ->
    element.removeClass (idx, css) ->
      return (css.match(/\bcolor-\S+/g) || []).join(' ')


  setResult = (btn, label) ->
    dropdownBtn = btn.next()

    removeColorClass(btn)
    removeColorClass(dropdownBtn)
    btn.addClass("color-#{gon.resultLabels[label]}")
    dropdownBtn.addClass("color-#{gon.resultLabels[label]}")

    btn.text(label)


  nextResultLabel = (currentLabel) ->
    idx = $.inArray(currentLabel, gon.resultLabelTexts)
    if idx == gon.resultLabelTexts.length - 1
      gon.resultLabelTexts[0]
    else
      gon.resultLabelTexts[idx + 1]


  prePostResult = null
  postResult = (caseId, result) ->
    clearTimeout(prePostResult)
    prePostResult = setTimeout (-> 
      ajaxPostResult(caseId, result)
    ), 300


  ajaxPostResult = (caseId, result) ->
    $.ajax
      url: "#{gon.test.slug}/cases/#{caseId}"
      type: 'PATCH'
      dataType: 'json'
      data: $.param({
        testcase: { result: result }
      })
      error: (jqXHR, textStatus, errorThrown) ->
        toastr.warning(I18n.t("js.tests.show.errors.conflict"), I18n.t("js.tests.show.errors.please_reload"))
        # console.log "Ajax Error: #{textStatus}"
      success: (data, textStatus, jqXHR) ->
        # console.log "Ajax Successful: #{data}"


# ==================================================
# Event
# ==================================================
  updateProgressBar()
  updateProgressCount()

  # Color picker
  $(document).on "click", ".color-picker .color-item", ->
    radio = $(this).prev()
    color = radio.val()

    popover = $(this).parents(".popover")
    triggerElement = popover.prev()
    removeColorClass(triggerElement)
    triggerElement.addClass("color-#{color}")
    triggerElement.val(color)


  # Use default label
  $(document).on "click", ".user-default-result-label", ->
    modalBody = $(this).parents(".modal-body")
    table = modalBody.find("table")
    tableFooter = modalBody.find(".table-footer")

    if $(this).is(":checked")
      table.hide()
      tableFooter.hide()
    else
      table.show()
      tableFooter.show()


  # Remove result label
  $(document).on "click", ".delete-result-label-icon", ->
    # Check item count
    tbody = $(this).parents("tbody")
    if tbody.find("tr").size() == 1
      alert(I18n.t("js.tests.edit_result_label.errors.too_short"))
      return

    # Remove item
    tr = $(this).parents("tr")
    tr.remove()


  # Add result label
  $(document).on "click", ".add-result-label-icon", ->
    table = $(this).parent(".table-footer").prev("table")
    tbody = table.children("tbody")
    tr = tbody.find("tr:first").clone()

    # Check item count
    if tbody.find("tr").size() == 9
      alert(I18n.t("js.tests.edit_result_label.errors.too_long"))
      return

    # Reset value
    textInput = tr.find(".result-label-text > input")
    textInput.val("")
    colorInput = tr.find(".result-label-color > input")
    removeColorClass(colorInput)
    colorInput.addClass("color-white")
    
    # Add Item
    tbody.append(tr)
    $(".select-color").popover({
      html : true, 
      content: $(".popover-content-template").html()
    })


  $(document).on "click", ".result-btn", ->
    label = nextResultLabel($(this).text().trim())
    btn = $(this)
    setResult(btn, label)
    postResult(btn.data("case-id"), label)
    updateProgressBar()
    updateProgressCount()


  $(document).on "click", ".result-item", ->
    groupEle = $(this).closest(".result-btn-group")[0]
    btn = $(groupEle).children(".result-btn")
    label = $(this).text().trim()
    setResult(btn, label)
    postResult(btn.data("case-id"), label)
    updateProgressBar()
    updateProgressCount()


  $(document).on "blur", ".testcase-list .note input", ->
    $(this).parents(".best_in_place").attr("data-original-title", $(this).val())


  $(document).on "ajax:error", ".best_in_place", () ->
    toastr.warning(I18n.t("js.tests.show.errors.conflict"), I18n.t("js.tests.show.errors.please_reload"))


  $(document).on "click", ".js-collapse-btn", ->
    heading = $(this).closest(".tr")
    headingLv = heading.data("heading-level")
    isCollapsed = heading.hasClass("collapsed")

    tr = heading.next(".tr")
    while tr.length == 1
      if tr.hasClass("testcase")
        if isCollapsed
          tr.show()
        else
          tr.hide()
        tr = tr.next(".tr")

      else if tr.hasClass("heading")
        if tr.data("heading-level") > headingLv
          if isCollapsed
            tr.removeClass("collapsed")
          else
            tr.addClass("collapsed")

          tr = tr.next(".tr")
        else
          break

    heading.toggleClass("collapsed")


  $(document).on "click", ".js-collapse-all-btn", ->
    for heading in $(".heading")
      $(heading).addClass("collapsed")
    for testcase in $(".testcase")
      $(testcase).hide()

    $(this).hide()
    $(".js-expand-all-btn").show()


  $(document).on "click", ".js-expand-all-btn", ->
    for heading in $(".heading")
      $(heading).removeClass("collapsed")
    for testcase in $(".testcase")
      $(testcase).show()

    $(this).hide()
    $(".js-collapse-all-btn").show()

================================================
FILE: app/assets/javascripts/validation.coffee
================================================
$(document).ready ->
  $(document).on "keydown", ".form-control.validation", (e) ->
    if (e.keyCode != 13)
      $(this).popover("destroy")


  $(document).on "ajax:beforeSend", "form", (e, xhr, settings) ->
    # console.log "ajax:beforeSend"


  $(document).on "ajax:success", "form", (e, data, status, xhr) ->
    # console.log "ajax:success"


  $(document).on "ajax:error", "form", (e, xhr, status, error) ->
    # console.log("ajax:error")
    errors = $.parseJSON(xhr.responseText)
    form = $(e.currentTarget)
    name = form.find(".form-control").attr("name")
    model = name.match(/^(.*)\[.*\]$/)[1]

    for k, v of errors
      field = $("##{model}_#{k}")
      msg = v
      group = field.parent(".form-group")

      if group.find(".form-control-feedback").length == 0
        group.addClass("has-error has-feedback")
        field.popover({ content: msg, placement: "bottom", trigger: "manual" }).popover("show")
        popover = group.children(".popover")
        popover.addClass("error")
        popover.css("left", 0)

      group.find(".popover-content").text(msg)

      btn = group.nextAll(".ladda-button:first")
      btn.ladda().ladda("stop")

  
  $(document).on "ajax:complete", "form", (e, xhr, status) ->
    # console.log("complete")

================================================
FILE: app/assets/stylesheets/application.scss
================================================
/*
 *= require_tree .
 *= require_self
 */

@import "bootstrap-sprockets";
@import "bootstrap";
@import "bootstrap_overrides";
@import "color";
@import "toastr.min";
@import "perfect-scrollbar.min";
@import "toastr_overrides";
@import "ladda-themeless.min";
@import "jquery.bootgrid.min";
@import "font-awesome";
@import "vendor/*";

================================================
FILE: app/assets/stylesheets/bootstrap_overrides.scss
================================================
a {
  &:hover, &:focus {
    text-decoration: none;
  }
}

textarea {
  resize: none;
}

.btn, .form-control {
  border-radius: 2px;
}

button.btn.ladda-button {
  &:focus {
    outline: none;
  }
}

.btn-link {
  &:hover, &:focus {
    text-decoration: none;
    outline: 0;
  }
}

.modal-xs, .modal-sm {
  margin: 100px auto;
}

.modal-xs {
  width: 300px;

  .modal-footer {
    padding: 15px;
  }
}

.modal-sm {
  width: 450px;
}

.modal-dialog {
  .modal-content {
    border-radius: 0;

    .modal-header {
      border-bottom: none;
    }

    .modal-body {
      padding: 10px 30px 30px;
    }

    .modal-footer {
      border-top: none;
    }
  }
}

.dropdown-menu {
  .dropdown-header {
    padding: 8px 12px 4px 12px;

    &:first-child {
      padding-top: 4px;
    }
  }

  .divider {
    margin: 4px 0;
  }
}


// TODO:
.navbar-nav > li {
  float: left;
}

.navbar-nav {
  margin: 0;
}

.navbar-nav .open .dropdown-menu {
  background-color: #FFF;
}

// TODO:
.navbar-right {
  float: right !important;
}

================================================
FILE: app/assets/stylesheets/color.scss
================================================
// http://www.materialui.co/colors
// background-color:        400
// background-color(hover): 500
// border-color:            600

.color-red {
  background-color: #F44336;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #E53935;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #C62828;
  }
}

.color-pink {
  background-color: #E91E63;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #D81B60;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #AD1457;
  }
}

.color-purple {
  background-color: #9C27B0;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #8E24AA;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #6A1B9A;
  }
}

.color-deeppurple {
  background-color: #673AB7;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #5E35B1;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #4527A0;
  }
}

.color-indigo {
  background-color: #3F51B5;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #3949AB;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #283593;
  }
}

.color-blue {
  background-color: #2196F3;
  color: #FFF;
  outline: 0;

  &.btn:hover, &.btn:focus {
    background-color: #1E88E5;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #1565C0;
  }
}

.color-cyan {
  background-color: #00BCD4;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #00ACC1;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #00838F;
  }
}

.color-teal {
  background-color: #009688;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #00897B;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #00695C;
  }
}

.color-green, .color-primary {
  background-color: #4CAF50;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #43A047;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #2E7D32;
  }
}

.color-lightgreen {
  background-color: #8BC34A;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #7CB342;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #558B2F;
  }
}

.color-lime {
  background-color: #CDDC39;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #C0CA33;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #9E9D24;
  }
}

.color-yellow {
  background-color: #FFEB3B;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #FDD835;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #F9A825;
  }
}

.color-amber {
  background-color: #FFC107;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #FFB300;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #FF8F00;
  }
}

.color-orange {
  background-color: #FF9800;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #FB8C00;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #EF6C00;
  }
}

.color-deeporange {
  background-color: #FF5722;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #F4511E;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #D84315;
  }
}

.color-brown {
  background-color: #795548;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #6D4C41;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #4E342E;
  }
}

.color-gray {
  background-color: #9E9E9E;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #757575;
    color: #FFF;
  }

  &.btn, &.label {
    border: 1px solid #616161;
  }
}

.color-bluegray {
  background-color: #607D8B;
  color: #FFF;

  &.btn:hover, &.btn:focus {
    background-color: #546E7A;
    color: #FFF;
  }
  
  &.btn, &.label {
    border: 1px solid #37474F;
  }
}

.color-lightgray {
  background-color: #DDD;
  color: #424242;

  &.btn:hover, &.btn:focus {
    background-color: #CCC;
    color: #424242;
  }

  &.btn, &.label {
    border: 1px solid #AAA;
  }
}

.color-white {
  background-color: #FFF;
  color: #333;

  &.btn:hover, &.btn:focus {
    background-color: #EEE;
    color: #333;
  }

  &.btn, &.label {
    border: 1px solid #BDBDBD;
  }
}

================================================
FILE: app/assets/stylesheets/common.scss
================================================
.modal-fullscreen {
  width: 100% !important;
  height: 100% !important;
  margin: 0 !important;
  padding: 20px;

  .modal-content {
    height: 100%;
    border-radius: 0;

    .modal-header {
      height: 55px;
    }

    .modal-body {
      position: absolute;
      top: 55px;
      left: 0;
      right: 0;
      bottom: 50px;
    }

    .modal-footer {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
    }
  }
}

.text-red {
  color: #d32f2f !important;
}

.btn-ghost {
  border: 3px solid #FFF;
  border-radius: 4px;
  background-color: transparent;
  color: #FFF;
  font-size: 20px;
  padding: 18px 20px;
  -webkit-transition: all 0.3s ease;
  -moz-transition: all 0.3s ease;
  -o-transition: all 0.3s ease;

  &:hover, &:focus {
    background-color: #FFF;
    color: #01AB52;
  }
}

.inline-block {
  display: inline-block !important;
}

.has-feedback .form-control.validation {
  padding-right: 16px;
}

.popover.error {
  width: 100%;
  max-width: 100%;
  background-color: #F44336;
  color: #FFF;

  &.top .arrow:after, &.bottom .arrow:after {
    border-bottom-color: #F44336;
  }
}

.empty-data {
  padding: 140px 0;
  text-align: center;

  .symbol {
    margin-bottom: 10px;
    font-size: 150px;
    color: #BBB;
  }

  h3 {
    margin-top: 0;
    margin-bottom: 40px;
    color: #BBB;
    font-size: 26px;
  }
}

.color-picker {
  input[type=radio] {
    display: none;
    margin: 0;

    + label {
      height: 20px;
      width: 20px;
      padding: 0;
      margin: 0;
      border-radius: 2px;
      cursor: pointer;
    }

    &:checked + label {
      border: 2px solid #333;
    }
  }
}

.card {
  position: relative;
  width: 500px;
  margin: 0 auto;
  padding: 50px 60px;
  background-color: #FFF;
  border: 1px solid #e8e8e8;
  border-radius: .25rem;
  box-shadow: 0 1px 0 rgba(0,0,0,.25);

  &.card-lg {
    width: 800px;
  }

  &.card-alert {
    margin: 20px auto -20px;
    padding: 20px;
    border-left: 6px solid #C62828;

    h2 {
      margin-top: 0;
      margin-bottom: 16px;
      font-size: 16px;
      font-weight: bold;
    }

    ul {
      padding-left: 20px;
      margin-bottom: 0;

      li:not(:last-child) {
        margin-bottom: 5px;
      }
    }
  }

  &.card-form {
    margin: 40px auto 0;
    padding: 40px 80px;
    text-align: center;

    .card-title {
      margin-top: 0;
      margin-bottom: 30px;
      font-size: 28px;
    }

    .btn[type='submit'] {
      margin-bottom: 20px;
    }
  }
}

.setting-list {
  margin-bottom: 0;
  padding-left: 0;
  list-style: none;

  li {
    position: relative;
    padding-bottom: 20px;
    border-bottom: 1px solid #DDD;

    &:not(:last-child) {
      margin-bottom: 20px;
    }

    .collapse-btn {
      position: absolute;
      top: 0;
      right: 0;
    }

    .accordion-title {
      font-size: 16px;
      font-weight: bold;
    }

    .accordion-description {
      margin-bottom: 20px;
      padding-right: 100px;
      color: #555;
    }

    .form-control {
      display: inline-block;
      margin-right: 5px;
      margin-bottom: 5px;
    }
  }
}

================================================
FILE: app/assets/stylesheets/data_table.scss
================================================
.actionBar .table-toolbar {
  display: inline-block;
  float: right;

  .selected-count {
    display: inline-block;
    padding: 7px 10px;
    margin-right: 10px;
  }

  .btn {
    display: inline-block;
    padding: 6px 10px;
  }
}

================================================
FILE: app/assets/stylesheets/layouts/navbar.scss
================================================
.navbar {
  background-color: #FFF;
  
  > .container-fluid {
    margin-top: 7px;
  }

  .navbar-nav > li > a {
    padding: 6px 12px;
    border-radius: 2px;
  }

  .navbar-nav > li:not(:last-child) {
    margin-right: 10px;
  }

  .navbar-nav.pull-right {
    padding-right: 20px;
  }
}

.navbar.navbar-with-sidebar {
  padding-left: 280px;

  .navbar-content {
    height: 50px;
    padding-left: 20px;
    padding-right: 20px;

    .btn {
      padding: 6px 12px;
      margin-top: 8px;
    }

    .navbar-title {
      padding: 4px;
      display: inline-block;
      font-size: 18px;
      font-weight: bold;
      padding-top: 12px;

      .dropdown {
        .fa-angle-down {
          padding: 0 8px;
          font-size: 85%;
        }
      }
    }
  }
}

================================================
FILE: app/assets/stylesheets/layouts/sidebar.scss
================================================
.page-with-sidebar {
  .sidebar {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: column;
    flex-direction: column;
    height: 100%;
  }

  ul {
    list-style: none;
    padding-left: 0;
    margin: 0;
  }

  .root-sidebar {
    background-color: #192637;

    a {
      color: #C5D0DE;
      display: block;

      &:hover, &:focus {
        background-color: #364760;
        color: #FFF;
      }
    }

    .home-btn, .add-team-btn {
      padding: 16px 0;
      text-align: center;
    }

    .home-btn {
      background-color: #01AB52;
      color: #FFF;

      &:hover, &:focus {
        background-color: #01AB52;
      }
    }

    .add-team-btn {
      background-color: #192637;
      font-size: 28px;
    }

    ul {
      -webkit-flex: 1;
      flex: 1;

      li {
        text-align: center;

        .team-btn {
          height: 60px;
          text-align: center;

          .hilight-bar {
            display: inline-block;
            float: left;
            width: 4px;
            height: 60px;
            background-color: transparent;
          }

          .symbol {
            display: block;
            font-size: 20px;
            font-weight: bold;
            padding-top: 6px;
          }

          .description {
            display: inline-block;
            overflow: hidden;
            width: 46px;  // sidebar-width - hilight-bar-width - (margin-left + margin-right)
            font-size: 11px;
          }
        }
      }

      li.active {
        .team-btn {
          background-color: #364760;
          color: #FFF;
        }

        .hilight-bar { background-color: #01AB52; }
      }
    }
  }

  .team-sidebar {
    border-right: 1px solid #DDD;
    background-color: #FFF;

    .sidebar-title {
      .dropdown-toggle {
        display: inline-block;
        width: 100%;
        margin-bottom: 10px;
        padding: 10px 20px;
        font-size: 20px;
        font-weight: bold;

        .team-name {
          > span {
            display: inline-block;
            word-wrap: break-word;
            max-width: 155px;
          }

          .fa-angle-down {
            padding-top: 0;
            width: 20px;
            font-size: 85%;
            text-align: right;
          }
        }

        &:hover {
          background-color: #EEE;
          border-radius: 2px;
        }
      }

      .username {
        display: block;
        overflow: hidden;
        margin-top: 5px;
        color: #777;
        font-size: 14px;
        font-weight: normal;
        font-style: italic;
      }
    }

    .list-header {
      padding: 0 20px;
      margin-bottom: 5px;
      font-size: 14px;
      font-weight: bold;
      color: #555;

      .add-project-btn {
        float: right;
        padding: 0 4px;
      }
    }

    .sidebar-list {
      -webkit-flex: 1;
      flex: 1;
      padding: 0 20px;

      li {
        overflow-x: hidden;

        a {
          display: inline-block;
          width: 100%;
          padding: 6px;
          font-size: 12px;
          font-weight: bold;
        }

        &:hover, &.active {
          background-color: #EEE;
          border-radius: 2px;
        }
      }
    }

    .coach-mark {
      color: #AAA;
      font-size: 16px;
      height: 60px;

      .fa {
        margin-top: 22px;
        margin-left: 10px;
      }
    }
  }
}

================================================
FILE: app/assets/stylesheets/layouts/style.scss
================================================
body, html {
  width: 100%;
  height: 100%;
}

body {
  -webkit-text-size-adjust: 100%;
  margin: 0;
}

body {
  &.registrations, &.sessions, &.passwords, &.confirmations, &.static_pages.terms {
    padding-top: 50px;
    background-color: #F3F3F3;

    .navbar {
      background-color: #FFF;
      box-shadow: 0 1px 1px rgba(0,0,0,.1);
    }

    .page {
      padding: 40px;
    }
  }
}

.logo {
  display: inline-block;
  color: #555;
  font-size: 24px;
  font-weight: bold;

  &:hover, &:focus {
    color: #555;
  }
}

.ps-scrollbar-x-rail, .ps-scrollbar-y-rail {
  z-index: 99;
}

.page {
  height: 100%;

  .contents {
    position: relative;
    padding: 20px;
    min-height: 100%;
  }
}

.page-with-sidebar {
  .sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
  }

  .root-sidebar {
    left: 0;
    width: 60px;
    z-index: 40;
  }

  .team-sidebar {
    left: 60px;  // Equal to root-sidebar width
    width: 220px;
    z-index: 30;
  }

  .contents {
    padding-top: 70px;
    padding-left: 300px;
    z-index: 10;

    .navbar {
      z-index: 20;
    }
  }
}

================================================
FILE: app/assets/stylesheets/static_pages/terms.scss
================================================
.terms {
  h1 {
    margin-top: 0;
  }

  h2 {
    margin-top: 30px;
    padding-bottom: 10px;
    border-bottom: 1px solid #DDD;
  }
}

================================================
FILE: app/assets/stylesheets/static_pages/top.scss
================================================
.static_pages.top {
  .navbar {
    background-color: #01AB52;
    box-shadow: none;
    margin-bottom: 0;
    border-radius: 0;

    .logo {
      color: #FFF;
    }

    .navbar-nav > li > a {
      color: #FFF;

      &:hover, &:focus {
        color: #01AB52;
      }
    }
  }

  .contents {
    padding: 0;
  }

  .branding {
    background-color: #01AB52;
    color: #FFF;
    padding: 50px 20px 0;

    @media (min-width: 768px) {
      padding-top: 100px;
    }

    h1 {
      margin-top: 0;
      margin-bottom: 20px;
      font-size: 34px;
      font-weight: bold;

      @media (min-width: 768px) {
        font-size: 52px;
      }
    }

    p {
      margin-bottom: 70px;
      font-size: 18px;

      @media (min-width: 768px) {
        font-size: 24px;
      }
    }

    .browser-outline {
      background-color: #F6F6F6;
      max-width: 900px;
      border-top-left-radius: 6px;
      border-top-right-radius: 6px;
      margin-top: 80px;
      margin-right: auto;
      margin-left: auto;

      .browser-header {
        text-align: left;
        padding: 2px 6px;
        font-size: 10px;

        @media (min-width: 768px) {
          padding: 5px 10px;
          font-size: 14px;
        }

        .browser-btn {
          li {
            display: inline-block;
            margin: 0 2px;

            .red { color: #FF4440; }
            .yellow { color: #FFBD00; }
            .green { color: #00D42A; }
          }
        }
      }
    }

    .carousel {
      border-style: solid;
      border-color: #DDD;
      border-width: 1px 1px 0 1px;

      .carousel-control {
        background-image: none;

        @media (min-width: 992px) {
          &.left { margin-left: -120px; }
          &.right { margin-right: -120px; }
        }
      }

      .carousel-indicators {
        li {
          border-color: #01AB52;

          &.active {
            background-color: #01AB52;          
          }
        }
      }
    }
  }

  .feature {
    .col-xs-12 {
      margin-bottom: 40px;
    }

    .feature-item {
      .feature-icon {
        margin-bottom: 10px;
        font-size: 60px;
        text-align: center;
      }

      .feature-title {
        margin-bottom: 15px;
        font-size: 16px;
        font-weight: bold;
        text-align: center;
      }

      .feature-content {
        font-size: 14px;
        text-align: left;
      }
    }
  }

  section {
    padding-top: 40px;
    padding-bottom: 30px;
    text-align: center;
    border-top: 1px solid #DDD;
    color: #666;

    h2 {
      margin-bottom: 40px;
      font-size: 42px;
      font-weight: bold;
    }

    ul {
      display: inline-block;
      padding-left: 0;
      margin-bottom: 0;
      list-style: none;
      text-align: left;

      li {
        margin-bottom: 30px;
        font-size: 20px;

        .fa {
          margin-right: 5px;
        }
      }
    }
  }

  .footer {
    border-top: 1px solid #DDD;
    text-align: center;
    padding-top: 17px;
    padding-bottom: 17px;
    position: relative;

    a {
      color: #555;

      &:hover {
        text-decoration: underline;
      }
    }

    .list-inline {
      display: inline-block;
      margin-bottom: 0;

      li {
        padding-left: 10px;
        padding-right: 10px;
      }
    }

    .copyright {
      display: block;
      margin-top: 18px;
      margin-right: 10px;

      @media (min-width: 768px) {
        position: absolute;
        top: 0;
        right: 14px;
      }
    }
  }
}

================================================
FILE: app/assets/stylesheets/teams/team_users.scss
================================================
.team-users-modal {
  .search-user {
    text-align: center;
    
    width: 300px;
    margin: 0 auto;
    margin-bottom: 30px;

    .form-group {
      text-align: left;
      margin-bottom: 30px;

      label {
        font-weight: normal;
      }
    }

    .ladda-button {
      .fa-chevron-down {
        margin-right: 4px;
      }

      &:disabled .fa-chevron-down {
        display: none;
      }
    }
  }
}

================================================
FILE: app/assets/stylesheets/tests/edit_result_label.scss
================================================
.edit-result-label-modal {
  .popover-content-template {
    display: none;
  }

  .checkbox {
    margin-left: 8px;
  }

  table {
    table-layout: fixed;
    width: 100%;

    td {
      padding: 8px;
    }

    tr {
      .result-label-text {
        input {
          display: inline-block;
          border: none;
          outline:none;
          padding: 2px 4px;
          border-radius: 2px;
          width: 100%;

          &:hover {
            background-color: #FFFFCC;
          }
        }
      }

      .result-label-color {
        .select-color {
          display: inline-block;
          width: 20px;
          height: 20px;
          padding: 0;
          color: transparent;
        }
      }

      .drag-handle-icon, .delete-result-label-icon {
        color: transparent;
        cursor: pointer;
      }

      .delete-result-label {
        text-align: right;

        .delete-result-label-icon {
          padding: 6px 4px;
        }
      }

      &:hover, &:focus {
        .drag-handle-icon {
          color: #555;
        }

        .delete-result-label-icon {
          color: #C62828;
        }
      }
    }
  }

  .table-footer {
    display: block;
    text-align: right;
    padding-right: 2px; 

    .add-result-label-icon {
      cursor: pointer;
      width: 30px;
      padding: 6px 4px;
      text-align: center;
    }
  }

  .drag-handle {
    cursor: move !important;
    cursor: -webkit-grabbing !important;
  }
}

================================================
FILE: app/assets/stylesheets/tests/form.scss
================================================
.tests.new, .tests.edit {
  .contents {
    position: relative;
  
    .test-title {
      position: absolute;
      left: 300px;
      right: 20px;
      top: 55px;
      height: 44px;
    }

    .test-editor {
      position: absolute;
      top: 110px;
      left: 300px;
      right: 20px;
      bottom: 65px;
      border: 1px solid #DDD;

      .test-markdown, .test-preview {
        display: inline-block;
        height: 100%;
        width: 50%;

        .test-editor-header {
          padding: 5px 10px;
          height: 30px;
          background-color: #EEE;
          color: #AAA;
        }
      }

      .test-markdown {
        border-right: 1px solid #DDD;

        .textoverlay-wrapper {
          height: calc(100% - 30px);
        }

        textarea {
          border: none;
          width: 100%;
          height: 100%;
          box-shadow: none;
          -moz-box-shadow: none;
          -webkit-box-shadow: none;
          overflow-x: hidden;
        }
      }

      .test-preview {
        float: right;

        .test-preview-content, .test-cheatsheet {
          width: 100%;
          height: calc(100% - 30px);
          overflow-y: scroll;
          padding:  10px;
        }

        .test-cheatsheet {
          color: #AAA;
          padding: 20px;

          .cheatsheet-header {
            margin-bottom: 15px;
            font-size: 18px;
            font-weight: bold;
          }

          .cheatsheet-block {
            margin-bottom: 20px;

            .cheatsheet-title {
              font-size: 14px;
              font-weight: bold;
            }

            .cheatsheet-body {
              padding: 10px 15px;
              background-color: #FAFAFA;
              border-radius: 4px;
              line-height: 22px;
            }
          }
        }
      }
    }

    footer {
      position: absolute;
      left: 20px;
      right: 20px;
      bottom: 10px;
    }
  }
}

================================================
FILE: app/assets/stylesheets/tests/move.scss
================================================
.move-test-modal {
  .project-list {
    .unset-project {
      padding: 5px 7px;
      font-weight: bold;
    }

    .team-name {
      padding: 2px 10px;
      margin-top: 2px;
      margin-bottom: 2px;
      font-weight: bold;
    }
      
    .project-name {
      padding: 5px 10px 5px 20px;
    }

    ul {
      &:not(:last-child) {
        margin-bottom: 10px;
      }

      .clickable {
        border-radius: 3px;
        cursor: pointer;
        border: 3px dashed transparent;

        &:hover, &:focus {
          border-color: #4CAF50;
        }

        &.active {
          background-color: #4CAF50;
          color: #C8E6C9;
        }
      }
    }
  }
}

================================================
FILE: app/assets/stylesheets/tests/show.scss
================================================
.tests.show {
  .progress-count-list {
    margin-bottom: 0;
    td {
      text-align: right;
      padding: 4px;

      &:first-child {
        padding-right: 8px;
      }

      &:last-child {
        color: #777;
      }

      .label {
        display: block;
      }
    }

    tr:nth-last-child(2) > td {
      padding-bottom: 10px;
    }

    tr:last-child {
      border-top: 1px solid #AAA;
    }
  }

  .contents {
    padding-top: 70px;
    
    .progress.progress-animation {
      position: fixed;
      left: 0;
      right: 0;
      bottom: 0;
      height: 7px;
      padding-top: 1px;
      margin-bottom: 0;
      z-index: 1030;
      border-radius: 0;
      box-shadow: none;
      background-color: #DDD;

      &.margin-sidebar {
        padding-left: 280px;
      }
    }

    .test-title {
      margin-top: 0;
    }

    .test-description {
      position: relative;
      margin-bottom: 20px;
      padding: 6px 34px 6px 10px;
      background-color: #EEE;
      border-radius: 2px;

      p {
        margin-bottom: 0;
        word-wrap: break-word;
      }

      .placeholder {
        color: #BBB; 
      }

      .tool-menu {
        position: absolute;
        top: 0;
        right: 0;
        display: inline-block;
      }
    }

    .test-detail {
      display: block;
      margin-bottom: 30px;
      color: #777;
      text-align: right;
    }

    .bip-placeholder {
      color: #CCC;
    }
  }
}

================================================
FILE: app/assets/stylesheets/tests/testcase.scss
================================================
.testcase-list {
  .testcase-group {
    background-color: #FFF;
    border: 1px solid #DDD;
    border-top-style: none;
    border-radius: 2px;
    margin-bottom: 16px;
  }

  .dropdown-menu {
    background-color: #324851;

    a { color: #FFF; }
  }

  .tr {
    display: table;
    width: 100%;
    border-top: 1px solid #DDD;
  }

  .td {
    display: table-cell;
    vertical-align: middle;
    padding: 2px 2px;
  }

  .heading {
    background-color: #FAFAFA;
    color: #717171;
    font-size: 14px;
    min-height: 29px;
    padding: 2px 2px 2px 48px;
    word-break: break-all;

    .expand-icon, .collapse-icon {
      width: 8px;
      color: #AAA;
    }

    .expand-icon {display: none; }
    .collapse-icon { display: inline-block; }

    &.collapsed {
      .expand-icon { display: inline-block; }
      .collapse-icon { display: none; }
    }

    .body {
      font-weight: bold;
    }

    &.heading-level-1 {
      font-size: 16px;
      letter-spacing: 0.1em;
      margin-top: 16px;
      padding-left: 8px;
      height: 34px;

      &:first-child {
        margin-top: 0;
      }
    }

    &.heading-level-2 {
      padding-left: 18px;
    }

    &.heading-level-3 {
      padding-left: 28px;
    }

    &.heading-level-4 {
      padding-left: 38px;
    }
  }

  .testcase {
    height: 43px;
    padding-left: 8px;

    .number {
      color: #CCC;
      padding-left: 4px;
      width: 30px;
      font-size: 12px;
    }

    .body {
      padding: 4px 10px;
      line-height: 16px;
    }

    .result {
      .result-btn-group {
        .result-btn, .dropdown-toggle {
          height: 32px;
        }

        .result-btn {
          width: 110px;
          overflow: hidden;
          border-top-left-radius: 3px;
          border-bottom-left-radius: 3px;
          font-size: 12px;
        }

        .dropdown-toggle {
          border-top-right-radius: 3px;
          border-bottom-right-radius: 3px;
        }
      }
    }
  }

  .result {
    width: 150px;
    text-align: center;

    .result-item, .result-bulk-item {
      display: block;
      cursor: pointer;
      color: #FFF;
      padding: 3px 20px;
      margin: 0;

      &:hover {
        background-color: #E1E3EA;
        color: #333;
      }
    }
  }

  .note {
    width: 200px;
    max-width: 200px;
    padding: 6px 4px;

    .best_in_place {
      white-space: nowrap;
      overflow: hidden;
    }
  }
}

================================================
FILE: app/assets/stylesheets/toastr_overrides.scss
================================================
#toast-container > div {
  opacity: 1.0;
}

.toast-info {
  background-color: #4CAF50;
}

.toast-warning {
  background-color: #FF9800;
}

================================================
FILE: app/assets/stylesheets/vendor/best_in_place.scss
================================================
.best_in_place {
  display: block;
  width: 100%;
  padding: 4px;
  border: 1px solid transparent;
  border-radius: 2px;

  &:hover {
    background-color: #FFFFCC;
    border-color: #CCC;
    cursor: text;
  }

  input, textarea {
    width: 100%;
    padding: 0;
    background-color: transparent;
    border: none;
    outline: 0;
  }

  textarea {
    resize: none;
    margin-bottom: -25px;
    white-space: normal;
  }
}

================================================
FILE: app/assets/stylesheets/vendor/bootgrid.scss
================================================
.bootgrid-header {
  margin-top: 0;

  .actionBar {
    padding-left: 0;
    padding-right: 0;
    text-align: left;

    .search {
      margin-right: 0;

      .search-field {
        width: 200px;

        &:focus {
          -webkit-transition: width .15s ease-out .1s;
          -moz-transition: width .15s ease-out .1s;
          transition: width .15s ease-out .1s;
          width: 300px;
        }
      }
    }
  }
}

.bootgrid-table {
  .no-results {
    padding: 30px;
  }
}

================================================
FILE: app/assets/stylesheets/vendor/ladda.scss
================================================
.ladda-button {
  &:disabled {
    cursor: default;
  }

  &[data-loading=""] .ladda-spinner {
    top: 50% !important;
  }

  .ladda-spinner {
    top: 0 !important;
  }
}

================================================
FILE: app/controllers/application_controller.rb
================================================
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_filter :set_locale, :set_timezone

  class Forbidden < ActionController::ActionControllerError; end

  def routing_error
    raise ActionController::RoutingError.new("No route matches #{request.path.inspect}")
  end

  def forbidden_error
    redirect_to root_url, flash: { warning: t("errors.forbidden") }
  end

  def after_sign_in_path_for(resource)
    dashboard_path
  end

  def format_error_message(object)
    msgs = object.errors.full_messages
    object.errors.messages.each_with_index.map { |(k, v), i| [k, msgs[i]] }.to_h
  end

  private
    def set_locale
      client_locale = http_accept_language.compatible_language_from(I18n.available_locales)

      if current_user
        locale = current_user.locale
        if locale.nil?
          locale = client_locale
          current_user.update(locale: locale)
        end
      else
        locale = client_locale
      end
      
      I18n.locale = locale
    end

    def set_timezone
      client_tz = Time.zone.name

      if current_user
        tz = current_user.timezone
        if tz.nil?
          tz = client_tz
          current_user.update(timezone: tz)
        end
      else
        tz = client_tz
      end
      
      Time.zone = tz
  end
end


================================================
FILE: app/controllers/concerns/.keep
================================================


================================================
FILE: app/controllers/dashboard_controller.rb
================================================
class DashboardController < ApplicationController
  before_action :authenticate_user!
  
  def index
    @tests = current_user.tests.includes(:project, project: [:team])
  end
end


================================================
FILE: app/controllers/projects_controller.rb
================================================
class ProjectsController < ApplicationController
  before_action :authenticate_user!
  before_action :authorize!, except: [:new, :create]

  def show
    @tests = @project.tests.includes(:user)
  end

  def new
    @project = Project.new
  end

  def edit
  end

  def create
    @project = Project.new(project_params)
    @project.user_id = current_user.id
    
    team = Team.find_by(name: params[:team_name])
    @project.team_id = team.id

    unless @project.save
      render json: format_error_message(@project), status: :unprocessable_entity
    end
  end

  def update
    unless @project.update(project_params)
      render json: format_error_message(@project), status: :unprocessable_entity
    end
  end

  def destroy
    @project.destroy
    redirect_to team_path(params[:team_name]), notice: t("projects.messages.destroy")
  end

  def settings
  end

  private
    def set_project
      team = Team.find_by(name: params[:team_name])
      @project = team.projects.find_by(name: params[:project_name])
      routing_error if @project.nil?
    end

    def authorize!
      @project || set_project
      forbidden_error unless @project.team.authorized?(current_user)
    end

    def project_params
      params.require(:project).permit(:name, :user_id, :team_id)
    end
end

================================================
FILE: app/controllers/static_pages_controller.rb
================================================
class StaticPagesController < ApplicationController
  def top
    @user = User.new
  end

  def terms
  end
end


================================================
FILE: app/controllers/team_users_controller.rb
================================================
class TeamUsersController < ApplicationController
  before_action :authenticate_user!

  def index
    @team = Team.find_by(name: params[:team_name])
    @team_users = @team.team_users.includes(:user)
    @team_user = TeamUser.new
  end

  def create
    @team = Team.find_by(name: params[:team_name])
    user = User.find_by(email: params[:email])

    TeamUser.create(team_id: @team.id, user_id: user.id) unless TeamUser.find_by(team_id: @team.id, user_id: user.id)
    @team_users = @team.team_users
    @team_user = TeamUser.new
  end

  def destroy
    @team_user = TeamUser.find(params[:id])
    @team = @team_user.team
    @team_user.destroy
    @team_users = @team.team_users
    @team_user = TeamUser.new
  end

  def ajax_search_user
    @user = User.find_by(email: params[:email])
    render json: @user.present?
  end
end


================================================
FILE: app/controllers/teams_controller.rb
================================================
class TeamsController < ApplicationController
  before_action :authenticate_user!
  before_action :authorize!, except: [:new, :create]

  def show
    if project = @team.projects.first
      redirect_to team_project_path(@team, project)
    end
  end

  def new
    @team = current_user.teams.build if user_signed_in?
  end

  def edit
  end

  def create
    @team = current_user.teams.build(team_params)
    @team.user_id = current_user.id
    if @team.save
      @team.authorized!(current_user)
    else
      render json: format_error_message(@team), status: :unprocessable_entity
    end
  end

  def update
    unless @team.update(team_params)
      render json: format_error_message(@team), status: :unprocessable_entity
    end
  end

  def destroy
    @team.destroy
    redirect_to dashboard_path, notice: t("teams.messages.destroy")
  end

  def settings
  end

  private
    def set_team
      @team = Team.find_by(name: params[:name])
      routing_error if @team.nil?
    end

    def authorize!
      @team || set_team
      forbidden_error unless @team.authorized?(current_user)
    end

    def team_params
      params.require(:team).permit(:name)
    end
end

================================================
FILE: app/controllers/testcases_controller.rb
================================================
class TestcasesController < ApplicationController
  before_action :set_testcase, only: [:update]

   def update
    test = Test.find_by(slug: params[:test_slug])
    if @testcase.update(testcase_params)
      render json: @testcase, status: 200
    else
      render json: @testcase.errors, status: :unprocessable_entity, notice: "Unknown error"
    end
  end

  private
    def set_testcase
      test = Test.find_by(slug: params[:test_slug])
      if test.testcases.exists?(id: params[:id])
        @testcase = test.testcases.find(params[:id])
      else
        render json: nil, status: :unprocessable_entity, notice: "Unknown error"
      end
    end

    def testcase_params
      params.require(:testcase).permit(:result, :note)
    end
end


================================================
FILE: app/controllers/tests_controller.rb
================================================
class TestsController < ApplicationController
  before_action :authenticate_user!, except: [:show]
  before_action :authorize!, except: [:index, :new, :create, :bulk_move, :bulk_destroy]

  def index
    @tests = Test.all
  end

  def show
    respond_to do |format|
      format.html do
        gon.test = @test
        gon.resultLabelTexts = @test.result_label_texts
        gon.resultLabels = @test.result_labels_or_default
      end
      format.csv do
        encode = "UTF-8"
        encode = "Windows-31J" if I18n.locale == :ja
        csv_data = render_to_string.encode(encode, :invalid => :replace, :undef => :replace)
        send_data csv_data, type: "text/csv; charset=#{encode}", filename: "testcase.csv"
      end
    end
  end

  def new
    @test = Test.new

    # Duplicate test
    if source = Test.find_by(slug: params[:source])
      @test.project_id = source.project_id
      @test.title = source.title
      @test.source = source.slug

      source.set_markdown(false)
      @test.markdown = source.markdown
    end
  end

  def edit
    forbidden_error unless @test.user  # Owner unknown
    
    @test.set_markdown(true)
  end

  def create
    @test = current_user.tests.build(test_params)

    team = Team.find_by(name: params[:test][:team_name])
    project = team.projects.find_by(name: params[:test][:project_name]) if team && team.authorized?(current_user)
    @test.project_id = project.id if project

    # Duplicate test
    if source = Test.find_by(slug: @test.source)
      @test.description = source.description
      @test.result_labels = source.result_labels
    end

    if @test.save
      @test.make_testcase
    end
  end

  def update
    @test.updated_at = Time.now
    if @test.update(test_params)
      @test.make_testcase if @test.markdown
    end
  end

  def destroy
    team = view_context.current_team
    project = view_context.current_project

    @test.destroy
    if project
      redirect_to team_project_path(team_name: team.name, project_name: project.name), notice: t("tests.messages.destroy")
    else
      redirect_to dashboard_path, notice: t("tests.messages.destroy")
    end
  end

  def description
  end

  def result_label
  end

  def update_result_label
    @test.result_labels = nil
    if params[:test][:use_default] == "0"
      # Use default label
      keys = params[:test][:result_label_texts]
      vals = params[:test][:result_label_colors]
      hash = Hash[*keys.zip(vals).flatten]
      @test.result_labels = hash
    end
    @test.save
  end

  def move
    @teams = current_user.teams
  end

  def bulk_move
    if params[:project].blank?
      project_id = nil  # Unset project
    else
      return unless project = Project.find(params[:project])  # Project not found
      return unless project.team.authorized?(current_user)  # Forbidden error
      project_id = project.id  # Move to project
    end

    params[:tests].each do |i|
      test = Test.find(i)
      next if test.project.nil? && test.user != current_user
      next unless test.authorized?(current_user)
      test.update_column(:project_id, project_id)
    end
  end

  def bulk_destroy
    params[:tests].each do |i|
      test = Test.find(i)
      next if test.project.nil? && test.user != current_user
      next unless test.authorized?(current_user)
      test.destroy
    end
  end

  def user_association
    @test.update(user_id: current_user.id) unless @test.user
    redirect_to @test
  end

  private
    def set_test
      @test = Test.find_by(slug: params[:slug])
      routing_error if @test.nil?
    end

    def authorize!
      @test || set_test
      if @project = @test.project
        team = @project.team || Team.find_by(name: params[:team_name])
        forbidden_error unless team.authorized?(current_user)
      end
    end

    def test_params
      params.require(:test).permit(:title, :description, :project_id, :markdown, :source)
    end
end

================================================
FILE: app/controllers/user_settings_controller.rb
================================================
class UserSettingsController < ApplicationController
  before_action :authenticate_user!
  before_action :set_user, only: [:edit, :update]

  def edit
  end

  def update
    unless @user.update(user_params)
      render json: format_error_message(@user), status: :unprocessable_entity
    end
  end

  private
    def set_user
      @user = current_user
    end

    def user_params
      params.require(:user).permit(:username, :timezone, :locale)
    end
end


================================================
FILE: app/controllers/users/registrations_controller.rb
================================================
class Users::RegistrationsController < Devise::RegistrationsController
  def edit
    routing_error  # Invalidate a "/users/edit"
  end

  def update
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)

    resource_updated = update_resource(resource, account_update_params)
    yield resource if block_given?
    if resource_updated
      if is_flashing_format?
        flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
          :update_needs_confirmation : :updated
        set_flash_message :notice, flash_key
      end
      sign_in resource_name, resource, bypass: true
      # respond_with resource, location: after_update_path_for(resource)
      render "user_settings/update"
    else
      clean_up_passwords resource
      # respond_with resource
      render json: format_error_message(resource), status: :unprocessable_entity
    end
  end
 
end


================================================
FILE: app/helpers/application_helper.rb
================================================
module ApplicationHelper
  def controller_action
    controller_name + "#" + action_name
  end

  def color_names
    %w(red pink purple deeppurple indigo blue cyan teal green lightgreen lime yellow amber orange deeporange brown gray bluegray lightgray white)
  end

  def page_title(title)
    if title.blank?
      "Chibineko: #{I18n.t('.static_pages.top.branding.title')}"
    else
      "#{title} | Chibineko"
    end
  end
end


================================================
FILE: app/helpers/dashboard_helper.rb
================================================
module DashboardHelper
end


================================================
FILE: app/helpers/projects_helper.rb
================================================
module ProjectsHelper
  def project_collection
    current_team.projects if current_team
  end

  def current_project
    team_name = params[:team_name]
    project_name = params[:project_name]
    if team_name && project_name
      team = Team.find_by(name: team_name)
      team.projects.find_by(name: project_name)
    else
      current_test.project if current_test
    end
  end
end


================================================
FILE: app/helpers/static_pages_helper.rb
================================================
module StaticPagesHelper
end


================================================
FILE: app/helpers/team_users_helper.rb
================================================
module TeamUsersHelper
end


================================================
FILE: app/helpers/teams_helper.rb
================================================
module TeamsHelper
  def current_team
    if team_name = params[:name] || params[:team_name]
      Team.find_by(name: team_name)  
    elsif current_test
      current_test.try(:project).try(:team) 
    end
  end
end


================================================
FILE: app/helpers/tests_helper.rb
================================================
module TestsHelper
  def current_test
    Test.find_by(slug: params[:slug])
  end
end


================================================
FILE: app/mailers/.keep
================================================


================================================
FILE: app/models/.keep
================================================


================================================
FILE: app/models/concerns/.keep
================================================


================================================
FILE: app/models/project.rb
================================================
class Project < ActiveRecord::Base
  belongs_to :team
  has_many :tests, :dependent => :destroy
  before_save { self.name = name.downcase }
  validates :name,
    presence: true,
    uniqueness: { case_sensitive: false, :scope => :team_id },
    length: { maximum: 30 },
    format: { with: /\A[a-z0-9_]+\z/i }
  default_scope { order("id ASC") }

  def to_param
    name
  end
end


================================================
FILE: app/models/team.rb
================================================
class Team < ActiveRecord::Base
  has_many :projects, :dependent => :destroy
  has_many :team_users, :dependent => :destroy
  has_many :users, :through => :team_users
  belongs_to :user
  before_save { self.name = name.downcase }
  validates :name,
    presence: true,
    uniqueness: { case_sensitive: false },
    length: { in: 4..30 },
    format: { with: /\A[a-z0-9_]+\z/i }
  default_scope { order("id ASC") }

  def authorized?(user)
    user && self.team_users.find_by(user_id: user.id) ? true : false
  end

  def authorized!(user)
    self.team_users.create(team_id: self.id, user_id: user.id)
  end
  
  def to_param
    name
  end
end


================================================
FILE: app/models/team_user.rb
================================================
class TeamUser < ActiveRecord::Base
  belongs_to :team
  belongs_to :user
  default_scope { order("id ASC") }
end


================================================
FILE: app/models/test.rb
================================================
class Test < ActiveRecord::Base
  belongs_to :user
  belongs_to :project
  has_many :testcases, dependent: :destroy
  after_initialize :set_slug
  serialize :result_labels
  validates :title, presence: true, length: { maximum: 255 }
  validates :description, length: { maximum: 4096 }
  default_scope { order("id ASC") }
  attr_accessor :markdown, :source

  def to_param
    slug
  end

  def authorized?(user)
    if project = self.project
      project.team.authorized?(user)
    else
      true
    end
  end

  def result_labels_or_default
    labels = I18n.t("tests.result_labels")
    result_labels || {
      labels[:unexecuted] => "white",
      labels[:pass] => "green",
      labels[:fail] => "red",
      labels[:blocked] => "orange",
      labels[:na] => "gray",
    }
  end

  def result_label_texts
    result_labels_or_default.keys
  end

  def result_label_colors
    result_labels_or_default.values
  end

  def testcase_groups
    groups = []
    buff = []

    testcases = self.testcases
    testcases.each_with_index do |c, i|
      buff << c
      if testcases[i + 1].try(:heading_level) == 1
        groups << buff
        buff = []
      end
    end
    groups << buff if buff.size
    groups
  end

  def set_markdown(with_result = false)
    array = []
    self.testcases.each do |t|
      buff = nil
      case t.type
      when :blank
        buff = ""
      when :heading
        buff = ("#" * t.heading_level) + " " + t.body
      when :testcase
        buff = t.body
        if with_result
          if t.result && t.result != self.result_label_texts.first
            buff += ", [#{t.result}]"
            unless t.note.blank?
              buff += ", #{t.note}"
            end
          end
        end
      end
      array << buff
    end
    self.markdown = array.join("\n")
  end

  def make_testcase
    self.testcases.delete_all

    self.markdown.each_line do |line|
      level  = Testcase.heading_level(line)
      body   = Testcase.body(line)
      result = Testcase.result(line)
      note   = Testcase.note(line)
      self.testcases.create(heading_level: level, body: body, result: result, note: note)
    end
  end

  private
    def set_slug
      self.slug = self.slug.blank? ? generate_slug : self.slug
    end

    def generate_slug
      token = SecureRandom.urlsafe_base64
      self.class.where(slug: token).blank? ? token : generate_slug
    end
end


================================================
FILE: app/models/testcase.rb
================================================
class Testcase < ActiveRecord::Base
  belongs_to :test
  validates :body, length: { maximum: 1024 }
  validates :result, length: { maximum: 255 }
  validates :note, length: { maximum: 1024 }
  default_scope { order("id ASC") }
  
  def type
    case self.heading_level
    when -1
      :blank
    when 0
      :testcase
    else
      :heading
    end
  end

  def result
    super || self.test.result_label_texts.first  # Default value
  end

  def result_color
    self.test.result_labels_or_default[self.result] || "white"  # Default value
  end

  class << self
    def heading_level(text)
      return -1 if text.blank?

      text.strip!
      level = 0
      if text.start_with?("#")
        text.each_char {|char| char == "#" ? level += 1 : break }
      end
      level
    end

    def body(text)
      text.try(:strip!)
      return nil if text.blank?
      
      level = self.heading_level(text)

      if level == 0
        text =~ /(.*)(?:,\s\[.*\])/
        body = $1 || text
      else
        body = text[level..-1]
        body.strip
      end
    end

    def result(text)
      text.try(:strip!)
      return nil if text.blank?

      text =~ /,(?:\s)?\[(.*)\]/
      result = $1
    end

    def note(text)
      text.try(:strip!)
      return nil if text.blank?

      text =~ /,(?:\s)?\[(?:.*)\],(.*)/
      note = $1
      note.strip if note
    end
  end
end

================================================
FILE: app/models/user.rb
================================================
class User < ActiveRecord::Base
  has_many :tests
  has_many :team_users
  has_many :teams, :through => :team_users
  validates :email, length: { maximum: 255 }
  validates :username, length: { maximum: 30 }
  default_scope { order("id ASC") }
  
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable

  def display_name
    username || email.split("@").first
  end
end


================================================
FILE: app/views/dashboard/_navbar.html.slim
================================================
nav.navbar.navbar-fixed-top.navbar-with-sidebar
  .navbar-content
    = link_to fa_icon("plus", text: t("common.button.new_test")), new_test_path(team_name: current_team.try(:name), project_name: current_project.try(:name)), class: "btn color-blue new-test-btn pull-right", data: { toggle: "tooltip", placement: "bottom", title: t("common.button.create_new_test") }

================================================
FILE: app/views/dashboard/index.html.slim
================================================
- provide :title, t("dashboard.index.title")

= render "navbar"

- if @tests.size == 0
  .empty-data
    = fa_icon("inbox", class: "symbol")
    h3 = t("projects.show.empty_message")
    = link_to fa_icon("plus", text: t(".navbar.new_test")), new_test_path, class: "btn btn-lg color-blue"

- else
  = render "tests/table_toolbar"
  table.table.table-condensed.table-hover.data-table style="table-layout:fixed;"
    thead
      tr
        th.hidden data-column-id="id" data-type="numeric" data-identifier="true" data-visible="false" ID
        th.hidden data-column-id="slug" data-visible="false" slug
        th data-column-id="title" data-formatter="title" data-searchable="true" data-width="50%" = t("activerecord.attributes.test.title")
        th data-column-id="project" data-searchable="false" = t("common.project")
        th data-column-id="updated" data-converter="date" data-searchable="false" data-order="desc" = t("common.updated_on")
    tbody
      - @tests.reorder("updated_at DESC").each do |test|
        tr
          td.hidden = test.id
          td.hidden = test.slug
          td = link_to test.title, test
          td = "#{test.project.team.name}##{test.project.name}" if test.project
          td = test.updated_at.strftime("%Y-%m-%d %H:%M:%S")

================================================
FILE: app/views/devise/confirmations/new.html.slim
================================================
- if devise_error_messages!.present?
  .card.card-alert = devise_error_messages!

.card.card-form
  = form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
    h1.card-title = t(".resend_confirmation")
    .card-body
      .form-group
        = f.email_field :email, class: "form-control input-lg", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email), autofocus: true, placeholder: t("activerecord.attributes.user.email"), required: true

      = f.submit t(".send_mail"), class: "btn btn-lg color-primary btn-block", data: { disable_with: "Processing" }

================================================
FILE: app/views/devise/mailer/confirmation_instructions.en.html.slim
================================================
p = "Welcome #{@email} !"

p You can confirm your account email through the link below:

p = link_to "Confirm my account", confirmation_url(@resource, confirmation_token: @token)

================================================
FILE: app/views/devise/mailer/confirmation_instructions.ja.html.slim
================================================
p = "ようこそ #{@email} さん。"

p 下記のリンクをクリックして、ユーザ登録を完了してください。

p = link_to "メールアドレスを認証", confirmation_url(@resource, confirmation_token: @token)

================================================
FILE: app/views/devise/mailer/password_change.html.erb
================================================
<p>Hello <%= @resource.email %>!</p>

<p>We're contacting you to notify you that your password has been changed.</p>


================================================
FILE: app/views/devise/mailer/reset_password_instructions.en.html.slim
================================================
p = "Hello #{@resource.email} !"

p Someone has requested a link to change your password. You can do this through the link below.

p = link_to "Change my password", edit_password_url(@resource, reset_password_token: @token)

p If you didn't request this, please ignore this email.
p Your password won't change until you access the link above and create a new one.

================================================
FILE: app/views/devise/mailer/reset_password_instructions.ja.html.slim
================================================
p = "こんにちは #{@resource.email} さん。"

p パスワードリセットのリクエストが行われました。<br>下記のリンクからパスワードを変更することができます。

p = link_to "パスワードを再設定", edit_password_url(@resource, reset_password_token: @token)

p もしこのメールに心当たりがない場合は、無視して下さい。<br>上記リンクをクリックして新しいパスワードを作成しない限り、パスワードは変更されません。

================================================
FILE: app/views/devise/passwords/new.html.slim
================================================
- if devise_error_messages!.present?
  .card.card-alert = devise_error_messages!

.card.card-form
  = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
    h1.card-title = t(".forgot_password")
    .card-body
      .form-group
        = f.email_field :email, class: "form-control input-lg", autofocus: true, placeholder: t("activerecord.attributes.user.email"), required: true

      = f.submit t(".send_mail"), class: "btn btn-lg btn-block color-primary", data: { disable_with: "Processing" }


================================================
FILE: app/views/devise/registrations/new.html.slim
================================================
- if devise_error_messages!.present?
  .card.card-alert = devise_error_messages!

.card.card-form
  = form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
    h1.card-title = t(".sign_up")
    .card-body
      .form-group
        = f.email_field :email, class: "form-control input-lg", autofocus: true, placeholder: t("activerecord.attributes.user.email"), required: true

      .form-group
        = f.password_field :password, class: "form-control input-lg", autocomplete: "off", placeholder: t("activerecord.attributes.user.password"), required: true

      .form-group
        = f.password_field :password_confirmation, class: "form-control input-lg", autocomplete: "off", placeholder: t("activerecord.attributes.user.password_confirmation"), required: true

      = f.submit t(".sign_up"), class: "btn btn-lg color-primary btn-block", data: { disable_with: "Processing" }
      
    .text-left
      = link_to t(".not_receive"), new_confirmation_path(resource_name)


================================================
FILE: app/views/devise/sessions/new.html.slim
================================================
.card.card-form
  = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
    h1.card-title = t(".sign_in")
    .card-body
      .form-group
        = f.email_field :email, class: "form-control input-lg", autofocus: true, placeholder: t("activerecord.attributes.user.email"), required: true

      .form-group
        = f.password_field :password, class: "form-control input-lg", autocomplete: "off", placeholder: t("activerecord.attributes.user.password"), required: true

      = f.submit t(".sign_in"), class: "btn btn-lg color-primary btn-block"
      
    .text-left
      = link_to t(".remember_password"), new_password_path(resource_name)

================================================
FILE: app/views/devise/shared/_links.html.erb
================================================
<%- if controller_name != 'sessions' %>
  <%= link_to "Log in", new_session_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
  <%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
  <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
  <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
  <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end -%>

<%- if devise_mapping.omniauthable? %>
  <%- resource_class.omniauth_providers.each do |provider| %>
    <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %><br />
  <% end -%>
<% end -%>


================================================
FILE: app/views/layouts/_dashboard_sidebar.html.slim
================================================
.sidebar.team-sidebar
  .sidebar-title.dropdown
    a.dropdown-toggle aria-expanded="false" aria-haspopup="true" data-toggle="dropdown" href="#" role="button"
      .team-name
        span = t("dashboard.index.title")
        = fa_icon "angle-down"
      span.username = current_user.display_name
    = render "layouts/main_menu"

  ul.sidebar-list
    li class="sidebar-list-item active"
      = link_to t(".your_test"), dashboard_path

  - if current_user.teams.size == 0
    .coach-mark = fa_icon("hand-o-left", text: t(".coach_mark"))

================================================
FILE: app/views/layouts/_logo.html.slim
================================================
/ = link_to "Chibineko", root_url, class: "logo"

================================================
FILE: app/views/layouts/_main_menu.html.slim
================================================
ul.dropdown-menu style="top: 44px; left: 18px;"
  li.dropdown-header = t("common.you")
  li = link_to fa_icon("cog", text: t(".account_settings")), user_settings_edit_path, remote: true
  li = render "layouts/sign_out_link"
  - if current_team
    li.dropdown-header = t("common.team")
    li = link_to fa_icon("cog", text: t(".team_settings")), settings_team_path(current_team), remote: true
    li = link_to fa_icon("smile-o", text: t(".edit_members")), team_team_users_path(current_team), remote: true

================================================
FILE: app/views/layouts/_navbar.html.slim
================================================
- if controller_action == "static_pages#top"
  nav.navbar
    .container-fluid
      = link_to "Chibineko", root_url, class: "logo"
      ul.nav.navbar-nav.navbar-right
        li = link_to fa_icon("github-alt", text: t(".github_page")), "https://github.com/tabbyz/chibineko"
        - if user_signed_in?
          li.dropdown
            a href="#" class="dropdown-toggle" data-toggle="dropdown" data-container="body" role="button" aria-expanded="false"
              = current_user.display_name
              span.caret
            ul.dropdown-menu.dropdown-menu-right role="menu"
              li = link_to fa_icon("home", text: t("dashboard.index.title")), dashboard_path
              li = render "layouts/sign_out_link"
        - else
          li = render "layouts/sign_in_link"

- else
  nav.navbar.navbar-fixed-top
    .container-fluid
      = link_to "Chibineko", root_url, class: "logo"
      ul.nav.navbar-nav.pull-right
        - if user_signed_in?
          li = render "layouts/sign_out_link"
        - else
          li = render "layouts/sign_in_link"
          li = render "layouts/sign_up_link"

================================================
FILE: app/views/layouts/_root_sidebar.html.slim
================================================
.sidebar.root-sidebar
  = link_to fa_icon("home 2x"), dashboard_path, class: "home-btn", data: { toggle: "tooltip", placement: "right", title: t("dashboard.index.title") }

  ul.hover-scroll
    / li = link_to fa_icon("home 2x"), dashboard_path, class: "home-btn", data: { toggle: "tooltip", placement: "right", title: t("dashboard.index.title") }
    - current_user.teams.reorder("name").each do |team|
      li class="#{'active' if team == current_team}"
        = link_to team_path(team), class: "team-btn", title: team.name do
          .hilight-bar
          span.symbol = team.name.first.upcase
          span.description = team.name

  = link_to fa_icon("plus-circle", right: true), new_team_path, class: "add-team-btn", data: { toggle: "tooltip", placement: "right", title: t(".create_team") }, remote: true

================================================
FILE: app/views/layouts/_sign_in_link.html.slim
================================================
= link_to t("common.button.sign_in"), new_user_session_path

================================================
FILE: app/views/layouts/_sign_out_link.html.slim
================================================
= link_to fa_icon("sign-out", text: t("common.button.sign_out")), destroy_user_session_path, method: :delete

================================================
FILE: app/views/layouts/_sign_up_link.html.slim
================================================
= link_to t("common.button.sign_up"), new_user_registration_path, class: "btn color-blue sign-up"

================================================
FILE: app/views/layouts/_team_sidebar.html.slim
================================================
.sidebar.team-sidebar
  .sidebar-title.dropdown
    a.dropdown-toggle aria-expanded="false" aria-haspopup="true" data-toggle="dropdown" href="#" role="button" 
      .team-name
        span = current_team.try(:name)
        = fa_icon "angle-down"
      span.username = current_user.display_name
    = render "layouts/main_menu"

  .list-header
    span = t("common.project")
    = link_to fa_icon("plus-circle"), new_team_project_path(current_team), class: "add-project-btn", data: { toggle: "tooltip", placement: "top", title: t("common.button.create_new_project") }, remote: true
  ul.sidebar-list.hover-scroll
    - current_team.projects.reorder("name").each do |project|
      li class="#{'active' if project == current_project}"
        = link_to project.name, team_project_path(team_name: current_team.name, project_name: project.name)

================================================
FILE: app/views/layouts/application.html.slim
================================================
doctype html
html
  head
    title = page_title(yield :title)
    - if controller_action == "static_pages#top"
      meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"
    = stylesheet_link_tag "application", media: "all"
    = favicon_link_tag
    = include_gon
    = javascript_include_tag "application"
    = javascript_include_tag "translations"
    javascript:
      I18n.defaultLocale = "#{I18n.default_locale}"
      I18n.locale = "#{I18n.locale}"
      I18n.fallbacks = true
    = csrf_meta_tags

  body class="#{controller_name} #{action_name}"
    - if flash
      - flash.each do |f|
        - type = f[0].to_s.gsub("alert", "warning").gsub("notice", "info")
        javascript:
          toastr["#{type}"]("#{f[1]}")

    - if controller_name.in?(%w"dashboard teams projects tests")
      - if user_signed_in?
        .page.page-with-sidebar
          = render "layouts/root_sidebar"
          = current_team ? render("layouts/team_sidebar") : render("layouts/dashboard_sidebar")
          .contents == yield
      - else
        .page
          .contents == yield
    - else
      = render "layouts/navbar"
      .page
        .contents
          == yield

    .modal.fade tabindex="-1" role="dialog" aria-hidden="true"

================================================
FILE: app/views/projects/_navbar.html.slim
================================================
nav.navbar.navbar-fixed-top.navbar-with-sidebar
  .navbar-content
    .navbar-title
      .dropdown
        a.dropdown-toggle aria-expanded="false" aria-haspopup="true" data-toggle="dropdown" href="#" role="button" 
          = current_project.try(:name)
          = fa_icon "angle-down"
        ul.dropdown-menu
          li.dropdown-header = t("common.project")
          li = link_to fa_icon("cog", text: t(".menu.project_settings")), settings_team_project_path(current_team, current_project), remote: true

    = link_to fa_icon("plus", text: t("common.button.new_test")), new_test_path(team_name: current_team.try(:name), project_name: current_project.try(:name)), class: "btn color-blue new-test-btn pull-right", data: { toggle: "tooltip", placement: "bottom", title: t("common.button.create_new_test") }

================================================
FILE: app/views/projects/_new.html.slim
================================================
.new-project-modal.modal-dialog.modal-sm
  .modal-content
    = form_for @project, url: team_projects_path, remote: true do |f|
      .modal-header
        button.close type="button" data-dismiss="modal" aria-label="Close"
          span aria-hidden="true" &times;
        h4.modal-title = t(".title")
      .modal-body
        .form-group
          = f.text_field :name, class: "form-control input-lg validation", placeholder: t(".enter_name"), autofocus: true, maxlength: 30, required: true
          p.text-danger.error-message
      .modal-footer
        button.btn.btn-lg.btn-default type="button" data-dismiss="modal" = t("dialog.cancel")
        = f.submit class: "btn btn-lg color-primary"

================================================
FILE: app/views/projects/_save.js.erb
================================================
$(".modal").modal("hide")
$(window.location.replace("<%= team_project_path(@project.team.name, @project.name) %>"))

================================================
FILE: app/views/projects/_settings.html.slim
================================================
.project-settings-modal.modal-dialog
  .modal-content
    .modal-header
      button.close type="button" data-dismiss="modal" aria-label="Close"
        span aria-hidden="true" &times;
      h4.modal-title = t(".title")

    .modal-body
      ul.setting-list
        li
          = link_to t("common.button.expand"), "#editName", class: "btn color-lightgray collapse-btn", data: { toggle: "collapse" }, aria: { expanded: "false", controls: "editName" }
          p.accordion-title = t(".name.title")
          p.accordion-description
            = t(".name.current_value_html", name: current_project.name)
          .collapse#editName
            = form_for current_project, url: team_project_path, remote: true do |f|
              .form-group.inline-block
                = f.text_field :name, class: "form-control validation", style: "width:250px;", maxlength: 255, required: true
              = button_tag class: "btn color-green ladda-button", data: { style: "expand-right" } do
                = content_tag :span, t("helpers.submit.update"), class: "ladda-label"

        li
          = link_to t("common.button.expand"), "#deleteProject", class: "btn color-lightgray collapse-btn", data: { toggle: "collapse" }, aria: { expanded: "false", controls: "deleteProject" }
          p.accordion-title.text-red = t(".delete.title")
          .collapse#deleteProject
            p.accordion-description = t(".delete.description")
            = link_to t(".delete.delete_project"), team_project_path(current_team.name, current_project.name), class: "btn btn-sm btn-danger", data: { confirm: t("messages.delete_confirm") }, :method => :delete

    .modal-footer
      button.btn.btn-lg.btn-default type="button" data-dismiss="modal" = t("dialog.close")

================================================
FILE: app/views/projects/create.js.erb
================================================
<%= render 'save' %>

================================================
FILE: app/views/projects/new.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'new') %>")
$(".modal").modal("show")

================================================
FILE: app/views/projects/settings.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'settings') %>")
Ladda.bind(".ladda-button")
$(".modal").modal("show")

================================================
FILE: app/views/projects/show.html.slim
================================================
- provide :title, "#{@project.team.name}##{@project.name}"

= render "navbar"

- if @project.tests.size == 0
  .empty-data
    = fa_icon("inbox", class: "symbol")
    h3 = t(".empty_message")
    = link_to fa_icon("plus", text: t("common.button.create_new_test")), new_test_path(team_name: current_team.try(:name), project_name: current_project.try(:name)), class: "btn btn-lg color-blue"

- else
  = render "tests/table_toolbar"
  table.table.table-condensed.table-hover.data-table style="table-layout:fixed;"
    thead
      tr
        th.hidden data-column-id="id" data-type="numeric" data-identifier="true" data-visible="false" ID
        th.hidden data-column-id="slug" data-visible="false" slug
        th data-column-id="title" data-formatter="title" data-searchable="true" data-width="50%" = t("activerecord.attributes.test.title")
        th data-column-id="created" data-searchable="false" = t("common.created_by")
        th data-column-id="updated" data-converter="date" data-searchable="false" data-order="desc" = t("common.updated_on")
    tbody
      - @tests.reorder("updated_at DESC").try(:each) do |test|
        tr
          td.hidden = test.id
          td.hidden = test.slug
          td = link_to test.title, test
          td = test.user.display_name
          td = test.updated_at.strftime("%Y-%m-%d %H:%M:%S")

================================================
FILE: app/views/projects/update.js.erb
================================================
<%= render 'save' %>

================================================
FILE: app/views/static_pages/terms.html.slim
================================================
.card.card-lg
  h1.card-title = t(".title")

  .card-body
    = t(".body_html")

================================================
FILE: app/views/static_pages/top.html.slim
================================================
.container-fluid
  .row.branding.text-center
    h1 = t(".branding.title")
    p = t(".branding.sub_title")

    - if user_signed_in?
      = link_to t(".branding.get_started"), dashboard_path, class: "btn-ghost"
    - else
      = link_to t(".branding.sign_up_free"), new_user_registration_path, class: "btn-ghost"

    .browser-outline
      .browser-header
        ul.nav.browser-btn
          - %w(red yellow green).each do |color|
            li = fa_icon("circle", class: color)
      #carousel-screenshot.carousel.slide data-ride="carousel"
        ol.carousel-indicators
          li.active data-slide-to="0" data-target="#carousel-screenshot" 
          li data-slide-to="1" data-target="#carousel-screenshot" 
          li data-slide-to="2" data-target="#carousel-screenshot" 
        .carousel-inner role="listbox" 
          - %w(screenshot_1.png screenshot_2.png screenshot_3.png).each_with_index do |file, i|
            div class="item #{'active' if i == 1}"
              img alt=("First") data-holder-rendered="true" data-src=("First slide") src="images/#{file}" /
        a.left.carousel-control data-slide="prev" href="#carousel-screenshot" role="button" 
          span.glyphicon.glyphicon-chevron-left aria-hidden="true"
          span.sr-only Previous
        a.right.carousel-control data-slide="next" href="#carousel-screenshot" role="button" 
          span.glyphicon.glyphicon-chevron-right aria-hidden="true" 
          span.sr-only Next

  section.row.feature
    h2 = t(".feature.title")
    .container
      row
        .col-md-3.col-sm-6.col-xs-12.feature-item
          .feature-icon = fa_icon("bar-chart")
          .feature-title = t(".feature.test_management_title")
          .feature-content = t(".feature.test_management_body")
        .col-md-3.col-sm-6.col-xs-12.feature-item
          .feature-icon = fa_icon("group")
          .feature-title = t(".feature.team_management_title")
          .feature-content = t(".feature.team_management_body")
        .col-md-3.col-sm-6.col-xs-12.feature-item
          .feature-icon = fa_icon("share")
          .feature-title = t(".feature.share_result_title")
          .feature-content = t(".feature.share_result_body")
        .col-md-3.col-sm-6.col-xs-12.feature-item
          .feature-icon = fa_icon("code-fork")
          .feature-title = t(".feature.oss_title")
          .feature-content = t(".feature.oss_body")

  section.row.section.support
    h2 = t(".support")
    ul
      li = mail_to "support@chibineko.jp", fa_icon("envelope-o", text: "Email"), encode: "hex"
      li = link_to fa_icon("github-alt", text: "GitHub Issues"), "https://github.com/tabbyz/chibineko/issues"
      li = link_to fa_icon("twitter", text: "Twitter"), "https://twitter.com/chibinekojp"

  .row.footer
    ul.list-inline
      li = link_to t(".terms"), terms_path
      li = link_to t(".releases"), "https://github.com/tabbyz/chibineko/releases"
    span.copyright
      = link_to "© 2015 SHIFT, Inc.", "http://www.shiftinc.jp/", target: "blank"

================================================
FILE: app/views/team_users/_index.html.slim
================================================
.team-users-modal.modal-dialog.modal-sm
  .modal-content
    .modal-header
      button.close type="button" data-dismiss="modal" aria-label="Close"
        span aria-hidden="true" &times;
      h4.modal-title = t(".title")
    .modal-body
      .search-user
        = form_for @team_user, url: team_team_users_path, remote: true do |f|
          = hidden_field_tag :team_name, @team.name
          .form-group
            label = t(".search_user")
            = email_field_tag :email, nil, class: "form-control", placeholder: "name@domain.com", required: true
          = button_tag type: "submit", class: "btn color-green ladda-button", data: { style: "expand-right" } do
            = fa_icon "chevron-down"
            = content_tag :span, t(".add_user"), class: "ladda-label"

      table.table.table-condensed
        thead
          tr
            th = t("activerecord.attributes.user.email").capitalize
            th = t("activerecord.attributes.user.name").capitalize
            th
        tbody
          - @team_users.each do |team_user|
            tr
              td = team_user.user.email
              td = team_user.user.username
              td
                - if team_user.user != current_user
                  = form_for team_user, url: team_team_user_path(@team, team_user), :html => { :method => :delete }, remote: true do |form|
                    = button_tag type: "submit", class: "btn-link", data: { confirm: t(".delete_confirm") } do
                      = fa_icon "close"
    .modal-footer
      button.btn.btn-lg.btn-default.pull-right type="button" data-dismiss="modal" = t("dialog.done")

================================================
FILE: app/views/team_users/_save.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'index') %>")
Ladda.bind(".ladda-button")

================================================
FILE: app/views/team_users/create.js.erb
================================================
<%= render 'save' %>

================================================
FILE: app/views/team_users/destroy.js.erb
================================================
<%= render 'save' %>

================================================
FILE: app/views/team_users/index.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'index') %>")
Ladda.bind(".ladda-button")
$(".modal").modal("show")

================================================
FILE: app/views/teams/_new.html.slim
================================================
.new-team-modal.modal-dialog.modal-sm
  .modal-content
    = form_for @team, remote: true do |f|
      .modal-header
        button.close type="button" data-dismiss="modal" aria-label="Close"
          span aria-hidden="true" &times;
        h4.modal-title = t(".title")
      .modal-body
        .form-group
          = f.text_field :name, class: "form-control input-lg validation", placeholder: t(".enter_name"), autofocus: true, maxlength: 30, required: true
          p.text-danger.error-message
      .modal-footer
        button.btn.btn-lg.btn-default type="button" data-dismiss="modal" = t("dialog.cancel")
        = f.submit class: "btn btn-lg color-primary"

================================================
FILE: app/views/teams/_save.js.erb
================================================
$(".modal").modal("hide")
$(window.location.replace("<%= team_path(@team.name) %>"))

================================================
FILE: app/views/teams/_settings.html.slim
================================================
.team-settings-modal.modal-dialog
  .modal-content
    .modal-header
      button.close type="button" data-dismiss="modal" aria-label="Close"
        span aria-hidden="true" &times;
      h4.modal-title = t(".title")

    .modal-body
      ul.setting-list
        li
          = link_to t("common.button.expand"), "#editName", class: "btn color-lightgray collapse-btn", data: { toggle: "collapse" }, aria: { expanded: "false", controls: "editName" }
          p.accordion-title = t(".name.title")
          p.accordion-description
            = t(".name.current_value_html", name: current_team.name)
          .collapse#editName
            = form_for current_team, remote: true do |f|
              .form-group.inline-block
                = f.text_field :name, class: "form-control validation", style: "width:250px;", maxlength: 255, required: true
              = button_tag class: "btn color-green ladda-button", data: { style: "expand-right" } do
                = content_tag :span, t("helpers.submit.update"), class: "ladda-label"

        li
          = link_to t("common.button.expand"), "#deleteTeam", class: "btn color-lightgray collapse-btn", data: { toggle: "collapse" }, aria: { expanded: "false", controls: "deleteTeam" }
          p.accordion-title.text-red = t(".delete.title")
          .collapse#deleteTeam
            p.accordion-description = t(".delete.description")
            = link_to t(".delete.delete_team"), current_team, class: "btn btn-sm btn-danger", data: { confirm: t("messages.delete_confirm") }, :method => :delete

    .modal-footer
      button.btn.btn-lg.btn-default type="button" data-dismiss="modal" = t("dialog.close")

================================================
FILE: app/views/teams/create.js.erb
================================================
<%= render 'save' %>

================================================
FILE: app/views/teams/new.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'new') %>")
$(".modal").modal("show")

================================================
FILE: app/views/teams/settings.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'settings') %>")
Ladda.bind(".ladda-button")
$(".modal").modal("show")

================================================
FILE: app/views/teams/show.html.slim
================================================
- provide :title, @team.name

- if @team.projects.size == 0
  .empty-data
    = fa_icon("inbox", class: "symbol")
    h3 = t(".empty_message")

    = link_to fa_icon("plus", text: t("common.button.create_new_project")), new_team_project_path(current_team), class: "btn btn-lg color-blue add-project-btn", remote: true

================================================
FILE: app/views/teams/update.js.erb
================================================
<%= render 'save' %>

================================================
FILE: app/views/tests/_alert.html.slim
================================================
- if @test.user && @test.project.nil?
  .alert.alert-info
    p = t("messages.public_test_html")

- if @test.user.nil?
  .alert.alert-warning
    p = t("messages.created_by_guest_html")
    p
      span = t("messages.please_association_html")
      = link_to t("messages.attach_current_user"), user_association_test_path, class: "btn btn-sm color-primary", :method => :patch if user_signed_in?

================================================
FILE: app/views/tests/_cheatsheet.en.html.slim
================================================
.cheatsheet
  p.cheatsheet-header = fa_icon("question-circle", text: "Tips: how to create test cases")
  .cheatsheet-block
    p.cheatsheet-title ・Your listed contents can be your test items as it is
    p.cheatsheet-body To be able to register an user<br>To be able to sign in
  .cheatsheet-block
    p.cheatsheet-title ・Group items by adding "#" at the beginning of a line
    p.cheatsheet-body # User management function<br>## User registration<br>To be able to register an user<br>## Sign in<br>To be able to log in with correct ID and Password<br>To be unable to log in with wrong ID and Password

================================================
FILE: app/views/tests/_cheatsheet.ja.html.slim
================================================
.cheatsheet
  p.cheatsheet-header = fa_icon("question-circle", text: "書き方のヒント")
  .cheatsheet-block
    p.cheatsheet-title ・箇条書きにした内容がそのままテスト項目になります
    p.cheatsheet-body ユーザー登録できること<br>ログインできること
  .cheatsheet-block
    p.cheatsheet-title ・行の先頭に # を記入するとグループ化することができます
    p.cheatsheet-body # ユーザー管理機能<br>## ユーザー登録<br>新規登録できること<br>## ログイン<br>正しいID/PASSでログインできること<br>誤ったID/PASSではエラーが表示されること

================================================
FILE: app/views/tests/_description.html.slim
================================================
.edit-description-modal.modal-dialog.modal-lg
  .modal-content
    = form_for @test, remote: true do |f|
      .modal-header
        button.close type="button" data-dismiss="modal" aria-label="Close"
          span aria-hidden="true" &times;
        h4.modal-title = t(".title")

      .modal-body
        = f.text_area :description, class: "form-control", autofocus: true, rows: 20, maxlength: 4096
            
      .modal-footer
        button.btn.btn-lg.btn-default type="button" data-dismiss="modal" = t("dialog.cancel")
        = f.submit t("helpers.submit.submit"), class: "btn btn-lg color-primary"

================================================
FILE: app/views/tests/_form.html.slim
================================================
= render "navbar"

= form_for @test, remote: true do |f|
  = f.hidden_field :source
  = f.hidden_field :team_name, value: current_team.try(:name)
  = f.hidden_field :project_name, value: current_project.try(:name)
  .test-title
    = f.text_field :title, class: "form-control input-lg", placeholder: t(".title_placeholder"), autofocus: (action_name == "new" ? true : false), maxlength: 255, required: true
  .test-editor
    .test-markdown
      .test-editor-header
        p = t(".markdown_header")
      = f.text_area :markdown, class: "form-control", placeholder: t(".markdown_placeholder"), autofocus: (action_name == "edit" ? true : false), required: true
    .test-preview
      .test-editor-header
        p = t(".preview_header")
      .test-preview-content
      .test-cheatsheet style="display:none;"
        = render "cheatsheet"

  footer
    = f.submit class: "btn btn-lg color-primary pull-right"


================================================
FILE: app/views/tests/_move.html.slim
================================================
.move-test-modal.modal-dialog.modal-xs
  .modal-content
    = form_for @test, remote: true do |f|
      = f.hidden_field :project_id, class: "selected-id-field"
      .modal-header
        button.close type="button" data-dismiss="modal" aria-label="Close"
          span aria-hidden="true" &times;
        h4.modal-title = t(".title")
      .modal-body
        .project-list
          ul.nav
            li class="unset-project clickable #{'active' if current_project.nil?}" = t(".unset_project")
          - @teams.each do |team|
            - if team.projects.size != 0
              p.team-name = team.name
              ul.nav
                - team.projects.each do |project|
                  li data-project-id="#{project.id}" class="project-name clickable #{'active' if project == current_project}"
                    = project.name
      .modal-footer
        button.btn.btn-lg.btn-default type="button" data-dismiss="modal" = t("dialog.cancel")
        = f.submit t(".submit"), class: "btn btn-lg color-primary"

================================================
FILE: app/views/tests/_navbar.html.slim
================================================
nav.navbar.navbar-fixed-top.navbar-with-sidebar
  .navbar-content
    - if action_name == "show"
      = link_to fa_icon("pencil", text: t(".edit_test")), edit_test_path(@test), class: "btn color-blue edit-test-btn #{'disabled' unless @test.user}", data: { toggle: "tooltip", placement: "bottom", title: t(".edit_current_test") }
      
    - elsif action_name.in?(%w"new edit")
      .navbar-title
        span = t("tests.form.title.#{action_name}")

    ul.nav.navbar-nav.navbar-right
      - if action_name == "show"
        li = link_to fa_icon("line-chart"), "#", class: "btn progress-count", data: { toggle: "popover", placement: "bottom", trigger: "hover", html: "true", content: "" }
        li = link_to fa_icon("download"), test_path(format: :csv), class: "btn", data: { toggle: "tooltip", placement: "bottom", title: t(".export_csv") }
        li = link_to fa_icon("copy"), new_test_path(team_name: current_team.try(:name), project_name: current_project.try(:name), source: @test.slug), class: "btn", data: { toggle: "tooltip", placement: "bottom", title: t(".duplicate_test") }
        li = link_to fa_icon("file-o"), new_test_path(team_name: current_team.try(:name), project_name: current_project.try(:name)), class: "btn", data: { toggle: "tooltip", placement: "bottom", title: t("common.button.create_new_test") }

        - if @test.user
          - if @test.project || @test.user == current_user
            li.dropdown
              a.btn data-target="#" href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"
                = fa_icon "cog"
              ul.dropdown-menu
                li.dropdown-header = t(".test_settings")
                li = link_to fa_icon("external-link", text: t(".move_to")), move_test_path(@test), remote: true
                li = link_to fa_icon("pencil", text: t(".customize_result_label")), result_label_test_path(@test), remote: true
                li.divider role="separator"
                li = link_to fa_icon("trash-o", text: t(".delete_test")), @test, class: "text-red", data: { confirm: t("messages.delete_confirm") }, :method => :delete

================================================
FILE: app/views/tests/_result_label.html.slim
================================================
.edit-result-label-modal.modal-dialog.modal-xs
  .modal-content
    = form_for @test, url: update_result_label_test_path, remote: true do |f|
      .modal-header
        button.close type="button" data-dismiss="modal" aria-label="Close"
          span aria-hidden="true" &times;
        h4.modal-title = t(".title")
        
      .modal-body
        .checkbox
          = f.label :use_default do
            = f.check_box :use_default, class: "user-default-result-label", checked: (@test.result_labels.nil? ? true : false)
            = t(".use_default_label")
        table style=("display: none;" if @test.result_labels.nil?)
          tbody#resultLabelList
            - @test.result_labels_or_default.each do |k, v|
              tr
                td.drag-handle style="width:30px;"
                  = fa_icon "bars", class: "drag-handle-icon"
                td.result-label-text
                  = text_field_tag "test[result_label_texts][]", k, { id: nil, placeholder: t(".label_placeholder"), maxlength: 10, required: true }
                td.result-label-color style="width:40px;"
                  input class="btn select-color color-#{v}" name="test[result_label_colors][]" value="#{v}" type="text" tabindex="0" role="button" data-toggle="popover" data-trigger="focus" data-placement="left"
                td.delete-result-label style="width:40px;"
                  = fa_icon("close", class: "delete-result-label-icon")
          .over
        .table-footer style=("display: none;" if @test.result_labels.nil?)
          = fa_icon("plus", class: "add-result-label-icon")

        .popover-content-template
          .color-picker
            - color_names.each do |color|
              input type="radio" name="color-radio" id="radio-#{color}" value="#{color}"
                label for="radio-#{color}" class="btn color-item color-#{color}"

      .modal-footer
        button.btn.btn-lg.btn-default type="button" data-dismiss="modal" = t("dialog.cancel")
        = f.submit t("helpers.submit.submit"), class: "btn btn-lg color-primary"

================================================
FILE: app/views/tests/_table_toolbar.html.slim
================================================
.table-toolbar
  span.selected-count
  ul.nav.navbar-nav.navbar-right
    li = link_to fa_icon("trash-o", text: t("common.button.delete")), "#", class: "btn text-red bulk-destroy-btn"
    li.dropdown
      a.btn data-target="#" href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"
        = fa_icon "external-link", text: t("common.button.move")
      ul.dropdown-menu
        li = link_to t("tests.move.unset_project"), "#", class: "bulk-move-btn"
        - current_user.teams.includes(:projects).each do |team|
          li.dropdown-header = team.name
          - team.projects.each do |project|
            li = link_to project.name, "#", class: "bulk-move-btn", data: { project_id: project.id }

================================================
FILE: app/views/tests/_testcase.html.slim
================================================
.testcase-toolbar
  button type="button" class="btn-link js-collapse-all-btn"
    = fa_icon "caret-down", text: t(".collapse_all"), class: "collapse-icon"
  button type="button" class="btn-link js-expand-all-btn" style="display:none;"
    = fa_icon "caret-right", text: t(".expand_all"), class: "expand-icon"

.testcase-list
  - case_id = 0
  - @test.testcase_groups.each do |group|
    .testcase-group
      - group.each do |c|
        - case c.type
        - when :heading
          div class="tr heading heading-level-#{c.heading_level}" data-heading-level="#{c.heading_level}"
            .td.body
              = fa_icon "caret-down", class: "collapse-icon"
              = fa_icon "caret-right", class: "expand-icon"
              button type="button" class="btn-link js-collapse-btn" = c.body
        - when :testcase
          .tr.testcase
            .td.number = case_id += 1
            .td.body = c.body
            .td.result
              .btn-group.result-btn-group
                = button_tag c.result, type: "button", class: "btn result-btn color-#{c.result_color}", data: { "case-id" => c.id }
                = button_tag type: "button", class: "btn dropdown-toggle color-#{c.result_color}", data: { toggle: "dropdown" } do
                  span.caret
                  span.sr-only Toggle Dropdown
                ul.dropdown-menu.pull-right role="menu"
                  - @test.result_label_texts.each do |label|
                    li
                      p.result-item = label
            .td.note = best_in_place c, :note, url: test_testcase_path(test_slug: @test.slug, id: c.id), place_holder: t(".note"), html_attrs: { maxlength: 1024 }, data: { toggle: "tooltip", placement: "top", "original-title" => c.note }

================================================
FILE: app/views/tests/bulk_destroy.js.erb
================================================
window.location.reload()

================================================
FILE: app/views/tests/bulk_move.js.erb
================================================
window.location.reload()

================================================
FILE: app/views/tests/create.js.erb
================================================
$(".modal").modal("hide")
$(window.location.replace("<%= test_path(@test.slug) %>"))

================================================
FILE: app/views/tests/description.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'description') %>")
$(".modal").modal("show")

================================================
FILE: app/views/tests/edit.html.slim
================================================
= render "form"

================================================
FILE: app/views/tests/move.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'move') %>")
$(".modal").modal("show")

================================================
FILE: app/views/tests/new.html.slim
================================================
= render "form"

================================================
FILE: app/views/tests/result_label.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'result_label') %>")
$(".modal").modal("show")

Sortable.create(resultLabelList, { handle: ".drag-handle" });

$(".select-color").popover({
  html : true, 
  content: $(".popover-content-template").html()
})

================================================
FILE: app/views/tests/show.csv.ruby
================================================
require 'csv'

testcases = @test.testcases

# Examine the maximum heading level
max_level = 0
testcases.each do |c|
  if c.type == :heading
    max_level = c.heading_level if c.heading_level > max_level  
  end
end
headings = Array.new(max_level)

# Header
header = Array.new(max_level, "-")
header << I18n.t("tests.csv.case") << I18n.t("tests.csv.result") << I18n.t("tests.csv.note")

# Generate csv
CSV.generate(headers: header, write_headers: true, force_quotes: true) do |csv|
# CSV.generate do |csv|
  testcases.each do |c|
    case c.type
      when :heading
        # Clear unnecessary column
        length = max_level - c.heading_level
        headings[c.heading_level, length] = Array.new(length, "")

        # Set value to column
        headings[c.heading_level - 1] = c.body
      when :testcase
        row = Array.new(headings)
        row << c.body << c.result << c.note
        csv << row
    end
  end
end

================================================
FILE: app/views/tests/show.html.slim
================================================
- provide :title, @test.title

- if !user_signed_in?
  = render "layouts/navbar"
- else
  = render "navbar"

.progress.progress-animation class=(user_signed_in? ? "margin-sidebar" : "")
  - @test.result_labels_or_default.drop(1).push(@test.result_labels_or_default.first).each do |k, v|
    div class="progress-bar progress-bar-xs color-#{v}" style="width: 0%; transition: width 0.5s ease;" data-result-text="#{k}"

= render "alert"

h3.test-title = @test.title

.test-description
  - if @test.description.blank?
    p.placeholder = t(".blank_description")
  - else
    = auto_link simple_format(html_escape(@test.description)), :html => { target: "_blank" }
  .tool-menu
    = link_to fa_icon("pencil"), description_test_path(@test), class: "btn", data: { toggle: "tooltip", placement: "left", title: t("tests.description.title") }, remote: true if @test.user && user_signed_in?

.test-detail
  span = t(".created_by", username: @test.user ? @test.user.display_name : t("common.guest"), updated_at: l(@test.updated_at, format: :short))

= render "testcase"

================================================
FILE: app/views/tests/update.js.erb
================================================
$(".modal").modal("hide")
$(window.location.replace("<%= test_path(@test.slug) %>"))

================================================
FILE: app/views/tests/update_result_label.js.erb
================================================
$(".modal").modal("hide")
$(window.location.reload())

================================================
FILE: app/views/user_settings/_modal.html.slim
================================================
.account-settings-modal.modal-dialog
  .modal-content
    .modal-header
      button.close type="button" data-dismiss="modal" aria-label="Close"
        span aria-hidden="true" &times;
      h4.modal-title = t(".title")

    .modal-body
      ul.setting-list
        li
          = link_to t("common.button.expand"), "#editUsername", class: "btn color-lightgray collapse-btn", data: { toggle: "collapse" }, aria: { expanded: "false", controls: "editUsername" }
          p.accordion-title = t(".username.title")
          p.accordion-description
            - if @user.username.blank?
              = t(".username.blank")
            - else
              = t(".username.current_value_html", username: @user.username)
          .collapse#editUsername
            = form_for @user, url: user_settings_update_path, remote: true do |f|
              .form-group.inline-block
                = f.text_field :username, class: "form-control validation", style: "width:200px;", maxlength: 255, required: true
              = button_tag class: "btn color-green ladda-button", data: { style: "expand-right" } do
                = content_tag :span, t("helpers.submit.submit"), class: "ladda-label"

        li
          = link_to t("common.button.expand"), "#editPassword", class: "btn color-lightgray collapse-btn", data: { toggle: "collapse" }, aria: { expanded: "false", controls: "editPassword" }
          p.accordion-title = t(".password.title")
          p.accordion-description = t(".password.change_password")
          .collapse#editPassword
            = form_for @user, as: "user", url: registration_path("user"), html: { method: :put }, remote: true do |f| 
              .form-group.inline-block
                label for="user_current_password" = t(".password.current_password")
                = f.password_field :current_password, class: "form-control validation", style: "width:200px; display:block;", required: true
              br
              .form-group.inline-block
                label for="user_password" = t(".password.new_password")
                = f.password_field :password, class: "form-control validation", style: "width:200px; display:block;", autocomplete: "off", required: true
              br
              .form-group.inline-block
                label for="user_password" = t(".password.confirm_password")
                = f.password_field :password_confirmation, class: "form-control validation", style: "width:200px; display:block;", autocomplete: "off", required: true
              br
              = button_tag class: "btn color-green ladda-button", data: { style: "expand-right" } do
                = content_tag :span, t(".password.update"), class: "ladda-label"

        li
          = link_to t("common.button.expand"), "#editTimezone", class: "btn color-lightgray collapse-btn", data: { toggle: "collapse" }, aria: { expanded: "false", controls: "editTimezone" }
          p.accordion-title = t(".timezone.title")
          p.accordion-description
            = t(".timezone.current_value_html", timezone: @user.timezone)
          .collapse#editTimezone
            = form_for @user, url: user_settings_update_path, remote: true do |f|
              = f.time_zone_select :timezone, nil, { include_blank: false }, { class: "form-control", required: true }
              = button_tag class: "btn color-green ladda-button", data: { style: "expand-right" } do
                = content_tag :span, t(".timezone.update"), class: "ladda-label"

        li
          = link_to t("common.button.expand"), "#editLanguage", class: "btn color-lightgray collapse-btn", data: { toggle: "collapse" }, aria: { expanded: "false", controls: "editLanguage" }
          p.accordion-title = t(".language.title")
          p.accordion-description
            = t(".language.current_value_html", language: t("language_name"))
          .collapse#editLanguage
            = form_for @user, url: user_settings_update_path, remote: true do |f|
              = f.select :locale, { "English" => "en", "日本語" => "ja" }, {}, { class: "form-control", style: "width:200px;" }
              = button_tag class: "btn color-green ladda-button", data: { style: "expand-right" } do
                = content_tag :span, t("helpers.submit.submit"), class: "ladda-label"

    .modal-footer
      button.btn.btn-lg.btn-default type="button" data-dismiss="modal" = t("dialog.close")

================================================
FILE: app/views/user_settings/edit.js.erb
================================================
$(".modal").html("<%= escape_javascript(render 'modal') %>")
Ladda.bind(".ladda-button")
$(".modal").modal("show")

================================================
FILE: app/views/user_settings/update.js.erb
================================================
$(".modal").modal("hide")
$(window.location.reload())

================================================
FILE: bin/bundle
================================================
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
load Gem.bin_path('bundler', 'bundle')


================================================
FILE: bin/rails
================================================
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'


================================================
FILE: bin/rake
================================================
#!/usr/bin/env ruby
require_relative '../config/boot'
require 'rake'
Rake.application.run


================================================
FILE: bin/setup
================================================
#!/usr/bin/env ruby
require 'pathname'

# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../',  __FILE__)

Dir.chdir APP_ROOT do
  # This script is a starting point to setup your application.
  # Add necessary setup steps to this file:

  puts "== Installing dependencies =="
  system "gem install bundler --conservative"
  system "bundle check || bundle install"

  # puts "\n== Copying sample files =="
  # unless File.exist?("config/database.yml")
  #   system "cp config/database.yml.sample config/database.yml"
  # end

  puts "\n== Preparing database =="
  system "bin/rake db:setup"

  puts "\n== Removing old logs and tempfiles =="
  system "rm -f log/*"
  system "rm -rf tmp/cache"

  puts "\n== Restarting application server =="
  system "touch tmp/restart.txt"
end


================================================
FILE: circle.yml
================================================
machine:
  ruby:
    version: 2.3.0
database:
  pre:
    - cp config/mailer.yml.example config/mailer.yml

================================================
FILE: config/application.rb
================================================
require File.expand_path('../boot', __FILE__)

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module Chibineko
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de
    config.i18n.available_locales = %w(en ja)

    # Do not swallow errors in after_commit/after_rollback callbacks.
    config.active_record.raise_in_transactional_callbacks = true

    config.assets.initialize_on_precompile = true

    config.web_console.development_only = false
  end
end


================================================
FILE: config/boot.rb
================================================
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' # Set up gems listed in the Gemfile.


================================================
FILE: config/database.yml
================================================
# SQLite version 3.x
#   gem install sqlite3
#
#   Ensure the SQLite 3 gem is defined in your Gemfile
#   gem 'sqlite3'
#
default: &default
  adapter: sqlite3
  pool: 5
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: db/test.sqlite3

production:
  <<: *default
  database: db/production.sqlite3


================================================
FILE: config/environment.rb
================================================
# Load the Rails application.
require File.expand_path('../application', __FILE__)

# Initialize the Rails application.
Rails.application.initialize!


================================================
FILE: config/environments/development.rb
================================================
Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # In the development environment your application's code is reloaded on
  # every request. This slows down response time but is perfect for development
  # since you don't have to restart the web server when you make code changes.
  config.cache_classes = false

  # Do not eager load code on boot.
  config.eager_load = false

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false

  # Print deprecation notices to the Rails logger.
  config.active_support.deprecation = :log

  # Raise an error on page load if there are pending migrations.
  config.active_record.migration_error = :page_load

  # Debug mode disables concatenation and preprocessing of assets.
  # This option may cause significant delays in view rendering with a large
  # number of complex assets.
  config.assets.debug = true

  # Asset digests allow you to set far-future HTTP expiration dates on all assets,
  # yet still be able to expire them through the digest params.
  config.assets.digest = true

  # Adds additional error checking when serving assets at runtime.
  # Checks for improperly declared sprockets dependencies.
  # Raises helpful error messages.
  config.assets.raise_runtime_errors = true

  # Raises error for missing translations
  # config.action_view.raise_on_missing_translations = true

  # Bullet settings
  config.after_initialize do
    Bullet.enable = true
    Bullet.alert = true
    Bullet.console = true
    Bullet.rails_logger = true
  end

  # Mailer settings.
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :letter_opener_web
end


================================================
FILE: config/environments/production.rb
================================================
Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # Code is not reloaded between requests.
  config.cache_classes = true

  # Eager load code on boot. This eager loads most of Rails and
  # your application in memory, allowing both threaded web servers
  # and those relying on copy on write to perform better.
  # Rake tasks automatically ignore this option for performance.
  config.eager_load = true

  # Full error reports are disabled and caching is turned on.
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # Enable Rack::Cache to put a simple HTTP cache in front of your application
  # Add `rack-cache` to your Gemfile before enabling this.
  # For large-scale production use, consider using a caching reverse proxy like
  # NGINX, varnish or squid.
  # config.action_dispatch.rack_cache = true

  # Compress JavaScripts and CSS.
  config.assets.js_compressor = :uglifier
  # config.assets.css_compressor = :sass

  # Do not fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = false

  # Asset digests allow you to set far-future HTTP expiration dates on all assets,
  # yet still be able to expire them through the digest params.
  config.assets.digest = true

  # Disable Rails's static asset server (Apache or nginx will already do this).
  config.serve_static_files = true

  # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb

  # Specifies the header that your server uses for sending files.
  # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  config.force_ssl = true

  # Use the lowest log level to ensure availability of diagnostic information
  # when problems arise.
  config.log_level = :debug

  # Prepend all log lines with the following tags.
  # config.log_tags = [ :subdomain, :uuid ]

  # Use a different logger for distributed setups.
  # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)

  # Use a different cache store in production.
  # config.cache_store = :mem_cache_store

  # Enable serving of images, stylesheets, and JavaScripts from an asset server.
  # config.action_controller.asset_host = 'http://assets.example.com'

  # Ignore bad email addresses and do not raise email delivery errors.
  # Set this to true and configure the email server for immediate delivery to raise delivery errors.
  # config.action_mailer.raise_delivery_errors = false

  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation cannot be found).
  config.i18n.fallbacks = true

  # Send deprecation notices to registered listeners.
  config.active_support.deprecation = :notify

  # Use default logging formatter so that PID and timestamp are not suppressed.
  config.log_formatter = ::Logger::Formatter.new

  # Do not dump schema after migrations.
  config.active_record.dump_schema_after_migration = false
end


================================================
FILE: config/environments/test.rb
================================================
Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # The test environment is used exclusively to run your application's
  # test suite. You never need to work with it otherwise. Remember that
  # your test database is "scratch space" for the test suite and is wiped
  # and recreated between test runs. Don't rely on the data there!
  config.cache_classes = true

  # Do not eager load code on boot. This avoids loading your whole application
  # just for the purpose of running a single test. If you are using a tool that
  # preloads Rails for running tests, you may have to set it to true.
  config.eager_load = false

  # Configure static file server for tests with Cache-Control for performance.
  config.serve_static_files   = true
  config.static_cache_control = 'public, max-age=3600'

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Raise exceptions instead of rendering exception templates.
  config.action_dispatch.show_exceptions = false

  # Disable request forgery protection in test environment.
  config.action_controller.allow_forgery_protection = false

  # Tell Action Mailer not to deliver emails to the real world.
  # The :test delivery method accumulates sent emails in the
  # ActionMailer::Base.deliveries array.
  config.action_mailer.delivery_method = :test

  # Randomize the order test cases are executed.
  config.active_support.test_order = :random

  # Print deprecation notices to the stderr.
  config.active_support.deprecation = :stderr

  # Raises error for missing translations
  # config.action_view.raise_on_missing_translations = true
end


================================================
FILE: config/i18n-js.yml
================================================
# Split context in several files.
# By default only one file with all translations is exported and
# no configuration is required. Your settings for asset pipeline
# are automatically recognized.
#
# If you want to split translations into several files or specify
# locale contexts that will be exported, just use this file to do
# so.
#
# If you're going to use the Rails 3.1 asset pipeline, change
# the following configuration to something like this:
#
#   translations:
#     - file: "app/assets/javascripts/i18n/translations.js"
#
# If you're running an old version, you can use something
# like this:
#

translations:
  - file: "public/javascripts/translations.js"
    only: "*.js"

================================================
FILE: config/initializers/action_mailer.rb
================================================
unless Chibineko::Application.config.action_mailer.nil?
  if options = YAML.load_file(Rails.root.join("config", "mailer.yml"))[Rails.env]
    Chibineko::Application.config.action_mailer.merge! options.deep_symbolize_keys!
  end
end

================================================
FILE: config/initializers/assets.rb
================================================
# Be sure to restart your server when you modify this file.

# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'

# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path

# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )


================================================
FILE: config/initializers/backtrace_silencers.rb
================================================
# Be sure to restart your server when you modify this file.

# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }

# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!


================================================
FILE: config/initializers/cookies_serializer.rb
================================================
# Be sure to restart your server when you modify this file.

Rails.application.config.action_dispatch.cookies_serializer = :json


================================================
FILE: config/initializers/devise.rb
================================================
# Use this hook to configure devise mailer, warden hooks and so forth.
# Many of these configuration options can be set straight in your model.
Devise.setup do |config|
  # The secret key used by Devise. Devise uses this key to generate
  # random tokens. Changing this key will render invalid all existing
  # confirmation, reset password and unlock tokens in the database.
  # Devise will use the `secret_key_base` on Rails 4+ applications as its `secret_key`
  # by default. You can change it below and use your own secret key.
  # config.secret_key = '35175ed82fda77f2e1c26412bc6ae3d0c295fdfc00205063ab570e74ffc1b1a6217959602c468032b3fecbb119f517d9a3c144f9a43892585470c3c5f1a1fc5e'

  # ==> Mailer Configuration
  # Configure the e-mail address which will be shown in Devise::Mailer,
  # note that it will be overwritten if you use your own mailer class
  # with default "from" parameter.
  config.mailer_sender = '"Chibineko" <noreply@chibineko.jp>'

  # Configure the class responsible to send e-mails.
  # config.mailer = 'Devise::Mailer'

  # ==> ORM configuration
  # Load and configure the ORM. Supports :active_record (default) and
  # :mongoid (bson_ext recommended) by default. Other ORMs may be
  # available as additional gems.
  require 'devise/orm/active_record'

  # ==> Configuration for any authentication mechanism
  # Configure which keys are used when authenticating a user. The default is
  # just :email. You can configure it to use [:username, :subdomain], so for
  # authenticating a user, both parameters are required. Remember that those
  # parameters are used only when authenticating and not when retrieving from
  # session. If you need permissions, you should implement that in a before filter.
  # You can also supply a hash where the value is a boolean determining whether
  # or not authentication should be aborted when the value is not present.
  # config.authentication_keys = [:email]

  # Configure parameters from the request object used for authentication. Each entry
  # given should be a request method and it will automatically be passed to the
  # find_for_authentication method and considered in your model lookup. For instance,
  # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
  # The same considerations mentioned for authentication_keys also apply to request_keys.
  # config.request_keys = []

  # Configure which authentication keys should be case-insensitive.
  # These keys will be downcased upon creating or modifying a user and when used
  # to authenticate or find a user. Default is :email.
  config.case_insensitive_keys = [:email]

  # Configure which authentication keys should have whitespace stripped.
  # These keys will have whitespace before and after removed upon creating or
  # modifying a user and when used to authenticate or find a user. Default is :email.
  config.strip_whitespace_keys = [:email]

  # Tell if authentication through request.params is enabled. True by default.
  # It can be set to an array that will enable params authentication only for the
  # given strategies, for example, `config.params_authenticatable = [:database]` will
  # enable it only for database (email + password) authentication.
  # config.params_authenticatable = true

  # Tell if authentication through HTTP Auth is enabled. False by default.
  # It can be set to an array that will enable http authentication only for the
  # given strategies, for example, `config.http_authenticatable = [:database]` will
  # enable it only for database authentication. The supported strategies are:
  # :database      = Support basic authentication with authentication key + password
  # config.http_authenticatable = false

  # If 401 status code should be returned for AJAX requests. True by default.
  # config.http_authenticatable_on_xhr = true

  # The realm used in Http Basic Authentication. 'Application' by default.
  # config.http_authentication_realm = 'Application'

  # It will change confirmation, password recovery and other workflows
  # to behave the same regardless if the e-mail provided was right or wrong.
  # Does not affect registerable.
  # config.paranoid = true

  # By default Devise will store the user in session. You can skip storage for
  # particular strategies by setting this option.
  # Notice that if you are skipping storage for all authentication paths, you
  # may want to disable generating routes to Devise's sessions controller by
  # passing skip: :sessions to `devise_for` in your config/routes.rb
  config.skip_session_storage = [:http_auth]

  # By default, Devise cleans up the CSRF token on authentication to
  # avoid CSRF token fixation attacks. This means that, when using AJAX
  # requests for sign in and sign up, you need to get a new CSRF token
  # from the server. You can disable this option at your own risk.
  # config.clean_up_csrf_token_on_authentication = true

  # ==> Configuration for :database_authenticatable
  # For bcrypt, this is the cost for hashing the password and defaults to 10. If
  # using other encryptors, it sets how many times you want the password re-encrypted.
  #
  # Limiting the stretches to just one in testing will increase the performance of
  # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
  # a value less than 10 in other environments. Note that, for bcrypt (the default
  # encryptor), the cost increases exponentially with the number of stretches (e.g.
  # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
  config.stretches = Rails.env.test? ? 1 : 10

  # Setup a pepper to generate the encrypted password.
  # config.pepper = '1dd38cee240f1b8caf5c7450a71fa6fc0053db3fc62d31706fcaf4b7135e03f616008ccc8124b934dedfd1d9b56306b441b9ef6cdd4a9f091355c0f2a4defa74'

  # Send a notification email when the user's password is changed
  # config.send_password_change_notification = false

  # ==> Configuration for :confirmable
  # A period that the user is allowed to access the website even without
  # confirming their account. For instance, if set to 2.days, the user will be
  # able to access the website for two days without confirming their account,
  # access will be blocked just in the third day. Default is 0.days, meaning
  # the user cannot access the website without confirming their account.
  # config.allow_unconfirmed_access_for = 2.days

  # A period that the user is allowed to confirm their account before their
  # token becomes invalid. For example, if set to 3.days, the user can confirm
  # their account within 3 days after the mail was sent, but on the fourth day
  # their account can't be confirmed with the token any more.
  # Default is nil, meaning there is no restriction on how long a user can take
  # before confirming their account.
  # config.confirm_within = 3.days

  # If true, requires any email changes to be confirmed (exactly the same way as
  # initial account confirmation) to be applied. Requires additional unconfirmed_email
  # db field (see migrations). Until confirmed, new email is stored in
  # unconfirmed_email column, and copied to email column on successful confirmation.
  config.reconfirmable = true

  # Defines which key will be used when confirming an account
  # config.confirmation_keys = [:email]

  # ==> Configuration for :rememberable
  # The time the user will be remembered without asking for credentials again.
  # config.remember_for = 2.weeks

  # Invalidates all the remember me tokens when the user signs out.
  config.expire_all_remember_me_on_sign_out = true

  # If true, extends the user's remember period when remembered via cookie.
  # config.extend_remember_period = false

  # Options to be passed to the created cookie. For instance, you can set
  # secure: true in order to force SSL only cookies.
  # config.rememberable_options = {}

  # ==> Configuration for :validatable
  # Range for password length.
  config.password_length = 4..72

  # Email regex used to validate email formats. It simply asserts that
  # one (and only one) @ exists in the given string. This is mainly
  # to give user feedback and not to assert the e-mail validity.
  # config.email_regexp = /\A[^@]+@[^@]+\z/

  # ==> Configuration for :timeoutable
  # The time you want to timeout the user session without activity. After this
  # time the user will be asked for credentials again. Default is 30 minutes.
  # config.timeout_in = 30.minutes

  # ==> Configuration for :lockable
  # Defines which strategy will be used to lock an account.
  # :failed_attempts = Locks an account after a number of failed attempts to sign in.
  # :none            = No lock strategy. You should handle locking by yourself.
  # config.lock_strategy = :failed_attempts

  # Defines which key will be used when locking and unlocking an account
  # config.unlock_keys = [:email]

  # Defines which strategy will be used to unlock an account.
  # :email = Sends an unlock link to the user email
  # :time  = Re-enables login after a certain amount of time (see :unlock_in below)
  # :both  = Enables both strategies
  # :none  = No unlock strategy. You should handle unlocking by yourself.
  # config.unlock_strategy = :both

  # Number of authentication tries before locking an account if lock_strategy
  # is failed attempts.
  # config.maximum_attempts = 20

  # Time interval to unlock the account if :time is enabled as unlock_strategy.
  # config.unlock_in = 1.hour

  # Warn on the last attempt before the account is locked.
  # config.last_attempt_warning = true

  # ==> Configuration for :recoverable
  #
  # Defines which key will be used when recovering the password for an account
  # config.reset_password_keys = [:email]

  # Time interval you can reset your password with a reset password key.
  # Don't put a too small interval or your users won't have the time to
  # change their passwords.
  config.reset_password_within = 6.hours

  # When set to false, does not sign a user in automatically after their password is
  # reset. Defaults to true, so a user is signed in automatically after a reset.
  # config.sign_in_after_reset_password = true

  # ==> Configuration for :encryptable
  # Allow you to use another encryption algorithm besides bcrypt (default). You can use
  # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
  # :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
  # and :restful_authentication_sha1 (then you should set stretches to 10, and copy
  # REST_AUTH_SITE_KEY to pepper).
  #
  # Require the `devise-encryptable` gem when using anything other than bcrypt
  # config.encryptor = :sha512

  # ==> Scopes configuration
  # Turn scoped views on. Before rendering "sessions/new", it will first check for
  # "users/sessions/new". It's turned off by default because it's slower if you
  # are using only default views.
  # config.scoped_views = false

  # Configure the default scope given to Warden. By default it's the first
  # devise role declared in your routes (usually :user).
  # config.default_scope = :user

  # Set this configuration to false if you want /users/sign_out to sign out
  # only the current scope. By default, Devise signs out all scopes.
  # config.sign_out_all_scopes = true

  # ==> Navigation configuration
  # Lists the formats that should be treated as navigational. Formats like
  # :html, should redirect to the sign in page when the user does not have
  # access, but formats like :xml or :json, should return 401.
  #
  # If you have any extra navigational formats, like :iphone or :mobile, you
  # should add them to the navigational formats lists.
  #
  # The "*/*" below is required to match Internet Explorer requests.
  # config.navigational_formats = ['*/*', :html]

  # The default HTTP method used to sign out a resource. Default is :delete.
  config.sign_out_via = :delete

  # ==> OmniAuth
  # Add a new OmniAuth provider. Check the wiki for more information on setting
  # up on your models and hooks.
  # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'

  # ==> Warden configuration
  # If you want to use other strategies, that are not supported by Devise, or
  # change the failure app, you can configure them inside the config.warden block.
  #
  # config.warden do |manager|
  #   manager.intercept_401 = false
  #   manager.default_strategies(scope: :user).unshift :some_external_strategy
  # end

  # ==> Mountable engine configurations
  # When using Devise inside an engine, let's call it `MyEngine`, and this engine
  # is mountable, there are some extra configurations to be taken into account.
  # The following options are available, assuming the engine is mounted as:
  #
  #     mount MyEngine, at: '/my_engine'
  #
  # The router that invoked `devise_for`, in the example above, would be:
  # config.router_name = :my_engine
  #
  # When using OmniAuth, Devise cannot automatically set OmniAuth path,
  # so you need to do it manually. For the users scope, it would be:
  # config.omniauth_path_prefix = '/my_engine/users/auth'
end


================================================
FILE: config/initializers/filter_parameter_logging.rb
================================================
# Be sure to restart your server when you modify this file.

# Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [:password]


================================================
FILE: config/initializers/inflections.rb
================================================
# Be sure to restart your server when you modify this file.

# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
#   inflect.plural /^(ox)$/i, '\1en'
#   inflect.singular /^(ox)en/i, '\1'
#   inflect.irregular 'person', 'people'
#   inflect.uncountable %w( fish sheep )
# end

# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
#   inflect.acronym 'RESTful'
# end


================================================
FILE: config/initializers/mime_types.rb
================================================
# Be sure to restart your server when you modify this file.

# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf


================================================
FILE: config/initializers/session_store.rb
================================================
# Be sure to restart your server when you modify this file.

Rails.application.config.session_store :cookie_store, key: '_chibineko_session'


================================================
FILE: config/initializers/time_formats.rb
================================================


================================================
FILE: config/initializers/wrap_parameters.rb
================================================
# Be sure to restart your server when you modify this file.

# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.

# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
end

# To enable root element in JSON for ActiveRecord objects.
# ActiveSupport.on_load(:active_record) do
#  self.include_root_in_json = true
# end


================================================
FILE: config/locales/devise.en.yml
================================================
# Additional translations at https://github.com/plataformatec/devise/wiki/I18n

en:
  devise:
    confirmations:
      confirmed: "Your email address has been successfully confirmed."
      send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
      send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
    failure:
      already_authenticated: "You are already signed in."
      inactive: "Your account is not activated yet."
      invalid: "Invalid email or password."
      locked: "Your account is locked."
      last_attempt: "You have one more attempt before your account is locked."
      not_found_in_database: "Invalid email or password."
      timeout: "Your session expired. Please sign in again to continue."
      unauthenticated: "You need to sign in or sign up before continuing."
      unconfirmedX: "You have to confirm your email address before continuing."
    mailer:
      confirmation_instructions:
        subject: "[Chibineko] Confirmation instructions"
      reset_password_instructions:
        subject: "[Chibineko] Reset password instructions"
      unlock_instructions:
        subject: "[Chibineko] Unlock instructions"
      password_change:
        subject: "[Chibineko] Password Changed"
    omniauth_callbacks:
      failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
      success: "Successfully authenticated from %{kind} account."
    passwords:
      no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
      send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
      send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
      updated: "Your password has been changed successfully. You are now signed in."
      updated_not_active: "Your password has been changed successfully."
    registrations:
      destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
      signed_up: "Welcome! You have signed up successfully."
      signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
      signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
      signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
      update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address."
      updated: "Your account has been updated successfully."
    sessions:
      signed_in: "Signed in successfully."
      signed_out: "Signed out successfully."
      already_signed_out: "Signed out successfully."
    unlocks:
      send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
      send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
      unlocked: "Your account has been unlocked successfully. Please sign in to continue."
  errors:
    messages:
      already_confirmed: "was already confirmed, please try signing in"
      confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
      expired: "has expired, please request a new one"
      not_found: "not found"
      not_locked: "was not locked"
      not_saved: "could not be processed"

================================================
FILE: config/locales/devise.ja.yml
================================================
# Additional translations at https://github.com/plataformatec/devise/wiki/I18n

ja:
  devise:
    confirmations:
      confirmed: "メールアドレスの確認が完了しました"
      send_instructions: "アカウントの有効化についてメールを送信しました"
      send_paranoid_instructions: "あなたのメールアドレスが登録済みの場合、本人確認用のメールが数分以内に送信されます"
    failure:
      already_authenticated: "すでにログインしています"
      inactive: "アカウントが有効化されていません。メールに記載された手順にしたがって、アカウントを有効化してください"
      invalid: "メールアドレスもしくはパスワードが正しくありません"
      locked: "あなたのアカウントは凍結されています"
      last_attempt: "あなたのアカウントが凍結される前に、複数回の操作がおこなわれています"
      not_found_in_database: "メールアドレスもしくはパスワードが正しくありません"
      timeout: "セッションがタイムアウトしました。もう一度ログインしてください"
      unauthenticated: "アカウント登録もしくはログインしてください"
      unconfirmed: "メールアドレスの認証が完了していません。送信されたメールの内容を確認してください"
    mailer:
      confirmation_instructions:
        subject: "[Chibineko] アカウントの有効化について"
      reset_password_instructions:
        subject: "[Chibineko] パスワードの再設定について"
      unlock_instructions:
        subject: "[Chibineko] アカウントの凍結解除について"
      password_change:
        subject: "[Chibineko] パスワードが変更されました"
    omniauth_callbacks:
      failure: "%{kind} アカウントによる認証に失敗しました。理由:(%{reason})"
      success: "%{kind} アカウントによる認証に成功しました"
    passwords:
      no_token: "このページにはアクセスできません。パスワード再設定メールのリンクからアクセスされた場合には、URL をご確認ください"
      send_instructions: "パスワードの再設定について数分以内にメールでご連絡いたします"
      send_paranoid_instructions: "あなたのメールアドレスが登録済みの場合、パスワード再設定用のメールが数分以内に送信されます"
      updated: "パスワードが正しく変更されました"
      updated_not_active: "パスワードが正しく変更されました"
    registrations:
      destroyed: "アカウントを削除しました。またのご利用をお待ちしております"
      signed_up: "アカウント登録が完了しました"
      signed_up_but_inactive: "ログインするためには、アカウントを有効化してください"
      signed_up_but_locked: "アカウントが凍結されているためログインできません"
      signed_up_but_unconfirmed: "本人確認用のメールを送信しました。メール内のリンクからアカウントを有効化させてください"
      update_needs_confirmation: "アカウント情報を変更しました。変更されたメールアドレスの本人確認のため、本人確認用メールより確認処理をおこなってください"
      updated: "アカウント情報を変更しました"
    sessions:
      signed_in: "ログインしました"
      signed_out: "ログアウトしました"
      already_signed_out: "既にログアウト済みです"
    unlocks:
      send_instructions: "アカウントの凍結解除方法を数分以内にメールでご連絡します"
      send_paranoid_instructions: "アカウントが見つかった場合、アカウントの凍結解除方法を数分以内にメールでご連絡します"
      unlocked: "アカウントを凍結解除しました"
  errors:
    messages:
      already_confirmed: "は既に登録済みです。ログインしてください"
      confirmation_period_expired: "の期限が切れました。%{period} までに確認する必要があります。 新しくリクエストしてください"
      expired: "の有効期限が切れました。新しくリクエストしてください"
      not_found: "が見つかりませんでした"
      not_locked: "は凍結されていません"
      not_saved: "処理できませんでした"

================================================
FILE: config/locales/devise_view.en.yml
================================================
en:
  devise:
    registrations:
      new:
        sign_up: "Sign up"
        not_receive: "Didn't receive confirmation instructions?"
    confirmations:
      new:
        resend_confirmation: "Resend confirmation instructions"
        send_mail: "Send mail"
    sessions:
      new:
        sign_in: "Sign in"
        remember_password: "Remember password"
    passwords:
      new:
        forgot_password: "Forgot password"
        send_mail: "Send mail"

================================================
FILE: config/locales/devise_view.ja.yml
================================================
ja:
  devise:
    registrations:
      new:
        sign_up: "ユーザー登録"
        not_receive: "登録確認メールが届かない方はこちら"
    confirmations:
      new:
        resend_confirmation: "登録確認メールを再送信"
        send_mail: "メールを送信"
    sessions:
      new:
        sign_in: "ログイン"
        remember_password: "パスワードを忘れた場合はこちら"
    passwords:
      new:
        forgot_password: "パスワードを再設定"
        send_mail: "メールを送信"

================================================
FILE: config/locales/en.yml
================================================
en:
  language_name: "English"

  common:
    created_by: "Created by"
    updated_at: "Updated at"
    updated_on: "Updated on"
    dashboard: "Dashboard"
    team: "Team"
    project: "Project"
    you: "You"
    guest: "Guest user"
    button:
      new_team: "New team"
      create_new_team: "Create a new team"
      new_project: "New project"
      create_new_project: "Create a new project"
      new_test: "New test"
      create_new_test: "Create a new test"
      sign_in: "Sign in"
      sign_out: "Sign out"
      sign_up: "Sign up"
      expand: "edit"
      close: "close"
      move: "Move"
      delete: "Delete"

  helpers:
    submit:
      create: "Create"
      submit: "Save"
      update: "Update"
      test:
        create: "Create test"
        update: "Update test"

  dialog:
    done: "Done"
    close: "Close"
    cancel: "Cancel"

  time:
    formats:
      default: "%a, %d %b %Y %H:%M:%S %z"
      long: "%B %d, %Y %H:%M"
      short: "%d %b %H:%M"

  activerecord:
    models:
      user: "User"
      team: "Team"
      project: "Project"
    attributes:
      user:
        email: "Email"
        current_password: "Current password"
        password: "Password"
        password_confirmation: "Password confirmation"
        name: "User name"
      team:
        name: "Team name"
      project:
        name: "Project name"
      test:
        title: "Title"
    errors:
      models:
        team:
          invalid: "may only contain letters (a-z), numbers, and underscores."
        project:
          invalid: "may only contain letters (a-z), numbers, and underscores."
      messages:
        too_short: "does not meet our requirements. (At least %{count} characters long)."
        too_long: "does not meet our requirements. (At most %{count} characters long)."
        taken: "has already been taken."
        invalid: "is invalid."
        confirmation: "doesn't match."

  errors:
    format: "%{attribute} %{message}"
    forbidden: "You are not authorized to view this directory or page. Please contact team admin."

  messages:
    delete_confirm: "Are you sure? You can't undo the operation."
    public_test_html: "This test can be accessed by anyone who knows the URL. Use the team features If you need to limit the access."
    created_by_guest_html: "Because this test was created by a guest user, some features such as editing and deleting of the test items are limited."
    please_association_html: "To user all features, log in and correlate to the user."
    attach_current_user: "Correlate to the current user"

  layouts:
    navbar:
      github_page: "GitHub page"
    root_sidebar:
      create_team: "Create a new team"
    dashboard_sidebar:
      your_test: "Your test"
      coach_mark: "Create a team HERE !"
    main_menu:
      account_settings: "Account settings"
      team_settings: "Team settings"
      edit_members: "Edit team members"

  static_pages:
    top:
      branding:
        title: "The simplest test supporting tool"
        sub_title: "Chibineko is a simple test supporting tool specializing in the management of manual tests"
        get_started: "Get Started"
        sign_up_free: "Sign Up for Free"
      feature:
        title: "Feature"
        test_management_title: "Test Management"
        test_management_body: "Chibineko supports your manual testing with its useful functions like test case creation, test execution, and progress management. Its simple design expands the usability in various situations."
        team_management_title: "Team"
        team_management_body: "With \"Team\" feature, you can share your test data among limited users. It enables you to secure your data information and manage test cases effectively."
        share_result_title: "Share"
        share_result_body: "Each test case has its individual URL. How do you share your test data with other users? All you need is to share the URL, you don't need to exchange any files any more."
        oss_title: "OSS"
        oss_body: "Our sourse code is available on GitHub. If you want to add some functions, feel free to extend. Issue and Pull Request will also be welcome."
      support: "Support"
      terms: "Terms of Service"
      releases: "Releases"
      roadmap: "Roadmap"

  dashboard:
    index:
      title: "Dashboard"
      navbar:
        new_test: "Create a new test"

  teams:
    show:
      empty_message: "No Projects"
    new:
      title: "New team"
      enter_name: "Enter team name"
    settings:
      title: "Team settings"
      name:
        title: "Team name"
        current_value_html: "Current team name: <strong>%{name}</strong>"
      delete:
        title: "Delete a team"
        description: "When you delete a team, all of the related data such as projects and tests are also deleted."
        delete_team: "Delete this team"
    messages:
      destroy: "The team has been successfully deleted."

  team_users:
    index:
      title: "Edit team members"
      search_user: "Search Chibineko user:"
      add_user: "Add this user to the team"
      delete_confirm: "Do you remove the user from the team members?"

  projects:
    navbar:
      menu:
        project_settings: "Project settings"
    show:
      empty_message: "No Tests"
    new:
      title: "New project"
      enter_name: "Enter project name"
    settings:
      title: "Project settings"
      name:
        title: "Project name"
        current_value_html: "Current project name:: <strong>%{name}</strong>"
      delete:
        title: "Delete a project"
        description: "When you delete a project, all of the related tests are also deleted."
        delete_project: "Delete this project"
    messages:
      destroy: "Project has been successfully deleted."

  tests:
    show:
      blank_description: "No description"
      created_by: "This test was created by %{username} (Updated at: %{updated_at})"
    form:
      title:
        new: "Create a new test"
        edit: "Edit test"
      title_placeholder: "Enter test title"
      markdown_header: "Test items"
      markdown_placeholder: "Itemize test cases"
      preview_header: "Preview"
    description:
      title: "Edit description"
    testcase:
      note: "Notes"
      collapse_all: "Collapse all"
      expand_all: "Expand all"
    move:
      title: "Move to"
      unset_project: "No projects"
      submit: "Move"
    result_label:
      title: "Customize result labels"
      use_default_label: "Use the default labels"
      label_placeholder: "Enter labels"
    navbar:
      edit_test: "Edit test"
      edit_current_test: "Edit the current test"
      export_csv: "Export CSV"
      test_settings: "Test settings"
      duplicate_test: "Duplicate this test"
      move_to: "Move to"
      customize_result_label: "Customize result labels"
      delete_test: "Delete this test"
    messages:
      destroy: "The test has been successfully deleted."
    result_labels:
      unexecuted: "NOT RUN"
      pass: "PASS"
      fail: "FAIL"
      blocked: "BLOCKED"
      na: "N/A"
    csv:
      case: "Test cases"
      result: "Results"
      note: "Notes"

  user_settings:
    modal:
      title: "Account settings"
      expand: "edit"
      close: "close"
      username:
        title: "User name"
        blank: "E-mail address is used as an user name until a new name is entered."
        current_value_html: "Your user name is <strong>%{username}</strong>"
      password:
        title: "Password"
        change_password: "Change sign in password"
        current_password: "Current password"
        new_password: "New password"
        confirm_password: "Confirm new password"
        update: "Update Password"
      timezone:
        title: "Time Zone"
        current_value_html: "Your current time zone: <strong>%{timezone}</strong>"
        update: "Save Time Zone"
      language:
        title: "Language"
        current_value_html: "Your current language: <strong>%{language}</strong>"

================================================
FILE: config/locales/ja.yml
================================================
ja:
  language_name: "日本語"

  common:
    created_by: "作成者"
    updated_at: "更新日時"
    updated_on: "更新日"
    dashboard: "ダッシュボード"
    team: "チーム"
    project: "プロジェクト"
    you: "あなた"
    guest: "ゲスト"
    button:
      new_team: "新規チーム"
      create_new_team: "新しいチームを作成"
      new_project: "新規プロジェクト"
      create_new_project: "新しいプロジェクトを作成"
      new_test: "新規テスト"
      create_new_test: "新しいテストを作成"
      sign_in: "ログイン"
      sign_out: "ログアウト"
      sign_up: "ユーザー登録"
      expand: "編集"
      close: "閉じる"
      move: "移動"
      delete: "削除"

  helpers:
    submit:
      create: "作成"
      submit: "保存"
      update: "更新"
      test:
        create: "テストを作成"
        update: "テストを更新"

  dialog:
    done: "完了"
    close: "閉じる"
    cancel: "キャンセル"

  time:
    formats:
      default: "%Y/%m/%d %H:%M:%S"
      long: "%Y年%m月%d日(%a) %H時%M分%S秒 %z"
      short: "%y/%m/%d %H:%M"

  activerecord:
    models:
      user: "ユーザー"
      team: "チーム"
      project: "プロジェクト"
    attributes:
      user:
        email: "メールアドレス"
        current_password: "現在のパスワード"
        password: "パスワード"
        password_confirmation: "パスワード(確認)"
        name: "ユーザー名"
      team:
        name: "チーム名"
      project:
        name: "プロジェクト名"
      test:
        title: "タイトル"
    errors:
      models:
        team:
          invalid: "は半角英数字かアンダースコアで入力してください"
        project:
          invalid: "は半角英数字かアンダースコアで入力してください"
      messages:
        too_short: "は%{count}文字以上で入力してください"
        too_long: "は%{count}文字以内で入力してください"
        taken: "はすでに存在します"
        invalid: "は不正な値です"
        confirmation: "が一致しません"

  errors:
    format: "%{attribute}%{message}"
    forbidden: "アクセスする権限がありません。チーム管理者に問い合わせてください。"

  messages:
    delete_confirm: "本当に削除しますか?この操作は取り消せません。"
    public_test_html: "このテストは<strong>URLを知っているユーザーなら誰でもアクセスできます</strong>。アクセスできるユーザーを制限したい場合は<strong>チーム機能</strong>をご利用ください。"
    created_by_guest_html: "このテストはゲストユーザーによって作成されたため、<strong>テスト項目の編集や削除など一部機能が制限</strong>されています。"
    please_association_html: "すべての機能を使用したい場合は、ログインして<strong>ユーザーとの紐付け</strong>を行ってください。"
    attach_current_user: "現在のユーザーに紐付ける"

  layouts:
    navbar:
      github_page: "GitHubページ"
    root_sidebar:
      create_team: "新しいチームを作成"
    dashboard_sidebar:
      your_test: "あなたのテスト"
      coach_mark: "チーム作成はこちら"
    main_menu:
      account_settings: "アカウント設定"
      team_settings: "チーム設定"
      edit_members: "チームメンバーを編集"

  static_pages:
    top:
      branding:
        title: "世界で最もシンプルなテスト支援ツール"
        sub_title: "Chibinekoはマニュアルテストの管理に特化したシンプルなテストツールです"
        get_started: "今すぐはじめる"
        sign_up_free: "無料でサインアップ"
      feature:
        title: "機能"
        test_management_title: "テスト管理"
        test_management_body: "テストケース作成、テスト実行、進捗管理など、マニュアルテストに必要な一通りの機能を提供します。シンプルがゆえに自由度が高いため、様々なシーンで活用いただけます。"
        team_management_title: "チーム管理"
        team_management_body: "チームを作成してユーザーをアサインすれば、限られたユーザーのみでテスト内容を共有することができます。セキュリティを保ちつつ効率的にテストケースを管理することができます。"
        share_result_title: "結果の共有"
        share_result_body: "テストケースにはユニークなURLが割り当てられるため、他のユーザーとテスト結果を共有したい場合はURLをシェアするだけ。面倒なファイルのやり取りなどは不要です。"
        oss_title: "OSS"
        oss_body: "このサービスのソースコードはすべてGitHub上で公開されています。もし足りない機能がある場合は、自由に拡張してください。issueやPull Requestも歓迎します。"
      support: "サポート"
      terms: "利用規約"
      releases: "リリースノート"
      roadmap: "ロードマップ"

  dashboard:
    index:
      title: "ダッシュボード"
      navbar:
        new_test: "新しいテストを作成"

  teams:
    show:
      empty_message: "プロジェクトがまだありません"
    new:
      title: "新しいチーム"
      enter_name: "チーム名を入力"
    settings:
      title: "チーム設定"
      name:
        title: "チーム名"
        current_value_html: "現在のチーム名: <strong>%{name}</strong>"
      delete:
        title: "チームを削除"
        description: "チームを削除すると、チームに含まれるプロジェクトおよびテストもすべて削除されます。"
        delete_team: "このチームを削除する"
    messages:
      destroy: "チームを削除しました"

  team_users:
    index:
      title: "チームメンバーを編集"
      search_user: "Chibinekoユーザーを検索:"
      add_user: "ユーザーをチームに追加"
      delete_confirm: "チームメンバーから削除しますか?"

  projects:
    navbar:
      menu:
        project_settings: "プロジェクト設定"
    show:
      empty_message: "テストがまだありません"
    new:
      title: "新しいプロジェクト"
      enter_name: "プロジェクト名を入力"
    settings:
      title: "プロジェクト設定"
      name:
        title: "プロジェクト名"
        current_value_html: "現在のプロジェクト名: <strong>%{name}</strong>"
      delete:
        title: "プロジェクトを削除"
        description: "プロジェクトを削除すると、プロジェクトに含まれるテストもすべて削除されます。"
        delete_project: "このプロジェクトを削除する"
    messages:
      destroy: "プロジェクトを削除しました"

  tests:
    show:
      blank_description: "説明が入力されていません"
      created_by: "このテストは %{username} によって作成されました(更新日時: %{updated_at})"
    form:
      title:
        new: "新しいテストを作成"
        edit: "テストを編集"
      title_placeholder: "タイトルを入力"
      markdown_header: "テスト項目"
      markdown_placeholder: "テスト項目を箇条書きで入力"
      preview_header: "プレビュー"
    description:
      title: "説明を編集"
    testcase:
      note: "メモ"
      collapse_all: "折りたたむ"
      expand_all: "すべて展開"
    move:
      title: "テストを移動"
      unset_project: "プロジェクト未設定"
      submit: "移動"
    result_label:
      title: "結果ラベルをカスタマイズ"
      use_default_label: "デフォルトラベルを使用"
      label_placeholder: "ラベルを入力"
    navbar:
      edit_test: "テストを編集"
      edit_current_test: "現在のテストを編集"
      export_csv: "CSVエクスポート"
      test_settings: "テスト設定"
      duplicate_test: "このテストを複製"
      move_to: "別プロジェクトへ移動"
      customize_result_label: "結果ラベルをカスタマイズ"
      delete_test: "このテストを削除"
    messages:
      destroy: "テストを削除しました"
    result_labels:
      unexecuted: "未実行"
      pass: "OK"
      fail: "NG"
      blocked: "保留"
      na: "対象外"
    csv:
      case: "テスト項目"
      result: "結果"
      note: "備考"

  user_settings:
    modal:
      title: "アカウント設定"
      expand: "編集"
      close: "閉じる"
      username:
        title: "ユーザー名"
        blank: "ユーザー名が未設定の場合、メールアドレスがユーザー名として表示されます"
        current_value_html: "あなたのユーザー名: <strong>%{username}</strong>"
      password:
        title: "パスワード"
        change_password: "ログインパスワードを変更します"
        current_password: "現在のパスワード"
        new_password: "新しいパスワード"
        confirm_password: "新しいパスワード(確認)"
        update: "パスワードを更新"
      timezone:
        title: "タイムゾーン"
        current_value_html: "現在のタイムゾーン: <strong>%{timezone}</strong>"
        update: "タイムゾーンを保存"
      language:
        title: "言語"
        current_value_html: "現在の言語: <strong>%{language}</strong>"

================================================
FILE: config/locales/js.en.yml
================================================
en:
  js:
    team_sidebar:
      edit_members:
        search_user: "Search user..."
        add_user: "Add this user to the team"
        not_found: "User not found"
        unknown_error: "Unknown error"
    tests:
      show:
        errors:
          conflict: "Test cases might have been editted by other uses."
          please_reload: "Reload the page"
      new:
        messages:
          unsaved_changes: "You have unsaved changes."
      edit_result_label:
        errors:
          too_short: "You can not delete any more."
          too_long: "You can not add any more."
      navbar:
        total: "Total"
      toolbar:
        selected: "selected"
    bootgrid:
      loading: "Loading..."
      no_results: "No results found."
      search: "Search by title"
    common:
      messages:
        delete_confirm: "Are you sure? You can't undo the operation."
      collapse:
        expand: "edit"
        close: "close"
      ladda:
        saving: "saving..."
        processing: "processing..."

================================================
FILE: config/locales/js.ja.yml
================================================
ja:
  js:
    team_sidebar:
      edit_members:
        search_user: "検索中..."
        add_user: "ユーザーをチームに追加"
        not_found: "ユーザーが見つかりません"
        unknown_error: "エラーが発生しました"
    tests:
      show:
        errors:
          conflict: "テスト項目が他のユーザーによって変更された可能性があります"
          please_reload: "ページをリロードしてください"
      new:
        messages:
          unsaved_changes: "変更内容が保存されていません。"
      edit_result_label:
        errors:
          too_short: "これ以上削除できません。"
          too_long: "これ以上追加できません。"
      navbar:
        total: "合計"
      toolbar:
        selected: "件選択中"
    bootgrid:
      loading: "読み込み中..."
      no_results: "検索結果がありません"
      search: "タイトルで検索"
    common:
      messages:
        delete_confirm: "本当に削除しますか?この操作は取り消せません。"
      collapse:
        expand: "編集"
        close: "閉じる"
      ladda:
        saving: "保存中..."
        processing: "処理中..."

================================================
FILE: config/locales/terms.en.yml
================================================
en:
  static_pages:
    terms:
      title: "Terms of Service"
      body_html: |
        <p>Last modified: January 20, 2015</p>

        <h2>Article 1. Using our Services</h2>

        <ol>
          <li>These Terms and Conditions (the "Terms") set forth the terms between SHIFT Inc.(“SHIFT”) regarding the usage of the service under the name of "Chibineko" (the "Service") provided by SHIFT. The User shall use the Services in accordance with the contents of the Terms.</li>
          <li>The Terms apply to all acts of Users in their use of the service.</li>
          <li>Users are considered to have agreed to all the content stated in the Terms upon using the service.</li>
        </ol>

        <h2>Article 2. Definition</h2>

        <ol>
          <li>"Chibineko" means the WEB service (<a href="https://chibineko.jp">https://chibineko.jp</a>) that SHIFT owns and operates. Chibineko includes the followings:<br>
          (a) similar or related Chibineko Website (including subdomain, different languages, widgets, smartphones, and so on), (b) a platform operated by SHIFT, (c) social plug ins, (d) software (e.g. toolbar), devices, and networks, existing or not-yet existing.</li>
          <li>"The other Terms and regulations" mean agreements other than the Agreement that specify the Terms of  the Services, regardless of their titles, including use agreements for fee-based services and use agreements for any other services.</li>
          <li>"Platform" means a set of APIs and services (such as contents) that enable others, including application developers and website operators, to retrieve data from Chibineko or provide data to us.</li>
          <li>"Information" mean facts and other information about you, including actions taken by Users and non-Users who interact with Chibineko.</li>
          <li>"Development Information" means programs, contents and materials related to software, Web sites, applications or the like that Users of the Services or others involved with Chibineko use this Services to  plan, develop, store and manage; records of development-related communication; information obtained by using any of the Services; facts or the like of their being engaged in development; and any other development-related facts or information.</li>
          <li>"Other contents" mean every information posted by Users and the third parties, and it.</li>
          <li>"User information" mean the information related to Users, development information, and  all or a part of other contents.</li>
          <li>"data" means any data, including a user's contents or information that you or a third party can retrieve from Chibineko or provide to Chibineko through Platform.</li>
          <li>"post" means to post on Chibineko or otherwise make available by using Chibineko.</li>
          <li>"use" means to use, run, copy, publicly perform or display, distribute, modify, translate, and create derivative works of.</li>
        </ol>

        <h2>Article 3.  Scope of the Terms</h2>

        <ol>
          <li>The conditions of the Service use is published in the Terms and other Terms and regulations.  The Other Terms of Use shall make-up a part of the Terms, regardless of the title.</li>
          <li>If provisions of the Term and the other Terms (and regulations) are not consistent, the Term shall prevail the other Terms.</li>
        </ol>

        <h2>Article 4.  Changes of the Terms</h2>

        <ol>
          <li>SHIFT reserves the right to change the Terms at its discretion without providing prior notice to Users.</li>
          <li>The modification will become effective once the modified Terms are posted on an appropriate location within Chibineko Website, unless otherwise specified by SHIFT.</li>
          <li>Users shall be deemed to have granted valid and irrevocable consent to the modified Terms by continuing to use the Service.</li>
        </ol>

        <h2>Article 5. Responsibility of Uses</h2>

        <ol>
          <li>SHIFT believes Users’ privacy is very important.</li>
          <li>SHIFT handles personal information properly based on our <a href="http://www.shiftinc.jp/en/privacy/">privacy policy</a>.</li>
        </ol>

        <h2>Article 6. Preparation of Computer Environment</h2>

        <ol>
          <li>Users shall supply the necessary computer environment (hardware, software, data connection) for using the Service under Users' own responsibility and at Users' own expense.</li>
          <li>Users shall, with its own costs and responsibilities, prepare and maintain security systems suitable for the Users' environment for use of the Service to avoid computer virus attacks, unauthorized access, information leakage, etc.</li>
          <li>SHIFT will not be responsible for preparation of computer environment.</li>
        </ol>

        <h2>Article 7. Users' Responsibility</h2>

        <ol>
          <li>Users use this service on their own responsibility.</li>
          <li>Users are responsible for all the information they provide to this service.  SHIFT is not responsible for the information.</li>
          <li>The User understands that SHIFT is not responsible for damages and loss of the data, and the User shall ta
Download .txt
gitextract_t1ykuj_k/

├── .gitignore
├── .rspec
├── Gemfile
├── LICENSE
├── README.md
├── Rakefile
├── app/
│   ├── assets/
│   │   ├── images/
│   │   │   └── .keep
│   │   ├── javascripts/
│   │   │   ├── application.coffee
│   │   │   ├── dashboards.coffee
│   │   │   ├── data_table.coffee
│   │   │   ├── move_tests.coffee
│   │   │   ├── projects.coffee
│   │   │   ├── static_pages.coffee
│   │   │   ├── team_users.coffee
│   │   │   ├── teams.coffee
│   │   │   ├── test_preview.coffee
│   │   │   ├── tests.coffee
│   │   │   └── validation.coffee
│   │   └── stylesheets/
│   │       ├── application.scss
│   │       ├── bootstrap_overrides.scss
│   │       ├── color.scss
│   │       ├── common.scss
│   │       ├── data_table.scss
│   │       ├── layouts/
│   │       │   ├── navbar.scss
│   │       │   ├── sidebar.scss
│   │       │   └── style.scss
│   │       ├── static_pages/
│   │       │   ├── terms.scss
│   │       │   └── top.scss
│   │       ├── teams/
│   │       │   └── team_users.scss
│   │       ├── tests/
│   │       │   ├── edit_result_label.scss
│   │       │   ├── form.scss
│   │       │   ├── move.scss
│   │       │   ├── show.scss
│   │       │   └── testcase.scss
│   │       ├── toastr_overrides.scss
│   │       └── vendor/
│   │           ├── best_in_place.scss
│   │           ├── bootgrid.scss
│   │           └── ladda.scss
│   ├── controllers/
│   │   ├── application_controller.rb
│   │   ├── concerns/
│   │   │   └── .keep
│   │   ├── dashboard_controller.rb
│   │   ├── projects_controller.rb
│   │   ├── static_pages_controller.rb
│   │   ├── team_users_controller.rb
│   │   ├── teams_controller.rb
│   │   ├── testcases_controller.rb
│   │   ├── tests_controller.rb
│   │   ├── user_settings_controller.rb
│   │   └── users/
│   │       └── registrations_controller.rb
│   ├── helpers/
│   │   ├── application_helper.rb
│   │   ├── dashboard_helper.rb
│   │   ├── projects_helper.rb
│   │   ├── static_pages_helper.rb
│   │   ├── team_users_helper.rb
│   │   ├── teams_helper.rb
│   │   └── tests_helper.rb
│   ├── mailers/
│   │   └── .keep
│   ├── models/
│   │   ├── .keep
│   │   ├── concerns/
│   │   │   └── .keep
│   │   ├── project.rb
│   │   ├── team.rb
│   │   ├── team_user.rb
│   │   ├── test.rb
│   │   ├── testcase.rb
│   │   └── user.rb
│   └── views/
│       ├── dashboard/
│       │   ├── _navbar.html.slim
│       │   └── index.html.slim
│       ├── devise/
│       │   ├── confirmations/
│       │   │   └── new.html.slim
│       │   ├── mailer/
│       │   │   ├── confirmation_instructions.en.html.slim
│       │   │   ├── confirmation_instructions.ja.html.slim
│       │   │   ├── password_change.html.erb
│       │   │   ├── reset_password_instructions.en.html.slim
│       │   │   └── reset_password_instructions.ja.html.slim
│       │   ├── passwords/
│       │   │   └── new.html.slim
│       │   ├── registrations/
│       │   │   └── new.html.slim
│       │   ├── sessions/
│       │   │   └── new.html.slim
│       │   └── shared/
│       │       └── _links.html.erb
│       ├── layouts/
│       │   ├── _dashboard_sidebar.html.slim
│       │   ├── _logo.html.slim
│       │   ├── _main_menu.html.slim
│       │   ├── _navbar.html.slim
│       │   ├── _root_sidebar.html.slim
│       │   ├── _sign_in_link.html.slim
│       │   ├── _sign_out_link.html.slim
│       │   ├── _sign_up_link.html.slim
│       │   ├── _team_sidebar.html.slim
│       │   └── application.html.slim
│       ├── projects/
│       │   ├── _navbar.html.slim
│       │   ├── _new.html.slim
│       │   ├── _save.js.erb
│       │   ├── _settings.html.slim
│       │   ├── create.js.erb
│       │   ├── new.js.erb
│       │   ├── settings.js.erb
│       │   ├── show.html.slim
│       │   └── update.js.erb
│       ├── static_pages/
│       │   ├── terms.html.slim
│       │   └── top.html.slim
│       ├── team_users/
│       │   ├── _index.html.slim
│       │   ├── _save.js.erb
│       │   ├── create.js.erb
│       │   ├── destroy.js.erb
│       │   └── index.js.erb
│       ├── teams/
│       │   ├── _new.html.slim
│       │   ├── _save.js.erb
│       │   ├── _settings.html.slim
│       │   ├── create.js.erb
│       │   ├── new.js.erb
│       │   ├── settings.js.erb
│       │   ├── show.html.slim
│       │   └── update.js.erb
│       ├── tests/
│       │   ├── _alert.html.slim
│       │   ├── _cheatsheet.en.html.slim
│       │   ├── _cheatsheet.ja.html.slim
│       │   ├── _description.html.slim
│       │   ├── _form.html.slim
│       │   ├── _move.html.slim
│       │   ├── _navbar.html.slim
│       │   ├── _result_label.html.slim
│       │   ├── _table_toolbar.html.slim
│       │   ├── _testcase.html.slim
│       │   ├── bulk_destroy.js.erb
│       │   ├── bulk_move.js.erb
│       │   ├── create.js.erb
│       │   ├── description.js.erb
│       │   ├── edit.html.slim
│       │   ├── move.js.erb
│       │   ├── new.html.slim
│       │   ├── result_label.js.erb
│       │   ├── show.csv.ruby
│       │   ├── show.html.slim
│       │   ├── update.js.erb
│       │   └── update_result_label.js.erb
│       └── user_settings/
│           ├── _modal.html.slim
│           ├── edit.js.erb
│           └── update.js.erb
├── bin/
│   ├── bundle
│   ├── rails
│   ├── rake
│   └── setup
├── circle.yml
├── config/
│   ├── application.rb
│   ├── boot.rb
│   ├── database.yml
│   ├── environment.rb
│   ├── environments/
│   │   ├── development.rb
│   │   ├── production.rb
│   │   └── test.rb
│   ├── i18n-js.yml
│   ├── initializers/
│   │   ├── action_mailer.rb
│   │   ├── assets.rb
│   │   ├── backtrace_silencers.rb
│   │   ├── cookies_serializer.rb
│   │   ├── devise.rb
│   │   ├── filter_parameter_logging.rb
│   │   ├── inflections.rb
│   │   ├── mime_types.rb
│   │   ├── session_store.rb
│   │   ├── time_formats.rb
│   │   └── wrap_parameters.rb
│   ├── locales/
│   │   ├── devise.en.yml
│   │   ├── devise.ja.yml
│   │   ├── devise_view.en.yml
│   │   ├── devise_view.ja.yml
│   │   ├── en.yml
│   │   ├── ja.yml
│   │   ├── js.en.yml
│   │   ├── js.ja.yml
│   │   ├── terms.en.yml
│   │   └── terms.ja.yml
│   ├── mailer.yml.example
│   ├── routes.rb
│   └── secrets.yml
├── config.ru
├── db/
│   ├── migrate/
│   │   ├── 20151224022612_devise_create_users.rb
│   │   ├── 20151224030646_create_teams.rb
│   │   ├── 20151225045046_create_projects.rb
│   │   ├── 20151225141534_create_tests.rb
│   │   ├── 20151226051709_create_testcases.rb
│   │   ├── 20160103121144_add_column_to_user.rb
│   │   ├── 20160109162956_create_team_users.rb
│   │   └── 20160319072222_add_created_at_index_to_test.rb
│   ├── schema.rb
│   └── seeds.rb
├── lib/
│   ├── assets/
│   │   └── .keep
│   └── tasks/
│       └── .keep
├── log/
│   └── .keep
├── public/
│   ├── 404.en.html
│   ├── 404.ja.html
│   ├── 422.en.html
│   ├── 422.ja.html
│   ├── 500.en.html
│   ├── 500.ja.html
│   ├── error.css
│   ├── javascripts/
│   │   └── translations.js
│   ├── maintenance.html
│   └── robots.txt
├── spec/
│   ├── factories/
│   │   ├── testcases.rb
│   │   └── tests.rb
│   ├── models/
│   │   ├── test_spec.rb
│   │   └── testcase_spec.rb
│   ├── rails_helper.rb
│   └── spec_helper.rb
└── vendor/
    └── assets/
        ├── javascripts/
        │   ├── .keep
        │   └── jquery.readyselector.js
        └── stylesheets/
            └── .keep
Download .txt
SYMBOL INDEX (130 symbols across 32 files)

FILE: app/controllers/application_controller.rb
  class ApplicationController (line 1) | class ApplicationController < ActionController::Base
    class Forbidden (line 7) | class Forbidden < ActionController::ActionControllerError; end
    method routing_error (line 9) | def routing_error
    method forbidden_error (line 13) | def forbidden_error
    method after_sign_in_path_for (line 17) | def after_sign_in_path_for(resource)
    method format_error_message (line 21) | def format_error_message(object)
    method set_locale (line 27) | def set_locale
    method set_timezone (line 43) | def set_timezone

FILE: app/controllers/dashboard_controller.rb
  class DashboardController (line 1) | class DashboardController < ApplicationController
    method index (line 4) | def index

FILE: app/controllers/projects_controller.rb
  class ProjectsController (line 1) | class ProjectsController < ApplicationController
    method show (line 5) | def show
    method new (line 9) | def new
    method edit (line 13) | def edit
    method create (line 16) | def create
    method update (line 28) | def update
    method destroy (line 34) | def destroy
    method settings (line 39) | def settings
    method set_project (line 43) | def set_project
    method authorize! (line 49) | def authorize!
    method project_params (line 54) | def project_params

FILE: app/controllers/static_pages_controller.rb
  class StaticPagesController (line 1) | class StaticPagesController < ApplicationController
    method top (line 2) | def top
    method terms (line 6) | def terms

FILE: app/controllers/team_users_controller.rb
  class TeamUsersController (line 1) | class TeamUsersController < ApplicationController
    method index (line 4) | def index
    method create (line 10) | def create
    method destroy (line 19) | def destroy
    method ajax_search_user (line 27) | def ajax_search_user

FILE: app/controllers/teams_controller.rb
  class TeamsController (line 1) | class TeamsController < ApplicationController
    method show (line 5) | def show
    method new (line 11) | def new
    method edit (line 15) | def edit
    method create (line 18) | def create
    method update (line 28) | def update
    method destroy (line 34) | def destroy
    method settings (line 39) | def settings
    method set_team (line 43) | def set_team
    method authorize! (line 48) | def authorize!
    method team_params (line 53) | def team_params

FILE: app/controllers/testcases_controller.rb
  class TestcasesController (line 1) | class TestcasesController < ApplicationController
    method update (line 4) | def update
    method set_testcase (line 14) | def set_testcase
    method testcase_params (line 23) | def testcase_params

FILE: app/controllers/tests_controller.rb
  class TestsController (line 1) | class TestsController < ApplicationController
    method index (line 5) | def index
    method show (line 9) | def show
    method new (line 25) | def new
    method edit (line 39) | def edit
    method create (line 45) | def create
    method update (line 63) | def update
    method destroy (line 70) | def destroy
    method description (line 82) | def description
    method result_label (line 85) | def result_label
    method update_result_label (line 88) | def update_result_label
    method move (line 100) | def move
    method bulk_move (line 104) | def bulk_move
    method bulk_destroy (line 121) | def bulk_destroy
    method user_association (line 130) | def user_association
    method set_test (line 136) | def set_test
    method authorize! (line 141) | def authorize!
    method test_params (line 149) | def test_params

FILE: app/controllers/user_settings_controller.rb
  class UserSettingsController (line 1) | class UserSettingsController < ApplicationController
    method edit (line 5) | def edit
    method update (line 8) | def update
    method set_user (line 15) | def set_user
    method user_params (line 19) | def user_params

FILE: app/controllers/users/registrations_controller.rb
  class Users::RegistrationsController (line 1) | class Users::RegistrationsController < Devise::RegistrationsController
    method edit (line 2) | def edit
    method update (line 6) | def update

FILE: app/helpers/application_helper.rb
  type ApplicationHelper (line 1) | module ApplicationHelper
    function controller_action (line 2) | def controller_action
    function color_names (line 6) | def color_names
    function page_title (line 10) | def page_title(title)

FILE: app/helpers/dashboard_helper.rb
  type DashboardHelper (line 1) | module DashboardHelper

FILE: app/helpers/projects_helper.rb
  type ProjectsHelper (line 1) | module ProjectsHelper
    function project_collection (line 2) | def project_collection
    function current_project (line 6) | def current_project

FILE: app/helpers/static_pages_helper.rb
  type StaticPagesHelper (line 1) | module StaticPagesHelper

FILE: app/helpers/team_users_helper.rb
  type TeamUsersHelper (line 1) | module TeamUsersHelper

FILE: app/helpers/teams_helper.rb
  type TeamsHelper (line 1) | module TeamsHelper
    function current_team (line 2) | def current_team

FILE: app/helpers/tests_helper.rb
  type TestsHelper (line 1) | module TestsHelper
    function current_test (line 2) | def current_test

FILE: app/models/project.rb
  class Project (line 1) | class Project < ActiveRecord::Base
    method to_param (line 12) | def to_param

FILE: app/models/team.rb
  class Team (line 1) | class Team < ActiveRecord::Base
    method authorized? (line 14) | def authorized?(user)
    method authorized! (line 18) | def authorized!(user)
    method to_param (line 22) | def to_param

FILE: app/models/team_user.rb
  class TeamUser (line 1) | class TeamUser < ActiveRecord::Base

FILE: app/models/test.rb
  class Test (line 1) | class Test < ActiveRecord::Base
    method to_param (line 12) | def to_param
    method authorized? (line 16) | def authorized?(user)
    method result_labels_or_default (line 24) | def result_labels_or_default
    method result_label_texts (line 35) | def result_label_texts
    method result_label_colors (line 39) | def result_label_colors
    method testcase_groups (line 43) | def testcase_groups
    method set_markdown (line 59) | def set_markdown(with_result = false)
    method make_testcase (line 84) | def make_testcase
    method set_slug (line 97) | def set_slug
    method generate_slug (line 101) | def generate_slug

FILE: app/models/testcase.rb
  class Testcase (line 1) | class Testcase < ActiveRecord::Base
    method type (line 8) | def type
    method result (line 19) | def result
    method result_color (line 23) | def result_color
    method heading_level (line 28) | def heading_level(text)
    method body (line 39) | def body(text)
    method result (line 54) | def result(text)
    method note (line 62) | def note(text)

FILE: app/models/user.rb
  class User (line 1) | class User < ActiveRecord::Base
    method display_name (line 15) | def display_name

FILE: config/application.rb
  type Chibineko (line 18) | module Chibineko
    class Application (line 19) | class Application < Rails::Application

FILE: db/migrate/20151224022612_devise_create_users.rb
  class DeviseCreateUsers (line 1) | class DeviseCreateUsers < ActiveRecord::Migration
    method change (line 2) | def change

FILE: db/migrate/20151224030646_create_teams.rb
  class CreateTeams (line 1) | class CreateTeams < ActiveRecord::Migration
    method change (line 2) | def change

FILE: db/migrate/20151225045046_create_projects.rb
  class CreateProjects (line 1) | class CreateProjects < ActiveRecord::Migration
    method change (line 2) | def change

FILE: db/migrate/20151225141534_create_tests.rb
  class CreateTests (line 1) | class CreateTests < ActiveRecord::Migration
    method change (line 2) | def change

FILE: db/migrate/20151226051709_create_testcases.rb
  class CreateTestcases (line 1) | class CreateTestcases < ActiveRecord::Migration
    method change (line 2) | def change

FILE: db/migrate/20160103121144_add_column_to_user.rb
  class AddColumnToUser (line 1) | class AddColumnToUser < ActiveRecord::Migration
    method change (line 2) | def change

FILE: db/migrate/20160109162956_create_team_users.rb
  class CreateTeamUsers (line 1) | class CreateTeamUsers < ActiveRecord::Migration
    method change (line 2) | def change

FILE: db/migrate/20160319072222_add_created_at_index_to_test.rb
  class AddCreatedAtIndexToTest (line 1) | class AddCreatedAtIndexToTest < ActiveRecord::Migration
    method change (line 2) | def change
Condensed preview — 206 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (283K chars).
[
  {
    "path": ".gitignore",
    "chars": 300,
    "preview": "# Ignore bundler config.\n/.bundle\n/vendor/bundle\n\n# Ignore mailer config.\n/config/mailer.yml\n\n# Ignore the default SQLit"
  },
  {
    "path": ".rspec",
    "chars": 30,
    "preview": "--color\n--require spec_helper\n"
  },
  {
    "path": "Gemfile",
    "chars": 1179,
    "preview": "source 'https://rubygems.org'\n\nruby '2.3.0'\n\ngem 'rails', '4.2.4'\ngem 'slim-rails', '~> 3.0.0'\ngem 'sass-rails', '~> 5.0"
  },
  {
    "path": "LICENSE",
    "chars": 11410,
    "preview": "Copyright 2016 SHIFT, Inc. All rights reserved.\n\n                                 Apache License\n                       "
  },
  {
    "path": "README.md",
    "chars": 2531,
    "preview": "# Chibineko\n[![CircleCI](https://circleci.com/gh/tabbyz/chibineko.svg?style=shield)](https://circleci.com/gh/tabbyz/chib"
  },
  {
    "path": "Rakefile",
    "chars": 249,
    "preview": "# Add your own tasks in files placed in lib/tasks ending in .rake,\n# for example lib/tasks/capistrano.rake, and they wil"
  },
  {
    "path": "app/assets/images/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/assets/javascripts/application.coffee",
    "chars": 1129,
    "preview": "#= require jquery\n#= require jquery_ujs\n#= require jquery.cookie\n#= require jstz\n#= require browser_timezone_rails/set_t"
  },
  {
    "path": "app/assets/javascripts/dashboards.coffee",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/assets/javascripts/data_table.coffee",
    "chars": 2006,
    "preview": "$(document).ready ->\n  # Bootgrid settings\n  $(\".data-table\").on(\"initialized.rs.jquery.bootgrid\", (e) ->\n    $(\".table-"
  },
  {
    "path": "app/assets/javascripts/move_tests.coffee",
    "chars": 276,
    "preview": "$(\".tests.show\").ready ->\n  \n  $(document).on \"click\", \".move-test-modal .clickable\", ->\n    $(\".project-list .clickable"
  },
  {
    "path": "app/assets/javascripts/projects.coffee",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/assets/javascripts/static_pages.coffee",
    "chars": 211,
    "preview": "# Place all the behaviors and hooks related to the matching controller here.\n# All this logic will automatically be avai"
  },
  {
    "path": "app/assets/javascripts/team_users.coffee",
    "chars": 1571,
    "preview": "$(\".projects, .teams, .tests\").ready ->\n# ==================================================\n# Function\n# =============="
  },
  {
    "path": "app/assets/javascripts/teams.coffee",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/assets/javascripts/test_preview.coffee",
    "chars": 3366,
    "preview": "$(\".tests.new, .tests.edit\").ready ->\n# ==================================================\n# Function\n# ================"
  },
  {
    "path": "app/assets/javascripts/tests.coffee",
    "chars": 6722,
    "preview": "$(\".tests.show\").ready ->\n# ==================================================\n# Function\n# ============================"
  },
  {
    "path": "app/assets/javascripts/validation.coffee",
    "chars": 1267,
    "preview": "$(document).ready ->\n  $(document).on \"keydown\", \".form-control.validation\", (e) ->\n    if (e.keyCode != 13)\n      $(thi"
  },
  {
    "path": "app/assets/stylesheets/application.scss",
    "chars": 332,
    "preview": "/*\n *= require_tree .\n *= require_self\n */\n\n@import \"bootstrap-sprockets\";\n@import \"bootstrap\";\n@import \"bootstrap_overr"
  },
  {
    "path": "app/assets/stylesheets/bootstrap_overrides.scss",
    "chars": 1019,
    "preview": "a {\n  &:hover, &:focus {\n    text-decoration: none;\n  }\n}\n\ntextarea {\n  resize: none;\n}\n\n.btn, .form-control {\n  border-"
  },
  {
    "path": "app/assets/stylesheets/color.scss",
    "chars": 4151,
    "preview": "// http://www.materialui.co/colors\n// background-color:        400\n// background-color(hover): 500\n// border-color:     "
  },
  {
    "path": "app/assets/stylesheets/common.scss",
    "chars": 3099,
    "preview": ".modal-fullscreen {\n  width: 100% !important;\n  height: 100% !important;\n  margin: 0 !important;\n  padding: 20px;\n\n  .mo"
  },
  {
    "path": "app/assets/stylesheets/data_table.scss",
    "chars": 233,
    "preview": ".actionBar .table-toolbar {\n  display: inline-block;\n  float: right;\n\n  .selected-count {\n    display: inline-block;\n   "
  },
  {
    "path": "app/assets/stylesheets/layouts/navbar.scss",
    "chars": 766,
    "preview": ".navbar {\n  background-color: #FFF;\n  \n  > .container-fluid {\n    margin-top: 7px;\n  }\n\n  .navbar-nav > li > a {\n    pad"
  },
  {
    "path": "app/assets/stylesheets/layouts/sidebar.scss",
    "chars": 3380,
    "preview": ".page-with-sidebar {\n  .sidebar {\n    display: -webkit-flex;\n    display: flex;\n    -webkit-flex-direction: column;\n    "
  },
  {
    "path": "app/assets/stylesheets/layouts/style.scss",
    "chars": 1086,
    "preview": "body, html {\n  width: 100%;\n  height: 100%;\n}\n\nbody {\n  -webkit-text-size-adjust: 100%;\n  margin: 0;\n}\n\nbody {\n  &.regis"
  },
  {
    "path": "app/assets/stylesheets/static_pages/terms.scss",
    "chars": 135,
    "preview": ".terms {\n  h1 {\n    margin-top: 0;\n  }\n\n  h2 {\n    margin-top: 30px;\n    padding-bottom: 10px;\n    border-bottom: 1px so"
  },
  {
    "path": "app/assets/stylesheets/static_pages/top.scss",
    "chars": 3495,
    "preview": ".static_pages.top {\n  .navbar {\n    background-color: #01AB52;\n    box-shadow: none;\n    margin-bottom: 0;\n    border-ra"
  },
  {
    "path": "app/assets/stylesheets/teams/team_users.scss",
    "chars": 417,
    "preview": ".team-users-modal {\n  .search-user {\n    text-align: center;\n    \n    width: 300px;\n    margin: 0 auto;\n    margin-botto"
  },
  {
    "path": "app/assets/stylesheets/tests/edit_result_label.scss",
    "chars": 1463,
    "preview": ".edit-result-label-modal {\n  .popover-content-template {\n    display: none;\n  }\n\n  .checkbox {\n    margin-left: 8px;\n  }"
  },
  {
    "path": "app/assets/stylesheets/tests/form.scss",
    "chars": 1934,
    "preview": ".tests.new, .tests.edit {\n  .contents {\n    position: relative;\n  \n    .test-title {\n      position: absolute;\n      lef"
  },
  {
    "path": "app/assets/stylesheets/tests/move.scss",
    "chars": 673,
    "preview": ".move-test-modal {\n  .project-list {\n    .unset-project {\n      padding: 5px 7px;\n      font-weight: bold;\n    }\n\n    .t"
  },
  {
    "path": "app/assets/stylesheets/tests/show.scss",
    "chars": 1437,
    "preview": ".tests.show {\n  .progress-count-list {\n    margin-bottom: 0;\n    td {\n      text-align: right;\n      padding: 4px;\n\n    "
  },
  {
    "path": "app/assets/stylesheets/tests/testcase.scss",
    "chars": 2413,
    "preview": ".testcase-list {\n  .testcase-group {\n    background-color: #FFF;\n    border: 1px solid #DDD;\n    border-top-style: none;"
  },
  {
    "path": "app/assets/stylesheets/toastr_overrides.scss",
    "chars": 137,
    "preview": "#toast-container > div {\n  opacity: 1.0;\n}\n\n.toast-info {\n  background-color: #4CAF50;\n}\n\n.toast-warning {\n  background-"
  },
  {
    "path": "app/assets/stylesheets/vendor/best_in_place.scss",
    "chars": 426,
    "preview": ".best_in_place {\n  display: block;\n  width: 100%;\n  padding: 4px;\n  border: 1px solid transparent;\n  border-radius: 2px;"
  },
  {
    "path": "app/assets/stylesheets/vendor/bootgrid.scss",
    "chars": 486,
    "preview": ".bootgrid-header {\n  margin-top: 0;\n\n  .actionBar {\n    padding-left: 0;\n    padding-right: 0;\n    text-align: left;\n\n  "
  },
  {
    "path": "app/assets/stylesheets/vendor/ladda.scss",
    "chars": 172,
    "preview": ".ladda-button {\n  &:disabled {\n    cursor: default;\n  }\n\n  &[data-loading=\"\"] .ladda-spinner {\n    top: 50% !important;\n"
  },
  {
    "path": "app/controllers/application_controller.rb",
    "chars": 1434,
    "preview": "class ApplicationController < ActionController::Base\n  # Prevent CSRF attacks by raising an exception.\n  # For APIs, you"
  },
  {
    "path": "app/controllers/concerns/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/controllers/dashboard_controller.rb",
    "chars": 180,
    "preview": "class DashboardController < ApplicationController\n  before_action :authenticate_user!\n  \n  def index\n    @tests = curren"
  },
  {
    "path": "app/controllers/projects_controller.rb",
    "chars": 1290,
    "preview": "class ProjectsController < ApplicationController\n  before_action :authenticate_user!\n  before_action :authorize!, except"
  },
  {
    "path": "app/controllers/static_pages_controller.rb",
    "chars": 112,
    "preview": "class StaticPagesController < ApplicationController\n  def top\n    @user = User.new\n  end\n\n  def terms\n  end\nend\n"
  },
  {
    "path": "app/controllers/team_users_controller.rb",
    "chars": 834,
    "preview": "class TeamUsersController < ApplicationController\n  before_action :authenticate_user!\n\n  def index\n    @team = Team.find"
  },
  {
    "path": "app/controllers/teams_controller.rb",
    "chars": 1176,
    "preview": "class TeamsController < ApplicationController\n  before_action :authenticate_user!\n  before_action :authorize!, except: ["
  },
  {
    "path": "app/controllers/testcases_controller.rb",
    "chars": 748,
    "preview": "class TestcasesController < ApplicationController\n  before_action :set_testcase, only: [:update]\n\n   def update\n    test"
  },
  {
    "path": "app/controllers/tests_controller.rb",
    "chars": 3922,
    "preview": "class TestsController < ApplicationController\n  before_action :authenticate_user!, except: [:show]\n  before_action :auth"
  },
  {
    "path": "app/controllers/user_settings_controller.rb",
    "chars": 462,
    "preview": "class UserSettingsController < ApplicationController\n  before_action :authenticate_user!\n  before_action :set_user, only"
  },
  {
    "path": "app/controllers/users/registrations_controller.rb",
    "chars": 1025,
    "preview": "class Users::RegistrationsController < Devise::RegistrationsController\n  def edit\n    routing_error  # Invalidate a \"/us"
  },
  {
    "path": "app/helpers/application_helper.rb",
    "chars": 432,
    "preview": "module ApplicationHelper\n  def controller_action\n    controller_name + \"#\" + action_name\n  end\n\n  def color_names\n    %w"
  },
  {
    "path": "app/helpers/dashboard_helper.rb",
    "chars": 27,
    "preview": "module DashboardHelper\nend\n"
  },
  {
    "path": "app/helpers/projects_helper.rb",
    "chars": 388,
    "preview": "module ProjectsHelper\n  def project_collection\n    current_team.projects if current_team\n  end\n\n  def current_project\n  "
  },
  {
    "path": "app/helpers/static_pages_helper.rb",
    "chars": 29,
    "preview": "module StaticPagesHelper\nend\n"
  },
  {
    "path": "app/helpers/team_users_helper.rb",
    "chars": 27,
    "preview": "module TeamUsersHelper\nend\n"
  },
  {
    "path": "app/helpers/teams_helper.rb",
    "chars": 217,
    "preview": "module TeamsHelper\n  def current_team\n    if team_name = params[:name] || params[:team_name]\n      Team.find_by(name: te"
  },
  {
    "path": "app/helpers/tests_helper.rb",
    "chars": 86,
    "preview": "module TestsHelper\n  def current_test\n    Test.find_by(slug: params[:slug])\n  end\nend\n"
  },
  {
    "path": "app/mailers/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/models/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/models/concerns/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/models/project.rb",
    "chars": 382,
    "preview": "class Project < ActiveRecord::Base\n  belongs_to :team\n  has_many :tests, :dependent => :destroy\n  before_save { self.nam"
  },
  {
    "path": "app/models/team.rb",
    "chars": 646,
    "preview": "class Team < ActiveRecord::Base\n  has_many :projects, :dependent => :destroy\n  has_many :team_users, :dependent => :dest"
  },
  {
    "path": "app/models/team_user.rb",
    "chars": 114,
    "preview": "class TeamUser < ActiveRecord::Base\n  belongs_to :team\n  belongs_to :user\n  default_scope { order(\"id ASC\") }\nend\n"
  },
  {
    "path": "app/models/test.rb",
    "chars": 2406,
    "preview": "class Test < ActiveRecord::Base\n  belongs_to :user\n  belongs_to :project\n  has_many :testcases, dependent: :destroy\n  af"
  },
  {
    "path": "app/models/testcase.rb",
    "chars": 1385,
    "preview": "class Testcase < ActiveRecord::Base\n  belongs_to :test\n  validates :body, length: { maximum: 1024 }\n  validates :result,"
  },
  {
    "path": "app/models/user.rb",
    "chars": 571,
    "preview": "class User < ActiveRecord::Base\n  has_many :tests\n  has_many :team_users\n  has_many :teams, :through => :team_users\n  va"
  },
  {
    "path": "app/views/dashboard/_navbar.html.slim",
    "chars": 365,
    "preview": "nav.navbar.navbar-fixed-top.navbar-with-sidebar\n  .navbar-content\n    = link_to fa_icon(\"plus\", text: t(\"common.button.n"
  },
  {
    "path": "app/views/dashboard/index.html.slim",
    "chars": 1267,
    "preview": "- provide :title, t(\"dashboard.index.title\")\n\n= render \"navbar\"\n\n- if @tests.size == 0\n  .empty-data\n    = fa_icon(\"inbo"
  },
  {
    "path": "app/views/devise/confirmations/new.html.slim",
    "chars": 645,
    "preview": "- if devise_error_messages!.present?\n  .card.card-alert = devise_error_messages!\n\n.card.card-form\n  = form_for(resource,"
  },
  {
    "path": "app/views/devise/mailer/confirmation_instructions.en.html.slim",
    "chars": 178,
    "preview": "p = \"Welcome #{@email} !\"\n\np You can confirm your account email through the link below:\n\np = link_to \"Confirm my account"
  },
  {
    "path": "app/views/devise/mailer/confirmation_instructions.ja.html.slim",
    "chars": 140,
    "preview": "p = \"ようこそ #{@email} さん。\"\n\np 下記のリンクをクリックして、ユーザ登録を完了してください。\n\np = link_to \"メールアドレスを認証\", confirmation_url(@resource, confirm"
  },
  {
    "path": "app/views/devise/mailer/password_change.html.erb",
    "chars": 117,
    "preview": "<p>Hello <%= @resource.email %>!</p>\n\n<p>We're contacting you to notify you that your password has been changed.</p>\n"
  },
  {
    "path": "app/views/devise/mailer/reset_password_instructions.en.html.slim",
    "chars": 363,
    "preview": "p = \"Hello #{@resource.email} !\"\n\np Someone has requested a link to change your password. You can do this through the li"
  },
  {
    "path": "app/views/devise/mailer/reset_password_instructions.ja.html.slim",
    "chars": 254,
    "preview": "p = \"こんにちは #{@resource.email} さん。\"\n\np パスワードリセットのリクエストが行われました。<br>下記のリンクからパスワードを変更することができます。\n\np = link_to \"パスワードを再設定\", ed"
  },
  {
    "path": "app/views/devise/passwords/new.html.slim",
    "chars": 549,
    "preview": "- if devise_error_messages!.present?\n  .card.card-alert = devise_error_messages!\n\n.card.card-form\n  = form_for(resource,"
  },
  {
    "path": "app/views/devise/registrations/new.html.slim",
    "chars": 1002,
    "preview": "- if devise_error_messages!.present?\n  .card.card-alert = devise_error_messages!\n\n.card.card-form\n  = form_for(resource,"
  },
  {
    "path": "app/views/devise/sessions/new.html.slim",
    "chars": 670,
    "preview": ".card.card-form\n  = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|\n    h1.card-title = t"
  },
  {
    "path": "app/views/devise/shared/_links.html.erb",
    "chars": 1149,
    "preview": "<%- if controller_name != 'sessions' %>\n  <%= link_to \"Log in\", new_session_path(resource_name) %><br />\n<% end -%>\n\n<%-"
  },
  {
    "path": "app/views/layouts/_dashboard_sidebar.html.slim",
    "chars": 538,
    "preview": ".sidebar.team-sidebar\n  .sidebar-title.dropdown\n    a.dropdown-toggle aria-expanded=\"false\" aria-haspopup=\"true\" data-to"
  },
  {
    "path": "app/views/layouts/_logo.html.slim",
    "chars": 48,
    "preview": "/ = link_to \"Chibineko\", root_url, class: \"logo\""
  },
  {
    "path": "app/views/layouts/_main_menu.html.slim",
    "chars": 504,
    "preview": "ul.dropdown-menu style=\"top: 44px; left: 18px;\"\n  li.dropdown-header = t(\"common.you\")\n  li = link_to fa_icon(\"cog\", tex"
  },
  {
    "path": "app/views/layouts/_navbar.html.slim",
    "chars": 1112,
    "preview": "- if controller_action == \"static_pages#top\"\n  nav.navbar\n    .container-fluid\n      = link_to \"Chibineko\", root_url, cl"
  },
  {
    "path": "app/views/layouts/_root_sidebar.html.slim",
    "chars": 815,
    "preview": ".sidebar.root-sidebar\n  = link_to fa_icon(\"home 2x\"), dashboard_path, class: \"home-btn\", data: { toggle: \"tooltip\", plac"
  },
  {
    "path": "app/views/layouts/_sign_in_link.html.slim",
    "chars": 59,
    "preview": "= link_to t(\"common.button.sign_in\"), new_user_session_path"
  },
  {
    "path": "app/views/layouts/_sign_out_link.html.slim",
    "chars": 108,
    "preview": "= link_to fa_icon(\"sign-out\", text: t(\"common.button.sign_out\")), destroy_user_session_path, method: :delete"
  },
  {
    "path": "app/views/layouts/_sign_up_link.html.slim",
    "chars": 97,
    "preview": "= link_to t(\"common.button.sign_up\"), new_user_registration_path, class: \"btn color-blue sign-up\""
  },
  {
    "path": "app/views/layouts/_team_sidebar.html.slim",
    "chars": 841,
    "preview": ".sidebar.team-sidebar\n  .sidebar-title.dropdown\n    a.dropdown-toggle aria-expanded=\"false\" aria-haspopup=\"true\" data-to"
  },
  {
    "path": "app/views/layouts/application.html.slim",
    "chars": 1302,
    "preview": "doctype html\nhtml\n  head\n    title = page_title(yield :title)\n    - if controller_action == \"static_pages#top\"\n      met"
  },
  {
    "path": "app/views/projects/_navbar.html.slim",
    "chars": 810,
    "preview": "nav.navbar.navbar-fixed-top.navbar-with-sidebar\n  .navbar-content\n    .navbar-title\n      .dropdown\n        a.dropdown-t"
  },
  {
    "path": "app/views/projects/_new.html.slim",
    "chars": 697,
    "preview": ".new-project-modal.modal-dialog.modal-sm\n  .modal-content\n    = form_for @project, url: team_projects_path, remote: true"
  },
  {
    "path": "app/views/projects/_save.js.erb",
    "chars": 115,
    "preview": "$(\".modal\").modal(\"hide\")\n$(window.location.replace(\"<%= team_project_path(@project.team.name, @project.name) %>\"))"
  },
  {
    "path": "app/views/projects/_settings.html.slim",
    "chars": 1751,
    "preview": ".project-settings-modal.modal-dialog\n  .modal-content\n    .modal-header\n      button.close type=\"button\" data-dismiss=\"m"
  },
  {
    "path": "app/views/projects/create.js.erb",
    "chars": 20,
    "preview": "<%= render 'save' %>"
  },
  {
    "path": "app/views/projects/new.js.erb",
    "chars": 84,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'new') %>\")\n$(\".modal\").modal(\"show\")"
  },
  {
    "path": "app/views/projects/settings.js.erb",
    "chars": 117,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'settings') %>\")\nLadda.bind(\".ladda-button\")\n$(\".modal\").modal(\"show\")"
  },
  {
    "path": "app/views/projects/show.html.slim",
    "chars": 1334,
    "preview": "- provide :title, \"#{@project.team.name}##{@project.name}\"\n\n= render \"navbar\"\n\n- if @project.tests.size == 0\n  .empty-da"
  },
  {
    "path": "app/views/projects/update.js.erb",
    "chars": 20,
    "preview": "<%= render 'save' %>"
  },
  {
    "path": "app/views/static_pages/terms.html.slim",
    "chars": 79,
    "preview": ".card.card-lg\n  h1.card-title = t(\".title\")\n\n  .card-body\n    = t(\".body_html\")"
  },
  {
    "path": "app/views/static_pages/top.html.slim",
    "chars": 3014,
    "preview": ".container-fluid\n  .row.branding.text-center\n    h1 = t(\".branding.title\")\n    p = t(\".branding.sub_title\")\n\n    - if us"
  },
  {
    "path": "app/views/team_users/_index.html.slim",
    "chars": 1627,
    "preview": ".team-users-modal.modal-dialog.modal-sm\n  .modal-content\n    .modal-header\n      button.close type=\"button\" data-dismiss"
  },
  {
    "path": "app/views/team_users/_save.js.erb",
    "chars": 88,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'index') %>\")\nLadda.bind(\".ladda-button\")"
  },
  {
    "path": "app/views/team_users/create.js.erb",
    "chars": 20,
    "preview": "<%= render 'save' %>"
  },
  {
    "path": "app/views/team_users/destroy.js.erb",
    "chars": 20,
    "preview": "<%= render 'save' %>"
  },
  {
    "path": "app/views/team_users/index.js.erb",
    "chars": 114,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'index') %>\")\nLadda.bind(\".ladda-button\")\n$(\".modal\").modal(\"show\")"
  },
  {
    "path": "app/views/teams/_new.html.slim",
    "chars": 666,
    "preview": ".new-team-modal.modal-dialog.modal-sm\n  .modal-content\n    = form_for @team, remote: true do |f|\n      .modal-header\n   "
  },
  {
    "path": "app/views/teams/_save.js.erb",
    "chars": 84,
    "preview": "$(\".modal\").modal(\"hide\")\n$(window.location.replace(\"<%= team_path(@team.name) %>\"))"
  },
  {
    "path": "app/views/teams/_settings.html.slim",
    "chars": 1660,
    "preview": ".team-settings-modal.modal-dialog\n  .modal-content\n    .modal-header\n      button.close type=\"button\" data-dismiss=\"moda"
  },
  {
    "path": "app/views/teams/create.js.erb",
    "chars": 20,
    "preview": "<%= render 'save' %>"
  },
  {
    "path": "app/views/teams/new.js.erb",
    "chars": 84,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'new') %>\")\n$(\".modal\").modal(\"show\")"
  },
  {
    "path": "app/views/teams/settings.js.erb",
    "chars": 117,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'settings') %>\")\nLadda.bind(\".ladda-button\")\n$(\".modal\").modal(\"show\")"
  },
  {
    "path": "app/views/teams/show.html.slim",
    "chars": 317,
    "preview": "- provide :title, @team.name\n\n- if @team.projects.size == 0\n  .empty-data\n    = fa_icon(\"inbox\", class: \"symbol\")\n    h3"
  },
  {
    "path": "app/views/teams/update.js.erb",
    "chars": 20,
    "preview": "<%= render 'save' %>"
  },
  {
    "path": "app/views/tests/_alert.html.slim",
    "chars": 393,
    "preview": "- if @test.user && @test.project.nil?\n  .alert.alert-info\n    p = t(\"messages.public_test_html\")\n\n- if @test.user.nil?\n "
  },
  {
    "path": "app/views/tests/_cheatsheet.en.html.slim",
    "chars": 601,
    "preview": ".cheatsheet\n  p.cheatsheet-header = fa_icon(\"question-circle\", text: \"Tips: how to create test cases\")\n  .cheatsheet-blo"
  },
  {
    "path": "app/views/tests/_cheatsheet.ja.html.slim",
    "chars": 389,
    "preview": ".cheatsheet\n  p.cheatsheet-header = fa_icon(\"question-circle\", text: \"書き方のヒント\")\n  .cheatsheet-block\n    p.cheatsheet-tit"
  },
  {
    "path": "app/views/tests/_description.html.slim",
    "chars": 607,
    "preview": ".edit-description-modal.modal-dialog.modal-lg\n  .modal-content\n    = form_for @test, remote: true do |f|\n      .modal-he"
  },
  {
    "path": "app/views/tests/_form.html.slim",
    "chars": 911,
    "preview": "= render \"navbar\"\n\n= form_for @test, remote: true do |f|\n  = f.hidden_field :source\n  = f.hidden_field :team_name, value"
  },
  {
    "path": "app/views/tests/_move.html.slim",
    "chars": 1022,
    "preview": ".move-test-modal.modal-dialog.modal-xs\n  .modal-content\n    = form_for @test, remote: true do |f|\n      = f.hidden_field"
  },
  {
    "path": "app/views/tests/_navbar.html.slim",
    "chars": 2133,
    "preview": "nav.navbar.navbar-fixed-top.navbar-with-sidebar\n  .navbar-content\n    - if action_name == \"show\"\n      = link_to fa_icon"
  },
  {
    "path": "app/views/tests/_result_label.html.slim",
    "chars": 2055,
    "preview": ".edit-result-label-modal.modal-dialog.modal-xs\n  .modal-content\n    = form_for @test, url: update_result_label_test_path"
  },
  {
    "path": "app/views/tests/_table_toolbar.html.slim",
    "chars": 734,
    "preview": ".table-toolbar\n  span.selected-count\n  ul.nav.navbar-nav.navbar-right\n    li = link_to fa_icon(\"trash-o\", text: t(\"commo"
  },
  {
    "path": "app/views/tests/_testcase.html.slim",
    "chars": 1741,
    "preview": ".testcase-toolbar\n  button type=\"button\" class=\"btn-link js-collapse-all-btn\"\n    = fa_icon \"caret-down\", text: t(\".coll"
  },
  {
    "path": "app/views/tests/bulk_destroy.js.erb",
    "chars": 24,
    "preview": "window.location.reload()"
  },
  {
    "path": "app/views/tests/bulk_move.js.erb",
    "chars": 24,
    "preview": "window.location.reload()"
  },
  {
    "path": "app/views/tests/create.js.erb",
    "chars": 84,
    "preview": "$(\".modal\").modal(\"hide\")\n$(window.location.replace(\"<%= test_path(@test.slug) %>\"))"
  },
  {
    "path": "app/views/tests/description.js.erb",
    "chars": 92,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'description') %>\")\n$(\".modal\").modal(\"show\")"
  },
  {
    "path": "app/views/tests/edit.html.slim",
    "chars": 15,
    "preview": "= render \"form\""
  },
  {
    "path": "app/views/tests/move.js.erb",
    "chars": 85,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'move') %>\")\n$(\".modal\").modal(\"show\")"
  },
  {
    "path": "app/views/tests/new.html.slim",
    "chars": 15,
    "preview": "= render \"form\""
  },
  {
    "path": "app/views/tests/result_label.js.erb",
    "chars": 254,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'result_label') %>\")\n$(\".modal\").modal(\"show\")\n\nSortable.create(resultLab"
  },
  {
    "path": "app/views/tests/show.csv.ruby",
    "chars": 924,
    "preview": "require 'csv'\n\ntestcases = @test.testcases\n\n# Examine the maximum heading level\nmax_level = 0\ntestcases.each do |c|\n  if"
  },
  {
    "path": "app/views/tests/show.html.slim",
    "chars": 1057,
    "preview": "- provide :title, @test.title\n\n- if !user_signed_in?\n  = render \"layouts/navbar\"\n- else\n  = render \"navbar\"\n\n.progress.p"
  },
  {
    "path": "app/views/tests/update.js.erb",
    "chars": 84,
    "preview": "$(\".modal\").modal(\"hide\")\n$(window.location.replace(\"<%= test_path(@test.slug) %>\"))"
  },
  {
    "path": "app/views/tests/update_result_label.js.erb",
    "chars": 53,
    "preview": "$(\".modal\").modal(\"hide\")\n$(window.location.reload())"
  },
  {
    "path": "app/views/user_settings/_modal.html.slim",
    "chars": 4385,
    "preview": ".account-settings-modal.modal-dialog\n  .modal-content\n    .modal-header\n      button.close type=\"button\" data-dismiss=\"m"
  },
  {
    "path": "app/views/user_settings/edit.js.erb",
    "chars": 114,
    "preview": "$(\".modal\").html(\"<%= escape_javascript(render 'modal') %>\")\nLadda.bind(\".ladda-button\")\n$(\".modal\").modal(\"show\")"
  },
  {
    "path": "app/views/user_settings/update.js.erb",
    "chars": 53,
    "preview": "$(\".modal\").modal(\"hide\")\n$(window.location.reload())"
  },
  {
    "path": "bin/bundle",
    "chars": 129,
    "preview": "#!/usr/bin/env ruby\nENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)\nload Gem.bin_path('bundler', '"
  },
  {
    "path": "bin/rails",
    "chars": 145,
    "preview": "#!/usr/bin/env ruby\nAPP_PATH = File.expand_path('../../config/application', __FILE__)\nrequire_relative '../config/boot'\n"
  },
  {
    "path": "bin/rake",
    "chars": 90,
    "preview": "#!/usr/bin/env ruby\nrequire_relative '../config/boot'\nrequire 'rake'\nRake.application.run\n"
  },
  {
    "path": "bin/setup",
    "chars": 805,
    "preview": "#!/usr/bin/env ruby\nrequire 'pathname'\n\n# path to your application root.\nAPP_ROOT = Pathname.new File.expand_path('../.."
  },
  {
    "path": "circle.yml",
    "chars": 105,
    "preview": "machine:\n  ruby:\n    version: 2.3.0\ndatabase:\n  pre:\n    - cp config/mailer.yml.example config/mailer.yml"
  },
  {
    "path": "config/application.rb",
    "chars": 1544,
    "preview": "require File.expand_path('../boot', __FILE__)\n\nrequire \"rails\"\n# Pick the frameworks you want:\nrequire \"active_model/rai"
  },
  {
    "path": "config/boot.rb",
    "chars": 132,
    "preview": "ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)\n\nrequire 'bundler/setup' # Set up gems listed in t"
  },
  {
    "path": "config/database.yml",
    "chars": 552,
    "preview": "# SQLite version 3.x\n#   gem install sqlite3\n#\n#   Ensure the SQLite 3 gem is defined in your Gemfile\n#   gem 'sqlite3'\n"
  },
  {
    "path": "config/environment.rb",
    "chars": 150,
    "preview": "# Load the Rails application.\nrequire File.expand_path('../application', __FILE__)\n\n# Initialize the Rails application.\n"
  },
  {
    "path": "config/environments/development.rb",
    "chars": 1896,
    "preview": "Rails.application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  "
  },
  {
    "path": "config/environments/production.rb",
    "chars": 3228,
    "preview": "Rails.application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  "
  },
  {
    "path": "config/environments/test.rb",
    "chars": 1755,
    "preview": "Rails.application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  "
  },
  {
    "path": "config/i18n-js.yml",
    "chars": 687,
    "preview": "# Split context in several files.\n# By default only one file with all translations is exported and\n# no configuration is"
  },
  {
    "path": "config/initializers/action_mailer.rb",
    "chars": 231,
    "preview": "unless Chibineko::Application.config.action_mailer.nil?\n  if options = YAML.load_file(Rails.root.join(\"config\", \"mailer."
  },
  {
    "path": "config/initializers/assets.rb",
    "chars": 486,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Version of your assets, change this if you want to expire"
  },
  {
    "path": "config/initializers/backtrace_silencers.rb",
    "chars": 404,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# You can add backtrace silencers for libraries that you're"
  },
  {
    "path": "config/initializers/cookies_serializer.rb",
    "chars": 129,
    "preview": "# Be sure to restart your server when you modify this file.\n\nRails.application.config.action_dispatch.cookies_serializer"
  },
  {
    "path": "config/initializers/devise.rb",
    "chars": 13105,
    "preview": "# Use this hook to configure devise mailer, warden hooks and so forth.\n# Many of these configuration options can be set "
  },
  {
    "path": "config/initializers/filter_parameter_logging.rb",
    "chars": 194,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Configure sensitive parameters which will be filtered fro"
  },
  {
    "path": "config/initializers/inflections.rb",
    "chars": 647,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Add new inflection rules using the following format. Infl"
  },
  {
    "path": "config/initializers/mime_types.rb",
    "chars": 156,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Add new mime types for use in respond_to blocks:\n# Mime::"
  },
  {
    "path": "config/initializers/session_store.rb",
    "chars": 141,
    "preview": "# Be sure to restart your server when you modify this file.\n\nRails.application.config.session_store :cookie_store, key: "
  },
  {
    "path": "config/initializers/time_formats.rb",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "config/initializers/wrap_parameters.rb",
    "chars": 517,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# This file contains settings for ActionController::ParamsW"
  },
  {
    "path": "config/locales/devise.en.yml",
    "chars": 3975,
    "preview": "# Additional translations at https://github.com/plataformatec/devise/wiki/I18n\n\nen:\n  devise:\n    confirmations:\n      c"
  },
  {
    "path": "config/locales/devise.ja.yml",
    "chars": 2513,
    "preview": "# Additional translations at https://github.com/plataformatec/devise/wiki/I18n\n\nja:\n  devise:\n    confirmations:\n      c"
  },
  {
    "path": "config/locales/devise_view.en.yml",
    "chars": 459,
    "preview": "en:\n  devise:\n    registrations:\n      new:\n        sign_up: \"Sign up\"\n        not_receive: \"Didn't receive confirmation"
  },
  {
    "path": "config/locales/devise_view.ja.yml",
    "chars": 396,
    "preview": "ja:\n  devise:\n    registrations:\n      new:\n        sign_up: \"ユーザー登録\"\n        not_receive: \"登録確認メールが届かない方はこちら\"\n    confi"
  },
  {
    "path": "config/locales/en.yml",
    "chars": 7976,
    "preview": "en:\n  language_name: \"English\"\n\n  common:\n    created_by: \"Created by\"\n    updated_at: \"Updated at\"\n    updated_on: \"Upd"
  },
  {
    "path": "config/locales/ja.yml",
    "chars": 6383,
    "preview": "ja:\n  language_name: \"日本語\"\n\n  common:\n    created_by: \"作成者\"\n    updated_at: \"更新日時\"\n    updated_on: \"更新日\"\n    dashboard: "
  },
  {
    "path": "config/locales/js.en.yml",
    "chars": 1015,
    "preview": "en:\n  js:\n    team_sidebar:\n      edit_members:\n        search_user: \"Search user...\"\n        add_user: \"Add this user t"
  },
  {
    "path": "config/locales/js.ja.yml",
    "chars": 870,
    "preview": "ja:\n  js:\n    team_sidebar:\n      edit_members:\n        search_user: \"検索中...\"\n        add_user: \"ユーザーをチームに追加\"\n        no"
  },
  {
    "path": "config/locales/terms.en.yml",
    "chars": 22060,
    "preview": "en:\n  static_pages:\n    terms:\n      title: \"Terms of Service\"\n      body_html: |\n        <p>Last modified: January 20, "
  },
  {
    "path": "config/locales/terms.ja.yml",
    "chars": 11579,
    "preview": "ja:\n  static_pages:\n    terms:\n      title: \"サービス利用規約\"\n      body_html: |\n        <p>2015年1月20日 制定</p>\n\n        <h2>第 1 "
  },
  {
    "path": "config/mailer.yml.example",
    "chars": 464,
    "preview": "defaults: &defaults\n\ndevelopment:\n  default_url_options:\n    host: \"localhost\"\n    port: \"3000\"\n\ntest:\n  default_url_opt"
  },
  {
    "path": "config/routes.rb",
    "chars": 1012,
    "preview": "Rails.application.routes.draw do\n  root 'static_pages#top'\n  get 'terms' => 'static_pages#terms'\n  get 'dashboard' => 'd"
  },
  {
    "path": "config/secrets.yml",
    "chars": 964,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Your secret key is used for verifying the integrity of si"
  },
  {
    "path": "config.ru",
    "chars": 153,
    "preview": "# This file is used by Rack-based servers to start the application.\n\nrequire ::File.expand_path('../config/environment',"
  },
  {
    "path": "db/migrate/20151224022612_devise_create_users.rb",
    "chars": 1346,
    "preview": "class DeviseCreateUsers < ActiveRecord::Migration\n  def change\n    create_table(:users) do |t|\n      ## Database authent"
  },
  {
    "path": "db/migrate/20151224030646_create_teams.rb",
    "chars": 225,
    "preview": "class CreateTeams < ActiveRecord::Migration\n  def change\n    create_table :teams do |t|\n      t.string :name, null: fals"
  },
  {
    "path": "db/migrate/20151225045046_create_projects.rb",
    "chars": 316,
    "preview": "class CreateProjects < ActiveRecord::Migration\n  def change\n    create_table :projects do |t|\n      t.string :name, null"
  },
  {
    "path": "db/migrate/20151225141534_create_tests.rb",
    "chars": 329,
    "preview": "class CreateTests < ActiveRecord::Migration\n  def change\n    create_table :tests do |t|\n      t.string :slug, null: fals"
  },
  {
    "path": "db/migrate/20151226051709_create_testcases.rb",
    "chars": 309,
    "preview": "class CreateTestcases < ActiveRecord::Migration\n  def change\n    create_table :testcases do |t|\n      t.integer :heading"
  },
  {
    "path": "db/migrate/20160103121144_add_column_to_user.rb",
    "chars": 195,
    "preview": "class AddColumnToUser < ActiveRecord::Migration\n  def change\n    add_column :users, :username, :string\n    add_column :u"
  },
  {
    "path": "db/migrate/20160109162956_create_team_users.rb",
    "chars": 331,
    "preview": "class CreateTeamUsers < ActiveRecord::Migration\n  def change\n    create_table :team_users do |t|\n      t.integer :team_i"
  },
  {
    "path": "db/migrate/20160319072222_add_created_at_index_to_test.rb",
    "chars": 147,
    "preview": "class AddCreatedAtIndexToTest < ActiveRecord::Migration\n  def change\n    add_index :tests, :created_at\n    add_index :te"
  },
  {
    "path": "db/schema.rb",
    "chars": 3939,
    "preview": "# encoding: UTF-8\n# This file is auto-generated from the current state of the database. Instead\n# of editing this file, "
  },
  {
    "path": "db/seeds.rb",
    "chars": 97,
    "preview": "user = User.create(email: \"test@example.com\", password: \"test\")\nuser.skip_confirmation!\nuser.save"
  },
  {
    "path": "lib/assets/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "lib/tasks/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "log/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "public/404.en.html",
    "chars": 639,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>404 | Chibineko</title>\n  <meta name=\"viewport\" content=\"width=device-width,initi"
  },
  {
    "path": "public/404.ja.html",
    "chars": 603,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>404 | Chibineko</title>\n  <meta name=\"viewport\" content=\"width=device-width,initi"
  },
  {
    "path": "public/422.en.html",
    "chars": 630,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>422 | Chibineko</title>\n  <meta name=\"viewport\" content=\"width=device-width,initi"
  },
  {
    "path": "public/422.ja.html",
    "chars": 597,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>422 | Chibineko</title>\n  <meta name=\"viewport\" content=\"width=device-width,initi"
  },
  {
    "path": "public/500.en.html",
    "chars": 636,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>500 | Chibineko</title>\n  <meta name=\"viewport\" content=\"width=device-width,initi"
  },
  {
    "path": "public/500.ja.html",
    "chars": 595,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>500 | Chibineko</title>\n  <meta name=\"viewport\" content=\"width=device-width,initi"
  },
  {
    "path": "public/error.css",
    "chars": 575,
    "preview": "body {\n  text-align: center;\n  padding-top: 60px;\n  color: #555;\n}\n\n.dialog {\n  display: inline-block;\n  text-align: lef"
  },
  {
    "path": "public/javascripts/translations.js",
    "chars": 1574,
    "preview": "var I18n = I18n || {};\nI18n.translations = {\"en\":{\"js\":{\"team_sidebar\":{\"edit_members\":{\"search_user\":\"Search user...\",\""
  },
  {
    "path": "public/maintenance.html",
    "chars": 536,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>503 | Chibineko</title>\n  <meta name=\"viewport\" content=\"width=device-width,initi"
  },
  {
    "path": "public/robots.txt",
    "chars": 202,
    "preview": "# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file\n#\n# To ban all spiders"
  },
  {
    "path": "spec/factories/testcases.rb",
    "chars": 55,
    "preview": "FactoryGirl.define do\n  factory :testcase do\n  end\nend\n"
  },
  {
    "path": "spec/factories/tests.rb",
    "chars": 98,
    "preview": "FactoryGirl.define do\n  factory :test do\n    sequence(:title) { |n| \"test_title_#{n}\" }\n  end\nend\n"
  },
  {
    "path": "spec/models/test_spec.rb",
    "chars": 3051,
    "preview": "require 'rails_helper'\n\nRSpec.describe Test, type: :model do\n  let(:test) { create(:test) }\n  let(:labels) {\n      resul"
  }
]

// ... and 6 more files (download for full content)

About this extraction

This page contains the full source code of the tabbyz/chibineko GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 206 files (229.6 KB), approximately 71.0k tokens, and a symbol index with 130 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!