[
  {
    "path": ".bowerrc",
    "content": "{\n    \"directory\": \"bower_components\"\n}\n"
  },
  {
    "path": ".editorconfig",
    "content": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# editorconfig.org\n\nroot = true\n\n\n[*]\n\n# Change these settings to your own preference\nindent_style = space\nindent_size = 2\n\n# We recommend you to keep these unchanged\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.tmp\n.sass-cache\nbower_components\n.idea/\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n  \"node\": true,\n  \"browser\": true,\n  \"esnext\": true,\n  \"bitwise\": true,\n  \"camelcase\": true,\n  \"curly\": true,\n  \"eqeqeq\": true,\n  \"immed\": true,\n  \"indent\": 2,\n  \"latedef\": true,\n  \"newcap\": true,\n  \"noarg\": true,\n  \"quotmark\": \"single\",\n  \"regexp\": true,\n  \"undef\": true,\n  \"unused\": true,\n  \"strict\": true,\n  \"trailing\": true,\n  \"smarttabs\": true,\n  \"globals\": {\n    \"angular\": false,\n    \"$\": false,\n    \"jQuery\": false\n  }\n}\n"
  },
  {
    "path": ".npmignore",
    "content": ".git/\n.idea/\n.tmp/\nbower_components/\ncommon/\nsrc/\nnode_modules/\n.editorconfig\n.gitattributes\n.gitignore\n.jshintrc\n.travis.yml"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\n\nnode_js:\n  - \"4.1\"\n  \nenv:\n  - CXX=g++-4.8\n\naddons:\n  apt:\n    sources:\n      - ubuntu-toolchain-r-test\n    packages:\n      - g++-4.8\n\nbefore_script:\n  - 'npm install -g bower grunt-cli'\n  - 'npm install'\n  - 'bower install'\n\nscript:\n  - grunt\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "CHANGELOG\n=========\n\n## 0.5.2 (2017-04-19)\n\n- Update `bootstrap-switch` to `~3.3.4`\n- Fix `jquery` import in tests\n- Fix `npm` dependencies\n- Fix `README` headings\n\n## 0.5.1 (2016-06-04)\n\n- Make `switch-change` trigger when model changes\n- Use `ng-change` for triggers only on view changes\n- Test `ng-change` and `switch-change` behaviors\n\n## 0.5.0 (2016-03-10)\n\n- Use `ngAnnotate` instead of `ngMin`\n- Update dev dependencies\n- Add `switch-change` attribute\n- Improve digest cycle\n- Use `null` for indeterminate state\n- Update to Angular 1.5.0\n\n**BREAKING CHANGES:**\n\n- Applications relying on `undefined` as the only indeterminate state\n  may break if they consider `null` a falsy value. `null` is now an\n  indeterminate value.\n\n## 0.4.1 (2015-06-15)\n\n- Update to `angular` 1.4.0\n- Add test support for IE\n- Enable indeterminate state\n- Enable generic true value (not just strings)\n\n## 0.4.0 (2015-04-13)\n\n- Alpha to stable with no changes\n\n## 0.4.0-alpha.2 (2015-04-01)\n\n- Add new parameters\n  - `switch-inverse`\n  - `switch-readonly`\n- Fix for radio switches\n- Handle models using getterSetter option\n- `'use strict'` to module-level only\n- Update to `angular` 1.3.15\n\n## 0.4.0-alpha.1 (2014-11-21)\n\n- Update to `bootstrap-switch` 3.2.2\n- Update to `angular` 1.3.3\n- Add new parameters\n  - `switch-label-width`\n  - `switch-handle-width`\n- Multiple bug fixes\n- Code optimization improvements\n\n## 0.3.0 (2014-06-27)\n\n- Update to `bootstrap-switch` 3.0.2\n- Update to `angular` 1.2.18\n- Support for `jquery` > 1.9.0\n- Promotion to stable\n\n## 0.3.0-alpha.2 (2014-03-30)\n\n- Update to `bootstrap-switch` 3.0.0 stable\n- Update to `angular` 1.2.15\n- **bsSwitch**: add `switch-wrapper` property\n\n## 0.3.0-alpha.1 (2014-02-22)\n\n### Breaking changes\n\nThis is an alpha release based on the `HEAD` of the `bootstrap-switch` `3.0` branch. Therefore, specifications\nhave slightly changed in order to reflect the original API. Use in production environment is discouraged, since the API\nmay change unexpectedly.\n\n- Handle text:\n  - Use `switch-on-text` instead of `switch-on-label`\n  - Use `switch-off-text` instead of `switch-off-label`\n- Handle color:\n  - Use `switch-on-color` instead of `switch-on`\n  - Use `switch-off-color` instead of `switch-off`\n\n- When setting `switch-icon`, `bootstrap-switch~2` used to inject an `<i>` tag with a predefined `icon` class,\nwhile it now injects a `<span>` tag without any additional classes other than the ones you specify.\n\n### Other changes\n\n- Update to `angular` 1.2.13\n- Update to `bootstrap-switch#3.0.0`\n- Update to `jquery` 2.1.0\n\n## 0.2.1 (2013-12-31)\n\n- Update to `angular` 1.2.6\n- Update to `bootstrap-switch` 2.0.0\n- **bsSwitch**: fix for `type` enforcing\n- **bsSwitchSpec**: fix tests\n- Add `CHANGELOG.md`\n\n## 0.2.0 (2013-12-16)\n\n- Improve build process\n- **bsSwitchSpec**: fix stop test-travis\n- **bsSwitch**: fix `$apply already in progress`, default active state\n- Update to `angular` 1.2.5\n- Update to `bootstrap-switch` 1.9.0\n- Add example page\n- Add contribution guidelines\n- **bsSwitchSpec**: Add test file (24 tests)\n- **bsSwitch**: fix class size (thanks to [@bardusco](https://github.com/bardusco))\n\n## 2.0.0 (2013-09-24)\n\n- Update to `angular` 1.2.0-rc.1\n- Update to `develop` branch of `bootstrap-switch`\n- **bsSwitch**: handle undefined `ngModel`\n\n## 0.1.0 (2013-08-12)\n\n- First release\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Contributing\n============\n\n## <a name=\"report-issue\"></a> Report an Issue\n\nIf you have found an issue with `angular-bootstrap-switch` and want to report it, **please make a live demo** first \nso that the misbehaviour can be reproduced. If you don't know how to do it, simply fork and edit \n**[this plnkr template](http://plnkr.co/edit/SWy8YmrVi8IsTa4FuqSZ)**.\n\nIssues with no live demo can get automatically closed.\n\nAlso, make sure to:\n  - look for **similar issues** in the repository bug tracker\n  - specify the `angular-bootstrap-switch` **version** showing the issue\n  - check if the issue was already fixed in an `alpha`/`beta` release or in the latest commit of the `develop` branch\n  (commits on the `develop` branch don't generate a single file in the `build` directory, you need to check against \n  files in the `src` directory)\n  - clearly describe how the plugin should be changed to address your request\n\n## <a name=\"submit-pr\"></a> Submit a Pull Request\n\nIf you want to submit a Pull Request, please follow the same rules as in [Report an Issue](#report-issue), plus all the\n**[submission guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#submitting-a-pull-request)**,\n**[coding rules](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#rules)** and \n**[commit message rules](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit)** that apply to the \nmain angular.js project.\n\n**IMPORTANT**: Before submitting your PR, write new tests for it (where applicable) and test everything by running:\n\n```shell\n$ grunt test-travis\n```\n\nPreviously existing tests *should* never break.\n"
  },
  {
    "path": "Gruntfile.js",
    "content": "'use strict';\n\nmodule.exports = function (grunt) {\n  // load all grunt tasks\n  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);\n\n  // configurable paths\n  var yeomanConfig = {\n    src: 'src',\n    dist: 'dist',\n    test: 'test',\n    temp: '.temp'\n  };\n\n  try {\n    yeomanConfig.src = require('./bower.json').appPath || yeomanConfig.src;\n  } catch (e) {}\n\n  grunt.initConfig({\n    yeoman: yeomanConfig,\n    pkg: grunt.file.readJSON('bower.json'),\n    meta: {\n      banner:\n        '/**\\n' +\n        ' * <%= pkg.name %>\\n' +\n        ' * @version v<%= pkg.version %> - <%= grunt.template.today(\"yyyy-mm-dd\") %>\\n' +\n        ' * @author <%= pkg.author.name %> (<%= pkg.author.email %>)\\n' +\n\t\t    ' * @link <%= pkg.homepage %>\\n' +\n        ' * @license <%= _.map(pkg.licenses, function(l) { return l.type + \"(\" + l.url + \")\"; }).join(\", \") %>\\n' +\n        '**/\\n\\n'\n    },\n    jshint: {\n      options: {\n        jshintrc: '.jshintrc'\n      },\n      all: [\n        'Gruntfile.js',\n        '<%= yeoman.src %>/**/*.js'\n      ],\n      test: {\n        src: ['<%= yeoman.test %>/spec/**/*.js'],\n        options: {\n          jshintrc: '<%= yeoman.test %>/.jshintrc'\n        }\n      }\n    },\n    karma: {\n      options: {\n        configFile: 'karma.conf.js'\n      },\n      unit: {\n        options: {\n          singleRun: false\n        }\n      },\n      final: {\n        options: {\n          singleRun: true\n        }\n      },\n      travis: {\n        browsers: ['PhantomJS'],\n        options: {\n          singleRun: true\n        }\n      }\n    },\n    clean: {\n      dist: {\n        files: [{\n          dot: true,\n          src: [\n            '<%= yeoman.dist %>/*',\n            '!<%= yeoman.dist %>/.git*'\n          ]\n        }]\n      },\n      temp: {\n        src: ['<%= yeoman.dist %>/<%= yeoman.temp %>']\n      }\n    },\n    ngAnnotate: {\n      dist: {\n        expand: true,\n        cwd: '<%= yeoman.src %>',\n        src: ['**/*.js'],\n        dest: '<%= yeoman.dist %>/<%= yeoman.temp %>'\n      }\n    },\n    concat: {\n      options: {\n        banner: '<%= meta.banner %>',\n        process: function(src, filepath) {\n          // don't strip 'use strict' in the prefix\n          if (filepath === 'bsSwitch.prefix') {\n            return src;\n          }\n          return '// Source: ' + filepath + '\\n' +\n            src.replace(/(^|\\n)[ \\t]*('use strict'|\"use strict\");?\\s*/g, '$1');\n        }\n      },\n      dist: {\n        src: ['bsSwitch.prefix', 'common/*.js', '<%= yeoman.dist %>/<%= yeoman.temp %>/**/*.js', 'bsSwitch.suffix'],\n        dest: '<%= yeoman.dist %>/<%= pkg.name %>.js'\n      }\n    },\n    uglify: {\n      options: {\n        banner: '<%= meta.banner %>'\n      },\n      min: {\n        files: {\n          '<%= yeoman.dist %>/<%= pkg.name %>.min.js': '<%= concat.dist.dest %>'\n        }\n      }\n    }\n  });\n\n  // Test the directive\n  grunt.registerTask('test', ['jshint', 'karma:unit']);\n  grunt.registerTask('test-travis', ['jshint', 'karma:travis']);\n\n  // Build the directive\n  //  - clean, cleans the output directory\n  //  - ngAnnotate, prepares the angular files\n  //  - concat, concatenates and adds a banner to the debug file\n  //  - uglify, minifies and adds a banner to the minified file\n  //  - clean:temp, cleans the ngAnnotate-ified directory\n  grunt.registerTask('build', ['clean', 'ngAnnotate', 'concat', 'uglify', 'clean:temp']);\n\n  // Default task, do everything\n  grunt.registerTask('default', ['test-travis', 'build']);\n};\n"
  },
  {
    "path": "LICENSE",
    "content": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that You\nchanged the files; and\nYou must retain, in the Source form of any Derivative Works that You distribute,\nall copyright, patent, trademark, and attribution notices from the Source form\nof the Work, excluding those notices that do not pertain to any part of the\nDerivative Works; and\nIf the Work includes a \"NOTICE\" text file as part of its distribution, then any\nDerivative Works that You distribute must include a readable copy of the\nattribution notices contained within such NOTICE file, excluding those notices\nthat do not pertain to any part of the Derivative Works, in at least one of the\nfollowing places: within a NOTICE text file distributed as part of the\nDerivative Works; within the Source form or documentation, if provided along\nwith the Derivative Works; or, within a display generated by the Derivative\nWorks, if and wherever such third-party notices normally appear. The contents of\nthe NOTICE file are for informational purposes only and do not modify the\nLicense. You may add Your own attribution notices within Derivative Works that\nYou distribute, alongside or as an addendum to the NOTICE text from the Work,\nprovided that such additional attribution notices cannot be construed as\nmodifying the License.\nYou may add Your own copyright statement to Your modifications and may provide\nadditional or different license terms and conditions for use, reproduction, or\ndistribution of Your modifications, or for any such Derivative Works as a whole,\nprovided Your use, reproduction, and distribution of the Work otherwise complies\nwith the conditions stated in this License.\n\n5. Submission of Contributions.\n\nUnless You explicitly state otherwise, any Contribution intentionally submitted\nfor inclusion in the Work by You to the Licensor shall be under the terms and\nconditions of this License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify the terms of\nany separate license agreement you may have executed with Licensor regarding\nsuch Contributions.\n\n6. Trademarks.\n\nThis License does not grant permission to use the trade names, trademarks,\nservice marks, or product names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty.\n\nUnless required by applicable law or agreed to in writing, Licensor provides the\nWork (and each Contributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,\nincluding, without limitation, any warranties or conditions of TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are\nsolely responsible for determining the appropriateness of using or\nredistributing the Work and assume any risks associated with Your exercise of\npermissions under this License.\n\n8. Limitation of Liability.\n\nIn no event and under no legal theory, whether in tort (including negligence),\ncontract, or otherwise, unless required by applicable law (such as deliberate\nand grossly negligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License or\nout of the use or inability to use the Work (including but not limited to\ndamages for loss of goodwill, work stoppage, computer failure or malfunction, or\nany and all other commercial damages or losses), even if such Contributor has\nbeen advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability.\n\nWhile redistributing the Work or Derivative Works thereof, You may choose to\noffer, and charge a fee for, acceptance of support, warranty, indemnity, or\nother liability obligations and/or rights consistent with this License. However,\nin accepting such obligations, You may act only on Your own behalf and on Your\nsole responsibility, not on behalf of any other Contributor, and only if You\nagree to indemnify, defend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason of your\naccepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\n\nTo apply the Apache License to your work, attach the following boilerplate\nnotice, with the fields enclosed by brackets \"[]\" replaced with your own\nidentifying information. (Don't include the brackets!) The text should be\nenclosed in the appropriate comment syntax for the file format. We also\nrecommend that a file or class name and description of purpose be included on\nthe same \"printed page\" as the copyright notice for easier identification within\nthird-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "angular-bootstrap-switch\n========================\n\n[![Bower version][bower-version-image]][bower-url]\n[![NPM version][npm-version-image]][npm-url]\n[![Build Status][travis-image]][travis-url]\n[![Apache License][license-image]][license-url]\n\nAngularJS directive for the [bootstrap-switch](https://github.com/nostalgiaz/bootstrap-switch) jQuery plugin.\n\n## Usage\n\n### Installation\n```shell\n$ bower install angular-bootstrap-switch\n```\n\nor\n\n```shell\n$ npm install angular-bootstrap-switch\n```\n\nThis will install AngularJS, jQuery, and the original bootstrap-switch.\n\n### Registration\n\nTo be able to use the directive, you need to register the `angular-bootstrap-switch` module as a dependency:\n\n```javascript\nangular.module('yourModule', ['frapontillo.bootstrap-switch'\n    // other dependencies\n]);\n```\n\n### Directive\nThe directive can work on both element and attribute levels. The following example contains all of the supported attributes:\n\n```html\n<input\n    bs-switch\n    ng-model=\"isSelected\"\n    type=\"checkbox\"\n    switch-active=\"{{ isActive }}\"\n    switch-readonly=\"{{ isReadonly }}\"\n    switch-size=\"{{ size }}\"\n    switch-animate=\"{{ animate }}\"\n    switch-label=\"{{ label }}\"\n    switch-icon=\"{{ icon }}\"\n    switch-on-text=\"{{ onLabel }}\"\n    switch-off-text=\"{{ offLabel }}\"\n    switch-on-color=\"{{ on }}\"\n    switch-off-color=\"{{ off }}\"\n    switch-radio-off=\"{{ radioOff }}\"\n    switch-label-width=\"{{ labelWidth }}\"\n    switch-handle-width=\"{{ handleWidth }}\"\n    switch-inverse=\"{{ inverse }}\"\n    switch-change=\"onChange()\"\n    ng-true-value=\"'yep'\"\n    ng-false-value=\"'nope'\">\n```\n\nShort doc for all of the attributes:\n\n* `ng-model`, the value to bind the switch to\n* `type`, has to be one of `checkbox` and `radio`.\nThis value is mandatory and must be a string, as it cannot be changed once set (see [this answer on StackOverflow](http://stackoverflow.com/a/15155407/801065)).\nIf you choose `radio`, be sure to follow the [AngularJS radio specs](https://docs.angularjs.org/api/ng/input/input%5Bradio%5D),\nmeaning you have to specify the same `ngModel` and a different `value` or `ng-value` attribute for each radio\n* `switch-active`, determines if the switch is enabled or not (changes the inner input's `disabled` attribute)\n* `switch-readonly`, determines if the switch is read-only or not (changes the inner input's `readonly` attribute)\n* `switch-size`, can be the empty string as default, `mini`, `small`, `large`\n* `switch-animate`, determines if the switch animates when toggled\n* `switch-on-text`, sets the positive (checked) text\n* `switch-off-text`, sets the negative (unchecked) text\n* `switch-on-color`, sets the positive (checked) class, can be `primary` (as default), `default`, `info`, `success`, `warning`, `danger`\n* `switch-off-color`, sets the negative (unchecked) class, can be `default` (as default), `primary`, `info`, `success`, `warning`, `danger`\n* `switch-label`, sets the toggle label\n* `switch-icon`, sets the toggle icon (e.g. `icon-save`)\n* `switch-wrapper`, sets the main container class, use a falsy value to fall back to the default one\n* `switch-radio-off`, allows a radio button to be unchecked by the user (from `true` to `false`)\n* `switch-label-width`, sets the width of the middle label\n* `switch-handle-width`, sets the width of both handles\n* `switch-inverse`, inverts the on/off handles\n* `switch-change`, evaluates an expression whenever the model value changes. Instead, `ng-change` will fire when view value changes (e.g from a click)\n\n### Migrating from bootstrap-switch~2\n\nRead the [CHANGELOG](CHANGELOG.md#030-alpha1-2014-02-22) information to learn what's different in `0.3.0`.\n\n### Examples\n\nThe `example` folder shows a simple working demo of the switch.\n\n### Compatibility\n\nIE8 requires you to attach the directive to an `<input type=\"checkbox\">` or `<input type=\"radio\">`. Due to some incompatibilities it is not possible to use a custom tag or `div` instead.\n\n## Development\n\n### Test and build\n\nTo build the directive yourself you need to have NodeJS. Then do the following:\n\n```shell\n$ npm install -g grunt-cli bower karma\n$ npm install\n$ bower install\n$ grunt test-travis\n$ grunt build\n```\n\n### Contribute\n\nTo contribute, please follow the generic [AngularJS Contributing Guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md), with the only exception to send the PR to the `develop` branch instead of `master`.\n\n## Author\n\nFrancesco Pontillo (<mailto:francescopontillo@gmail.com>)\n\n## License\n\n```\n   Copyright 2014-2017 Francesco Pontillo\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n```\n\n[license-image]: http://img.shields.io/badge/license-Apache_2.0-blue.svg?style=flat\n[license-url]: LICENSE\n\n[bower-version-image]: http://img.shields.io/bower/v/angular-bootstrap-switch.svg?style=flat\n[bower-url]: http://bower.io/search/?q=angular-bootstrap-switch\n\n[npm-url]: https://npmjs.org/package/angular-bootstrap-switch\n[npm-version-image]: http://img.shields.io/npm/v/angular-bootstrap-switch.svg?style=flat\n\n[travis-image]: http://img.shields.io/travis/frapontillo/angular-bootstrap-switch/develop.svg?style=flat\n[travis-url]: https://travis-ci.org/frapontillo/angular-bootstrap-switch\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"angular-bootstrap-switch\",\n  \"version\": \"0.5.2\",\n  \"author\": {\n    \"name\": \"Francesco Pontillo\",\n    \"email\": \"francescopontillo@gmail.com\",\n    \"url\": \"https://github.com/frapontillo\"\n  },\n  \"homepage\": \"https://github.com/frapontillo/angular-bootstrap-switch\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:frapontillo/angular-bootstrap-switch.git\"\n  },\n  \"licenses\": [\n    {\n      \"type\": \"Apache License 2.0\",\n      \"url\": \"http://www.apache.org/licenses/LICENSE-2.0.html\"\n    }\n  ],\n  \"main\": \"./dist/angular-bootstrap-switch.js\",\n  \"dependencies\": {\n    \"angular\": \">=1.4.0\",\n    \"jquery\": \">=1.9.0\",\n    \"bootstrap\": \">=2.3.2\",\n    \"bootstrap-switch\": \"~3.3.4\"\n  },\n  \"devDependencies\": {\n    \"angular-mocks\": \">=1.4.0\",\n    \"angular-scenario\": \">=1.4.0\"\n  }\n}\n"
  },
  {
    "path": "bsSwitch.prefix",
    "content": "(function() {\n'use strict';\n"
  },
  {
    "path": "bsSwitch.suffix",
    "content": "})();"
  },
  {
    "path": "common/module.js",
    "content": "'use strict';\n\nangular.module('frapontillo.bootstrap-switch', []);\n"
  },
  {
    "path": "dist/angular-bootstrap-switch.js",
    "content": "/**\n * angular-bootstrap-switch\n * @version v0.5.2 - 2017-04-19\n * @author Francesco Pontillo (francescopontillo@gmail.com)\n * @link https://github.com/frapontillo/angular-bootstrap-switch\n * @license Apache License 2.0(http://www.apache.org/licenses/LICENSE-2.0.html)\n**/\n\n(function() {\n'use strict';\n\n// Source: common/module.js\nangular.module('frapontillo.bootstrap-switch', []);\n\n// Source: dist/.temp/directives/bsSwitch.js\nangular.module('frapontillo.bootstrap-switch')\n  .directive('bsSwitch', [\"$parse\", \"$timeout\", function ($parse, $timeout) {\n    return {\n      restrict: 'A',\n      require: 'ngModel',\n      link: function link(scope, element, attrs, controller) {\n        var isInit = false;\n\n        /**\n         * Return the true value for this specific checkbox.\n         * @returns {Object} representing the true view value; if undefined, returns true.\n         */\n        var getTrueValue = function() {\n          if (attrs.type === 'radio') {\n            return attrs.value || $parse(attrs.ngValue)(scope) || true;\n          }\n          var trueValue = ($parse(attrs.ngTrueValue)(scope));\n          if (angular.isUndefined(trueValue)) {\n            trueValue = true;\n          }\n          return trueValue;\n        };\n\n        /**\n         * Get a boolean value from a boolean-like string, evaluating it on the current scope.\n         * @param value The input object\n         * @returns {boolean} A boolean value\n         */\n        var getBooleanFromString = function(value) {\n          return scope.$eval(value) === true;\n        };\n\n        /**\n         * Get a boolean value from a boolean-like string, defaulting to true if undefined.\n         * @param value The input object\n         * @returns {boolean} A boolean value\n         */\n        var getBooleanFromStringDefTrue = function(value) {\n          return (value === true || value === 'true' || !value);\n        };\n\n        /**\n         * Returns the value if it is truthy, or undefined.\n         *\n         * @param value The value to check.\n         * @returns the original value if it is truthy, {@link undefined} otherwise.\n         */\n        var getValueOrUndefined = function (value) {\n          return (value ? value : undefined);\n        };\n\n        /**\n         * Returns a function that executes the provided expression\n         *\n         * @param value The string expression\n         * @return a function that evaluates the expression\n         */\n        var getExprFromString = function (value) {\n          if (angular.isUndefined(value)) {\n            return angular.noop;\n          }\n          return function () {\n            scope.$evalAsync(value);\n          };\n        };\n\n        /**\n         * Get the value of the angular-bound attribute, given its name.\n         * The returned value may or may not equal the attribute value, as it may be transformed by a function.\n         *\n         * @param attrName  The angular-bound attribute name to get the value for\n         * @returns {*}     The attribute value\n         */\n        var getSwitchAttrValue = function(attrName) {\n          var map = {\n            'switchRadioOff': getBooleanFromStringDefTrue,\n            'switchActive': function(value) {\n              return !getBooleanFromStringDefTrue(value);\n            },\n            'switchAnimate': getBooleanFromStringDefTrue,\n            'switchLabel': function(value) {\n              return value ? value : '&nbsp;';\n            },\n            'switchIcon': function(value) {\n              if (value) {\n                return '<span class=\\'' + value + '\\'></span>';\n              }\n            },\n            'switchWrapper': function(value) {\n              return value || 'wrapper';\n            },\n            'switchInverse': getBooleanFromString,\n            'switchReadonly': getBooleanFromString,\n            'switchChange': getExprFromString\n          };\n          var transFn = map[attrName] || getValueOrUndefined;\n          return transFn(attrs[attrName]);\n        };\n\n        /**\n         * Set a bootstrapSwitch parameter according to the angular-bound attribute.\n         * The parameter will be changed only if the switch has already been initialized\n         * (to avoid creating it before the model is ready).\n         *\n         * @param element   The switch to apply the parameter modification to\n         * @param attr      The name of the switch parameter\n         * @param modelAttr The name of the angular-bound parameter\n         */\n        var setSwitchParamMaybe = function(element, attr, modelAttr) {\n          if (!isInit) {\n            return;\n          }\n          var newValue = getSwitchAttrValue(modelAttr);\n          element.bootstrapSwitch(attr, newValue);\n        };\n\n        var setActive = function() {\n          setSwitchParamMaybe(element, 'disabled', 'switchActive');\n        };\n\n        /**\n         * If the directive has not been initialized yet, do so.\n         */\n        var initMaybe = function() {\n          // if it's the first initialization\n          if (!isInit) {\n            var viewValue = (controller.$modelValue === getTrueValue());\n            isInit = !isInit;\n            // Bootstrap the switch plugin\n            element.bootstrapSwitch({\n              radioAllOff: getSwitchAttrValue('switchRadioOff'),\n              disabled: getSwitchAttrValue('switchActive'),\n              state: viewValue,\n              onText: getSwitchAttrValue('switchOnText'),\n              offText: getSwitchAttrValue('switchOffText'),\n              onColor: getSwitchAttrValue('switchOnColor'),\n              offColor: getSwitchAttrValue('switchOffColor'),\n              animate: getSwitchAttrValue('switchAnimate'),\n              size: getSwitchAttrValue('switchSize'),\n              labelText: attrs.switchLabel ? getSwitchAttrValue('switchLabel') : getSwitchAttrValue('switchIcon'),\n              wrapperClass: getSwitchAttrValue('switchWrapper'),\n              handleWidth: getSwitchAttrValue('switchHandleWidth'),\n              labelWidth: getSwitchAttrValue('switchLabelWidth'),\n              inverse: getSwitchAttrValue('switchInverse'),\n              readonly: getSwitchAttrValue('switchReadonly')\n            });\n            if (attrs.type === 'radio') {\n              controller.$setViewValue(controller.$modelValue);\n            } else {\n              controller.$setViewValue(viewValue);\n            }\n          }\n        };\n\n        var switchChange = getSwitchAttrValue('switchChange');\n\n        /**\n         * Listen to model changes.\n         */\n        var listenToModel = function () {\n\n          attrs.$observe('switchActive', function (newValue) {\n\n            var active = getBooleanFromStringDefTrue(newValue);\n            // if we are disabling the switch, delay the deactivation so that the toggle can be switched\n            if (!active) {\n              $timeout(setActive);\n            } else {\n              // if we are enabling the switch, set active right away\n              setActive();\n            }\n          });\n\n          // When the model changes\n          controller.$render = function () {\n            initMaybe();\n            var newValue = controller.$modelValue;\n            if (newValue !== undefined && newValue !== null) {\n              element.bootstrapSwitch('state', newValue === getTrueValue(), true);\n            } else {\n              element.bootstrapSwitch('indeterminate', true, true);\n              controller.$setViewValue(undefined);\n            }\n            switchChange();\n          };\n\n          // angular attribute to switch property bindings\n          var bindings = {\n            'switchRadioOff': 'radioAllOff',\n            'switchOnText': 'onText',\n            'switchOffText': 'offText',\n            'switchOnColor': 'onColor',\n            'switchOffColor': 'offColor',\n            'switchAnimate': 'animate',\n            'switchSize': 'size',\n            'switchLabel': 'labelText',\n            'switchIcon': 'labelText',\n            'switchWrapper': 'wrapperClass',\n            'switchHandleWidth': 'handleWidth',\n            'switchLabelWidth': 'labelWidth',\n            'switchInverse': 'inverse',\n            'switchReadonly': 'readonly'\n          };\n\n          var observeProp = function(prop, bindings) {\n            return function() {\n              attrs.$observe(prop, function () {\n                setSwitchParamMaybe(element, bindings[prop], prop);\n              });\n            };\n          };\n\n          // for every angular-bound attribute, observe it and trigger the appropriate switch function\n          for (var prop in bindings) {\n            attrs.$observe(prop, observeProp(prop, bindings));\n          }\n        };\n\n        /**\n         * Listen to view changes.\n         */\n        var listenToView = function () {\n\n          if (attrs.type === 'radio') {\n            // when the switch is clicked\n            element.on('change.bootstrapSwitch', function (e) {\n              // discard not real change events\n              if ((controller.$modelValue === controller.$viewValue) && (e.target.checked !== $(e.target).bootstrapSwitch('state'))) {\n                // $setViewValue --> $viewValue --> $parsers --> $modelValue\n                // if the switch is indeed selected\n                if (e.target.checked) {\n                  // set its value into the view\n                  controller.$setViewValue(getTrueValue());\n                } else if (getTrueValue() === controller.$viewValue) {\n                  // otherwise if it's been deselected, delete the view value\n                  controller.$setViewValue(undefined);\n                }\n                switchChange();\n              }\n            });\n          } else {\n            // When the checkbox switch is clicked, set its value into the ngModel\n            element.on('switchChange.bootstrapSwitch', function (e) {\n              // $setViewValue --> $viewValue --> $parsers --> $modelValue\n              controller.$setViewValue(e.target.checked);\n              switchChange();\n            });\n          }\n        };\n\n        // Listen and respond to view changes\n        listenToView();\n\n        // Listen and respond to model changes\n        listenToModel();\n\n        // On destroy, collect ya garbage\n        scope.$on('$destroy', function () {\n          element.bootstrapSwitch('destroy');\n        });\n      }\n    };\n  }])\n  .directive('bsSwitch', function () {\n    return {\n      restrict: 'E',\n      require: 'ngModel',\n      template: '<input bs-switch>',\n      replace: true\n    };\n  });\n\n// Source: bsSwitch.suffix\n})();"
  },
  {
    "path": "example/index.html",
    "content": "<!doctype html>\n<!--[if lt IE 7]>\n<html class=\"no-js lt-ie9 lt-ie8 lt-ie7\"> <![endif]-->\n<!--[if IE 7]>\n<html class=\"no-js lt-ie9 lt-ie8\"> <![endif]-->\n<!--[if IE 8]>\n<html class=\"no-js lt-ie9\"> <![endif]-->\n<!--[if gt IE 8]><!-->\n<html class=\"no-js\"> <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>AngularJS Bootstrap Switch example</title>\n  <meta name=\"description\" content=\"\">\n  <meta name=\"viewport\" content=\"width=device-width\">\n  <link rel=\"stylesheet\" href=\"styles/main.css\">\n  <link rel=\"stylesheet\" href=\"../bower_components/bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.css\">\n</head>\n<body ng-app=\"bsSwitchApp\">\n\n<!--[if lt IE 9]>\n<script src=\"../bower_components/es5-shim/es5-shim.js\"></script>\n<script src=\"../bower_components/json3/lib/json3.min.js\"></script>\n<![endif]-->\n\n<form name=\"form\" class=\"container\" ng-controller=\"MainCtrl\">\n\n  <!--<input\n    bs-switch\n    ng-model=\"isSelected\"\n    type=\"radio\"\n    switch-active=\"{{ isActive }}\"\n    switch-on-text=\"{{ onText }}\"\n    switch-off-text=\"{{ offText }}\"\n    switch-on-color=\"{{ onColor }}\"\n    switch-off-color=\"{{ 'danger' }}\"\n    switch-animate=\"{{ animate }}\"\n    switch-size=\"{{ size }}\"\n    switch-label=\"{{ label }}\"\n    switch-icon=\"{{ icon }}\"\n    switch-radio-off=\"{{ radioOff }}\"\n    switch-label-width=\"{{ labelWidth }}\"\n    switch-handle-width=\"{{ handleWidth }}\"\n    switch-wrapper=\"{{ wrapper }}\"\n    ng-value=\"'uno'\"\n    ng-true-value=\"'yep'\"\n    ng-false-value=\"'nope'\"\n    switch-inverse=\"{{ !inverse }}\"\n    switch-readonly=\"{{ readonly }}\">\n\n  <input\n    bs-switch\n    ng-model=\"isSelected\"\n    type=\"radio\"\n    switch-active=\"{{ isActive }}\"\n    switch-on-text=\"{{ onText }}\"\n    switch-off-text=\"{{ offText }}\"\n    switch-on-color=\"{{ onColor }}\"\n    switch-off-color=\"{{ offColor }}\"\n    switch-animate=\"{{ animate }}\"\n    switch-size=\"{{ size }}\"\n    switch-label=\"{{ label }}\"\n    switch-icon=\"{{ icon }}\"\n    switch-radio-off=\"{{ radioOff }}\"\n    switch-label-width=\"{{ labelWidth }}\"\n    switch-handle-width=\"{{ handleWidth }}\"\n    switch-wrapper=\"{{ wrapper }}\"\n    ng-value=\"'dos'\"\n    ng-true-value=\"'yep'\"\n    ng-false-value=\"'nope'\"\n    switch-inverse=\"{{ !inverse }}\">-->\n\n  {{ isSelected }}\n\n  <br>\n\n  <input\n    bs-switch\n    ng-model=\"isSelected\"\n    type=\"checkbox\"\n    switch-active=\"{{ isActive }}\"\n    switch-on-text=\"{{ onText }}\"\n    switch-off-text=\"{{ offText }}\"\n    switch-on-color=\"{{ onColor }}\"\n    switch-off-color=\"{{ offColor }}\"\n    switch-animate=\"{{ animate }}\"\n    switch-size=\"{{ size }}\"\n    switch-label=\"{{ label }}\"\n    switch-icon=\"{{ icon }}\"\n    switch-radio-off=\"{{ radioOff }}\"\n    switch-label-width=\"{{ labelWidth }}\"\n    switch-handle-width=\"{{ handleWidth }}\"\n    switch-wrapper=\"{{ wrapper }}\"\n    ng-true-value=\"'yep'\"\n    ng-false-value=\"'nope'\"\n    switch-inverse=\"{{ !inverse }}\">\n\n  <input type=\"button\" value=\"toggle value\" ng-click=\"toggle()\">\n  <input type=\"button\" value=\"toggle value / activation\" ng-click=\"toggle(); toggleActivation();\">\n  <input type=\"button\" value=\"set undefined value\" ng-click=\"setUndefined()\">\n</form>\n</div>\n\n<script src=\"../bower_components/jquery/dist/jquery.js\"></script>\n<script src=\"../bower_components/bootstrap/dist/js/bootstrap.js\"></script>\n<script src=\"../bower_components/bootstrap-switch/dist/js/bootstrap-switch.js\"></script>\n\n<script src=\"../bower_components/angular/angular.js\"></script>\n<script src=\"../common/module.js\"></script>\n<script src=\"../src/directives/bsSwitch.js\"></script>\n\n<script src=\"scripts/app.js\"></script>\n<script src=\"scripts/controllers/main.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "example/scripts/app.js",
    "content": "'use strict';\n\nangular.module('bsSwitchApp', ['frapontillo.bootstrap-switch']);\n"
  },
  {
    "path": "example/scripts/controllers/main.js",
    "content": "'use strict';\n\nangular.module('bsSwitchApp')\n  .controller('MainCtrl', function ($scope, $log) {\n    $scope.isSelected = 'nope';\n    $scope.onText = 'Y';\n    $scope.offText = 'N';\n    $scope.isActive = true;\n    $scope.size = 'normal';\n    $scope.animate = true;\n    $scope.radioOff = true;\n    $scope.handleWidth = \"auto\";\n    $scope.labelWidth = \"auto\";\n    $scope.inverse = true;\n\n    $scope.$watch('isSelected', function() {\n      $log.info('Selection changed.');\n    });\n\n    $scope.toggle = function() {\n      $scope.isSelected = $scope.isSelected === 'yep' ? 'nope' : 'yep';\n    };\n\n    $scope.setUndefined = function() {\n      $scope.isSelected = undefined;\n    };\n\n    $scope.toggleActivation = function() {\n      $scope.isActive = !$scope.isActive;\n    }\n  });\n"
  },
  {
    "path": "example/styles/main.css",
    "content": "body {\n    background: #fafafa;\n    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    color: #333;\n}\n\n.hero-unit {\n    margin: 50px auto 0 auto;\n    width: 300px;\n    font-size: 18px;\n    font-weight: 200;\n    line-height: 30px;\n    background-color: #eee;\n    border-radius: 6px;\n    padding: 60px;\n}\n\n.hero-unit h1 {\n    font-size: 60px;\n    line-height: 1;\n    letter-spacing: -1px;\n}\n"
  },
  {
    "path": "karma-chrome.conf.js",
    "content": "// Karma configuration\n// Generated on Thu Mar 27 2014 09:18:43 GMT+0100 (ora solare Europa occidentale)\n\nmodule.exports = function(config) {\n  config.set({\n\n    // base path that will be used to resolve all patterns (eg. files, exclude)\n    basePath: '',\n\n\n    // frameworks to use\n    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter\n    frameworks: ['jasmine'],\n\n\n    // list of files / patterns to load in the browser\n    files: [\n      'bower_components/jquery/jquery.js',\n      'bower_components/angular/angular.js',\n      'bower_components/angular-mocks/angular-mocks.js',\n      'bower_components/bootstrap-switch/dist/js/bootstrap-switch.js',\n      'common/module.js',\n      'src/**/*.js',\n      'test/**/*.js'\n    ],\n\n\n    // list of files to exclude\n    exclude: [\n      \n    ],\n\n\n    // preprocess matching files before serving them to the browser\n    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor\n    preprocessors: {\n    \n    },\n\n\n    // test results reporter to use\n    // possible values: 'dots', 'progress'\n    // available reporters: https://npmjs.org/browse/keyword/karma-reporter\n    reporters: ['progress'],\n\n\n    // web server port\n    port: 9876,\n\n\n    // enable / disable colors in the output (reporters and logs)\n    colors: true,\n\n\n    // level of logging\n    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\n    logLevel: config.LOG_INFO,\n\n\n    // enable / disable watching file and executing tests whenever any file changes\n    autoWatch: true,\n\n\n    // start these browsers\n    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher\n    browsers: ['Chrome'],\n\n\n    // Continuous Integration mode\n    // if true, Karma captures browsers, runs the tests and exits\n    singleRun: false\n  });\n};\n"
  },
  {
    "path": "karma.conf.js",
    "content": "// Karma configuration\n// Generated on Thu Mar 27 2014 09:18:43 GMT+0100 (ora solare Europa occidentale)\n\nmodule.exports = function(config) {\n  config.set({\n\n    // base path that will be used to resolve all patterns (eg. files, exclude)\n    basePath: '',\n\n\n    // frameworks to use\n    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter\n    frameworks: ['jasmine'],\n\n\n    // list of files / patterns to load in the browser\n    files: [\n      'bower_components/jquery/jquery.js',\n      'bower_components/angular/angular.js',\n      'bower_components/angular-mocks/angular-mocks.js',\n      'bower_components/bootstrap-switch/dist/js/bootstrap-switch.js',\n      'common/module.js',\n      'src/**/*.js',\n      'test/**/*.js'\n    ],\n\n\n    // list of files to exclude\n    exclude: [\n\n    ],\n\n\n    // preprocess matching files before serving them to the browser\n    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor\n    preprocessors: {\n\n    },\n\n\n    // test results reporter to use\n    // possible values: 'dots', 'progress'\n    // available reporters: https://npmjs.org/browse/keyword/karma-reporter\n    reporters: ['progress'],\n\n\n    // web server port\n    port: 9876,\n\n\n    // enable / disable colors in the output (reporters and logs)\n    colors: true,\n\n\n    // level of logging\n    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\n    logLevel: config.LOG_INFO,\n\n\n    // enable / disable watching file and executing tests whenever any file changes\n    autoWatch: true,\n\n\n    // start these browsers\n    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher\n    browsers: ['Chrome', 'Firefox', 'PhantomJS'],\n\n\n    // Continuous Integration mode\n    // if true, Karma captures browsers, runs the tests and exits\n    singleRun: false\n  });\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"angular-bootstrap-switch\",\n  \"version\": \"0.5.2\",\n  \"main\": \"dist/angular-bootstrap-switch.js\",\n  \"author\": {\n    \"name\": \"Francesco Pontillo\",\n    \"email\": \"francescopontillo@gmail.com\",\n    \"url\": \"https://github.com/frapontillo\"\n  },\n  \"homepage\": \"https://github.com/frapontillo/angular-bootstrap-switch\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:frapontillo/angular-bootstrap-switch.git\"\n  },\n  \"license\": \"Apache-2.0\",\n  \"dependencies\": {\n    \"angular\": \">=1.4.0\",\n    \"jquery\": \">=1.9.0\",\n    \"bootstrap\": \">=2.3.2\",\n    \"bootstrap-switch\": \"3.3.2\"\n  },\n  \"devDependencies\": {\n    \"grunt\": \"~0.4.5\",\n    \"grunt-contrib-clean\": \"~0.7.0\",\n    \"grunt-contrib-concat\": \"~0.5.1\",\n    \"grunt-contrib-jshint\": \"~0.11.0\",\n    \"grunt-contrib-uglify\": \"~0.11.0\",\n    \"grunt-karma\": \"~0.12.1\",\n    \"grunt-ng-annotate\": \"^1.0.1\",\n    \"jasmine-core\": \"^2.4.1\",\n    \"karma\": \"^0.13.19\",\n    \"karma-chrome-launcher\": \"~0.2.2\",\n    \"karma-firefox-launcher\": \"~0.1.7\",\n    \"karma-jasmine\": \"~0.3.6\",\n    \"karma-phantomjs-launcher\": \"~1.0.0\",\n    \"matchdep\": \"~1.0.0\",\n    \"phantomjs-prebuilt\": \"^2.1.3\"\n  },\n  \"engines\": {\n    \"node\": \">=4.0.0\"\n  },\n  \"scripts\": {\n    \"test\": \"grunt test-travis\"\n  }\n}\n"
  },
  {
    "path": "src/directives/bsSwitch.js",
    "content": "'use strict';\n\nangular.module('frapontillo.bootstrap-switch')\n  .directive('bsSwitch', function ($parse, $timeout) {\n    return {\n      restrict: 'A',\n      require: 'ngModel',\n      link: function link(scope, element, attrs, controller) {\n        var isInit = false;\n\n        /**\n         * Return the true value for this specific checkbox.\n         * @returns {Object} representing the true view value; if undefined, returns true.\n         */\n        var getTrueValue = function() {\n          if (attrs.type === 'radio') {\n            return attrs.value || $parse(attrs.ngValue)(scope) || true;\n          }\n          var trueValue = ($parse(attrs.ngTrueValue)(scope));\n          if (angular.isUndefined(trueValue)) {\n            trueValue = true;\n          }\n          return trueValue;\n        };\n\n        /**\n         * Get a boolean value from a boolean-like string, evaluating it on the current scope.\n         * @param value The input object\n         * @returns {boolean} A boolean value\n         */\n        var getBooleanFromString = function(value) {\n          return scope.$eval(value) === true;\n        };\n\n        /**\n         * Get a boolean value from a boolean-like string, defaulting to true if undefined.\n         * @param value The input object\n         * @returns {boolean} A boolean value\n         */\n        var getBooleanFromStringDefTrue = function(value) {\n          return (value === true || value === 'true' || !value);\n        };\n\n        /**\n         * Returns the value if it is truthy, or undefined.\n         *\n         * @param value The value to check.\n         * @returns the original value if it is truthy, {@link undefined} otherwise.\n         */\n        var getValueOrUndefined = function (value) {\n          return (value ? value : undefined);\n        };\n\n        /**\n         * Returns a function that executes the provided expression\n         *\n         * @param value The string expression\n         * @return a function that evaluates the expression\n         */\n        var getExprFromString = function (value) {\n          if (angular.isUndefined(value)) {\n            return angular.noop;\n          }\n          return function () {\n            scope.$evalAsync(value);\n          };\n        };\n\n        /**\n         * Get the value of the angular-bound attribute, given its name.\n         * The returned value may or may not equal the attribute value, as it may be transformed by a function.\n         *\n         * @param attrName  The angular-bound attribute name to get the value for\n         * @returns {*}     The attribute value\n         */\n        var getSwitchAttrValue = function(attrName) {\n          var map = {\n            'switchRadioOff': getBooleanFromStringDefTrue,\n            'switchActive': function(value) {\n              return !getBooleanFromStringDefTrue(value);\n            },\n            'switchAnimate': getBooleanFromStringDefTrue,\n            'switchLabel': function(value) {\n              return value ? value : '&nbsp;';\n            },\n            'switchIcon': function(value) {\n              if (value) {\n                return '<span class=\\'' + value + '\\'></span>';\n              }\n            },\n            'switchWrapper': function(value) {\n              return value || 'wrapper';\n            },\n            'switchInverse': getBooleanFromString,\n            'switchReadonly': getBooleanFromString,\n            'switchChange': getExprFromString\n          };\n          var transFn = map[attrName] || getValueOrUndefined;\n          return transFn(attrs[attrName]);\n        };\n\n        /**\n         * Set a bootstrapSwitch parameter according to the angular-bound attribute.\n         * The parameter will be changed only if the switch has already been initialized\n         * (to avoid creating it before the model is ready).\n         *\n         * @param element   The switch to apply the parameter modification to\n         * @param attr      The name of the switch parameter\n         * @param modelAttr The name of the angular-bound parameter\n         */\n        var setSwitchParamMaybe = function(element, attr, modelAttr) {\n          if (!isInit) {\n            return;\n          }\n          var newValue = getSwitchAttrValue(modelAttr);\n          element.bootstrapSwitch(attr, newValue);\n        };\n\n        var setActive = function() {\n          setSwitchParamMaybe(element, 'disabled', 'switchActive');\n        };\n\n        /**\n         * If the directive has not been initialized yet, do so.\n         */\n        var initMaybe = function() {\n          // if it's the first initialization\n          if (!isInit) {\n            var viewValue = (controller.$modelValue === getTrueValue());\n            isInit = !isInit;\n            // Bootstrap the switch plugin\n            element.bootstrapSwitch({\n              radioAllOff: getSwitchAttrValue('switchRadioOff'),\n              disabled: getSwitchAttrValue('switchActive'),\n              state: viewValue,\n              onText: getSwitchAttrValue('switchOnText'),\n              offText: getSwitchAttrValue('switchOffText'),\n              onColor: getSwitchAttrValue('switchOnColor'),\n              offColor: getSwitchAttrValue('switchOffColor'),\n              animate: getSwitchAttrValue('switchAnimate'),\n              size: getSwitchAttrValue('switchSize'),\n              labelText: attrs.switchLabel ? getSwitchAttrValue('switchLabel') : getSwitchAttrValue('switchIcon'),\n              wrapperClass: getSwitchAttrValue('switchWrapper'),\n              handleWidth: getSwitchAttrValue('switchHandleWidth'),\n              labelWidth: getSwitchAttrValue('switchLabelWidth'),\n              inverse: getSwitchAttrValue('switchInverse'),\n              readonly: getSwitchAttrValue('switchReadonly')\n            });\n            if (attrs.type === 'radio') {\n              controller.$setViewValue(controller.$modelValue);\n            } else {\n              controller.$setViewValue(viewValue);\n              controller.$formatters[0] = function(value) {\n                if (value === undefined || value === null) {\n                  return value;\n                }\n                return angular.equals(value, getTrueValue());\n              };\n            }\n          }\n        };\n\n        var switchChange = getSwitchAttrValue('switchChange');\n\n        /**\n         * Listen to model changes.\n         */\n        var listenToModel = function () {\n\n          attrs.$observe('switchActive', function (newValue) {\n\n            var active = getBooleanFromStringDefTrue(newValue);\n            // if we are disabling the switch, delay the deactivation so that the toggle can be switched\n            if (!active) {\n              $timeout(setActive);\n            } else {\n              // if we are enabling the switch, set active right away\n              setActive();\n            }\n          });\n\n          // When the model changes\n          controller.$render = function () {\n            initMaybe();\n\n            // WORKAROUND for https://github.com/Bttstrp/bootstrap-switch/issues/540\n            // to update model value when bootstrapSwitch is disabled we should\n            // re-enable it and only then update 'state'\n            element.bootstrapSwitch('disabled', '');\n\n            var newValue = controller.$modelValue;\n            if (newValue !== undefined && newValue !== null) {\n              element.bootstrapSwitch('state', newValue === getTrueValue(), true);\n            } else {\n              element.bootstrapSwitch('indeterminate', true, true);\n              controller.$setViewValue(undefined);\n            }\n\n            // return initial value for \"disabled\"\n            setActive();\n\n            switchChange();\n          };\n\n          // angular attribute to switch property bindings\n          var bindings = {\n            'switchRadioOff': 'radioAllOff',\n            'switchOnText': 'onText',\n            'switchOffText': 'offText',\n            'switchOnColor': 'onColor',\n            'switchOffColor': 'offColor',\n            'switchAnimate': 'animate',\n            'switchSize': 'size',\n            'switchLabel': 'labelText',\n            'switchIcon': 'labelText',\n            'switchWrapper': 'wrapperClass',\n            'switchHandleWidth': 'handleWidth',\n            'switchLabelWidth': 'labelWidth',\n            'switchInverse': 'inverse',\n            'switchReadonly': 'readonly'\n          };\n\n          var observeProp = function(prop, bindings) {\n            return function() {\n              attrs.$observe(prop, function () {\n                setSwitchParamMaybe(element, bindings[prop], prop);\n              });\n            };\n          };\n\n          // for every angular-bound attribute, observe it and trigger the appropriate switch function\n          for (var prop in bindings) {\n            attrs.$observe(prop, observeProp(prop, bindings));\n          }\n        };\n\n        /**\n         * Listen to view changes.\n         */\n        var listenToView = function () {\n\n          if (attrs.type === 'radio') {\n            // when the switch is clicked\n            element.on('change.bootstrapSwitch', function (e) {\n              // discard not real change events\n              if ((controller.$modelValue === controller.$viewValue) && (e.target.checked !== $(e.target).bootstrapSwitch('state'))) {\n                // $setViewValue --> $viewValue --> $parsers --> $modelValue\n                // if the switch is indeed selected\n                if (e.target.checked) {\n                  // set its value into the view\n                  controller.$setViewValue(getTrueValue());\n                } else if (getTrueValue() === controller.$viewValue) {\n                  // otherwise if it's been deselected, delete the view value\n                  controller.$setViewValue(undefined);\n                }\n                switchChange();\n              }\n            });\n          } else {\n            // When the checkbox switch is clicked, set its value into the ngModel\n            element.on('switchChange.bootstrapSwitch', function (e) {\n              // $setViewValue --> $viewValue --> $parsers --> $modelValue\n              controller.$setViewValue(e.target.checked);\n              switchChange();\n            });\n          }\n        };\n\n        // Listen and respond to view changes\n        listenToView();\n\n        // Listen and respond to model changes\n        listenToModel();\n\n        // On destroy, collect ya garbage\n        scope.$on('$destroy', function () {\n          element.bootstrapSwitch('destroy');\n        });\n      }\n    };\n  })\n  .directive('bsSwitch', function () {\n    return {\n      restrict: 'E',\n      require: 'ngModel',\n      template: '<input bs-switch>',\n      replace: true\n    };\n  });\n"
  },
  {
    "path": "test/.jshintrc",
    "content": "{\n  \"node\": true,\n  \"browser\": true,\n  \"esnext\": true,\n  \"bitwise\": true,\n  \"camelcase\": true,\n  \"curly\": true,\n  \"eqeqeq\": true,\n  \"immed\": true,\n  \"indent\": 2,\n  \"latedef\": true,\n  \"newcap\": true,\n  \"noarg\": true,\n  \"quotmark\": \"single\",\n  \"regexp\": true,\n  \"undef\": true,\n  \"unused\": true,\n  \"strict\": true,\n  \"trailing\": true,\n  \"smarttabs\": true,\n  \"globals\": {\n    \"jQuery\": false,\n    \"after\": false,\n    \"afterEach\": false,\n    \"angular\": false,\n    \"before\": false,\n    \"beforeEach\": false,\n    \"browser\": false,\n    \"describe\": false,\n    \"expect\": false,\n    \"inject\": false,\n    \"it\": false,\n    \"spyOn\": false,\n    \"jasmine\": false\n  }\n}\n\n"
  },
  {
    "path": "test/runner.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <title>End2end Test Runner</title>\n    <script src=\"vendor/angular-scenario.js\" ng-autotest></script>\n    <script src=\"scenarios.js\"></script>\n  </head>\n  <body>\n  </body>\n</html>"
  },
  {
    "path": "test/spec/directives/bsSwitchSpec.js",
    "content": "'use strict';\n\ndescribe('Directive: bsSwitch', function () {\n  var scope, $sandbox, $compile, $timeout;\n\n  beforeEach(module('frapontillo.bootstrap-switch'));\n\n  /* jshint camelcase: false */\n  beforeEach(inject(function ($injector, $rootScope, _$compile_, _$timeout_) {\n    scope = $rootScope;\n    $compile = _$compile_;\n    $timeout = _$timeout_;\n    $sandbox = angular.element('<div id=\"sandbox\"></div>').appendTo(angular.element.find('body'));\n  }));\n  /* jshint camelcase: true */\n\n  afterEach(function() {\n    $sandbox.remove();\n    scope.$destroy();\n  });\n\n  var templates = {\n    'default': {\n      scope: {model:true},\n      element: 'ng-model=\"model\" type=\"checkbox\"'\n    },\n    'multipleRadios': {\n      scope: {model:''},\n      element: [\n        'ng-model=\"model\" name=\"radio\" type=\"radio\" value=\"uno\"',\n        'ng-model=\"model\" name=\"radio\" type=\"radio\" value=\"dos\"',\n        'ng-model=\"model\" name=\"radio\" type=\"radio\" value=\"tres\"'\n      ]\n    },\n    'radio': {\n      scope: {model:true},\n      element: 'ng-model=\"model\" name=\"radio\" type=\"radio\"'\n    },\n    'radioOff': {\n      scope: {model:true, radioOff:false},\n      element: 'ng-model=\"model\" name=\"radio\" type=\"radio\" switch-radio-off=\"{{ radioOff }}\"'\n    },\n    'active': {\n      scope: {model:true, isActive:true},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-active=\"{{ isActive }}\"'\n    },\n    'unactivated': {\n      scope: {model:true, isActive:false},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-active=\"{{ isActive }}\"'\n    },\n    'readonly': {\n      scope: {model:true},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-readonly=\"{{ isReadonly }}\"'\n    },\n    'size': {\n      scope: {model:true, size:'large'},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-size=\"{{ size }}\" switch-label-width=\"{{ labelWidth }}\" switch-handle-width=\"{{ handleWidth }}\"'\n    },\n    'color': {\n      scope: {model:true, on:'info', off:'warning'},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-on-color=\"{{ on }}\" switch-off-color=\"{{ off }}\"'\n    },\n    'label': {\n      scope: {model:true},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-on-text=\"{{ on }}\" switch-off-text=\"{{ off }}\" switch-label=\"{{ label }}\"'\n    },\n    'icon': {\n      scope: {model:true, icon:'icon-youtube'},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-icon=\"{{ icon }}\"'\n    },\n    'animation': {\n      scope: {model:true},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-animate=\"{{ animate }}\"'\n    },\n    'modifier': {\n      scope: {model:true},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-wrapper=\"{{ modifier }}\"'\n    },\n    'customValues': {\n      scope: {model:'something'},\n      element: 'ng-model=\"model\" type=\"checkbox\" ng-true-value=\"\\'yep\\'\" ng-false-value=\"\\'nope\\'\"'\n    },\n    'customObjectsValues': {\n      scope: {model:1},\n      element: 'ng-model=\"model\" type=\"checkbox\" ng-true-value=\"{{ 0 | json }}\" ng-false-value=\"{{ 1 | json }}\"'\n    },\n    'inverse': {\n      scope: {model:true},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-inverse=\"{{ inverse }}\"'\n    },\n    'getterSetter': {\n      scope: {},\n      element: 'ng-model=\"modelGetterSetter\" ng-model-options=\"{getterSetter: true}\" type=\"checkbox\"'\n    },\n    'change': {\n      scope: {},\n      element: 'ng-model=\"model\" type=\"checkbox\" switch-change=\"switchChange()\"'\n    },\n    'ngChange': {\n      scope: {},\n      element: 'ng-model=\"model\" type=\"checkbox\" ng-change=\"ngChange()\"'\n    }\n  };\n\n  var CONST = {\n    SWITCH_CLASS: 'bootstrap-switch',\n    SWITCH_WRAPPER_CLASS: 'bootstrap-switch-wrapper',\n    SWITCH_CONTAINER_CLASS: 'bootstrap-switch-container',\n    SWITCH_INVERSE_CLASS: 'bootstrap-switch-inverse',\n    SWITCH_INDETERMINATE_CLASS: 'bootstrap-switch-indeterminate',\n    SWITCH_ON_CLASS: 'bootstrap-switch-on',\n    SWITCH_OFF_CLASS: 'bootstrap-switch-off',\n    SWITCH_DISABLED_CLASS: 'bootstrap-switch-disabled',\n    SWITCH_READONLY_CLASS: 'bootstrap-switch-readonly',\n    SWITCH_MINI_CLASS: 'bootstrap-switch-mini',\n    SWITCH_INFO_CLASS: 'bootstrap-switch-info',\n    SWITCH_WARNING_CLASS: 'bootstrap-switch-warning',\n    SWITCH_SUCCESS_CLASS: 'bootstrap-switch-success',\n    SWITCH_ERROR_CLASS: 'bootstrap-switch-error',\n    SWITCH_ANIMATED_CLASS: 'bootstrap-switch-animate',\n    SWITCH_LEFT_SELECTOR: '.bootstrap-switch-handle-on',\n    SWITCH_RIGHT_SELECTOR: '.bootstrap-switch-handle-off',\n    LABEL_SELECTOR: '.bootstrap-switch-label',\n    INPUT_SELECTOR: 'input',\n    ICON_SELECTOR: '.bootstrap-switch-label span',\n    DEFAULT_TRUE_TEXT: 'ON',\n    DEFAULT_FALSE_TEXT: 'OFF'\n  };\n\n  /**\n   * Build an element string.\n   * @param template The template element to be used\n   * @param input true if the element must be an `input` tag, anything falsy for `bs-switch`\n   * @returns {string} The HTML element as a string\n   */\n  function buildElement(template, input) {\n    var elementContent = template.element;\n    var realElement;\n    if (angular.isArray(elementContent)) {\n      realElement = '<div>';\n      for (var c in elementContent) {\n        realElement += buildSingleElement(elementContent[c], input);\n      }\n      realElement += '</div>';\n      return realElement;\n    }\n    return buildSingleElement(elementContent, input);\n  }\n\n  function buildSingleElement(content, isInput) {\n    var singleElement = (isInput ? '<input ' : '<') + 'bs-switch ' + content + '>';\n    if (!isInput) {\n      singleElement += '</bs-switch>';\n    }\n    return singleElement;\n  }\n\n  /**\n   * Compile a given template object as an `input` or a `bs-switch`.\n   * @param template The template object\n   * @param input true if the element must be an `input` tag, anything falsy for `bs-switch`\n   * @returns {*} compiled angular element\n   */\n  function compileDirective(template, input) {\n    template = template ? templates[template] : templates['default'];\n    angular.extend(scope, template.scope || templates['default'].scope);\n    var content = buildElement(template, input);\n    var $element = angular.element(content).appendTo($sandbox);\n    $compile($element)(scope);\n    scope.$apply();\n    $element = $sandbox.find('> *:first-child');\n    return $element;\n  }\n\n  // Test the widget creation and defaults\n  function makeTestCreateSwitch(input) {\n    return function() {\n      var element = compileDirective(undefined, input);\n      expect(element).not.toBe(undefined);\n      expect(element.hasClass(CONST.SWITCH_CLASS)).toBe(true);\n      expect(element.find(CONST.SWITCH_LEFT_SELECTOR).html()).toBe(CONST.DEFAULT_TRUE_TEXT);\n      expect(element.find(CONST.SWITCH_RIGHT_SELECTOR).html()).toBe(CONST.DEFAULT_FALSE_TEXT);\n      expect(element.find(CONST.LABEL_SELECTOR).html()).toBe('&nbsp;');\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_DISABLED_CLASS)).toBeFalsy();\n      expect(element.find(CONST.INPUT_SELECTOR).attr('disabled')).toBeFalsy();\n    };\n  }\n  it('should create a switch', inject(makeTestCreateSwitch()));\n  it('should create a switch (input)', inject(makeTestCreateSwitch(true)));\n\n  // Test the switch type\n  function makeTestRadio(input) {\n    return function () {\n      var element = compileDirective('radio', input);\n      expect(element.find(CONST.INPUT_SELECTOR).attr('type')).toBe('radio');\n    };\n  }\n  it('should create a radio switch', inject(makeTestRadio()));\n  it('should create a radio switch (input)', inject(makeTestRadio(true)));\n\n  // Test the change of a radio switch from true to false\n  function makeTestRadioOffFalse(input) {\n    return function () {\n      var element = compileDirective('radioOff', input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = false;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should not change a radio from true to false', inject(makeTestRadioOffFalse()));\n  it('should not change a radio from true to false (input)', inject(makeTestRadioOffFalse(true)));\n\n  // Test the change of a radio switch from true to false\n  function makeTestRadioOffTrue(input) {\n    return function () {\n      var element = compileDirective('radioOff', input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.radioOff = true;\n      scope.$apply();\n      scope.model = false;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n    };\n  }\n  it('should change a radio from true to false', inject(makeTestRadioOffTrue()));\n  it('should change a radio from true to false (input)', inject(makeTestRadioOffTrue(true)));\n\n\n  function expectNothing(el1, el2, el3) {\n    expect(el1.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n    expect(el1.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n    expect(el2.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n    expect(el2.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n    expect(el3.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n    expect(el3.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n  }\n\n  function makeTestMultipleRadios(input) {\n    return function () {\n      var element = compileDirective('multipleRadios', input);\n      var elements = element.find('.bootstrap-switch');\n      var el1 = angular.element(elements[0]);\n      var el2 = angular.element(elements[1]);\n      var el3 = angular.element(elements[2]);\n      expectNothing(el1, el2, el3);\n      scope.model = 'wat';\n      scope.$apply();\n      expectNothing(el1, el2, el3);\n      scope.model = 'dos';\n      scope.$apply();\n      expect(el2.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(el2.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      expect(scope.model).toEqual('dos');\n      expect(el1.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(el1.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n      expect(el3.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(el3.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n    };\n  }\n  it('should set the proper model with multiple radios', inject(makeTestMultipleRadios()));\n  it('should set the proper model with multiple radios (input)', inject(makeTestMultipleRadios(true)));\n\n  function makeTestMultipleRadiosOff(input) {\n    return function () {\n      var element = compileDirective('multipleRadios', input);\n      var elements = element.find('.bootstrap-switch');\n      expect(scope.model).toEqual('');\n      var el1 = angular.element(elements[0]);\n      var el2 = angular.element(elements[1]);\n      var el3 = angular.element(elements[2]);\n      expectNothing(el1, el2, el3);\n      jQuery(el3).find('input').bootstrapSwitch('toggleState');\n      scope.$apply();\n      expect(scope.model).toEqual('tres');\n      jQuery(el3).find('input').bootstrapSwitch('toggleState');\n      scope.$apply();\n      expect(scope.model).toEqual(undefined);\n      expectNothing(el1, el2, el3);\n    };\n  }\n  it('should set the proper model to undefined when a radio is turned off', inject(makeTestMultipleRadiosOff()));\n  it('should set the proper model to undefined when a radio is turned off (input)', inject(makeTestMultipleRadiosOff(true)));\n\n  // Test the model change\n  function makeTestChangeModel(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = false;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n    };\n  }\n  it('should move the switch when the model changes', inject(makeTestChangeModel()));\n  it('should move the switch when the model changes (input)', inject(makeTestChangeModel(true)));\n\n  // Test the undefined model (the on/off class is untouched when the indeterminate class is added)\n  function makeTestIndeterminateUndefinedModel(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = undefined;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should set the indeterminate state when the model is undefined', inject(makeTestIndeterminateUndefinedModel()));\n  it('should set the indeterminate state when the model is undefined (input)', inject(makeTestIndeterminateUndefinedModel(true)));\n\n  // Test the null model (the on/off class is untouched when the indeterminate class is added)\n  function makeTestIndeterminateNullModel(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = null;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should set the indeterminate state when the model is null', inject(makeTestIndeterminateNullModel()));\n  it('should set the indeterminate state when the model is null (input)', inject(makeTestIndeterminateNullModel(true)));\n\n  // Test the view change\n  function makeTestChangeView(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(scope.model).toBeTruthy();\n      element.find('input').bootstrapSwitch('toggleState');\n      scope.$apply();\n      expect(scope.model).toBeFalsy();\n      element.find('input').bootstrapSwitch('toggleState');\n      scope.$apply();\n      expect(scope.model).toBeTruthy();\n    };\n  }\n  it('should change the model when the switch is clicked', inject(makeTestChangeView()));\n  it('should change the model when the switch is clicked (input)', inject(makeTestChangeView(true)));\n\n  // Test the deactivation\n  function makeTestDeactivate(input) {\n    return function () {\n      var element = compileDirective('active', input);\n      expect(element.hasClass(CONST.SWITCH_DISABLED_CLASS)).toBeFalsy();\n      expect(element.find(CONST.INPUT_SELECTOR).attr('disabled')).toBeFalsy();\n      scope.isActive = false;\n      scope.$apply();\n      $timeout.flush();\n      expect(element.hasClass(CONST.SWITCH_DISABLED_CLASS)).toBeTruthy();\n      expect(element.find(CONST.INPUT_SELECTOR).attr('disabled')).toBeTruthy();\n    };\n  }\n  it('should deactivate the switch', inject(makeTestDeactivate()));\n  it('should deactivate the switch (input)', inject(makeTestDeactivate(true)));\n\n  // Test a model change followed by a deactivation\n  function makeTestChangeModelThenDeactivate(input) {\n    return function () {\n      var element = compileDirective('active', input);\n      // test the active state, should be true\n      expect(element.hasClass(CONST.SWITCH_DISABLED_CLASS)).toBeFalsy();\n      expect(element.find(CONST.INPUT_SELECTOR).attr('disabled')).toBeFalsy();\n      // test the model, should be false\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = false;\n      scope.isActive = false;\n      scope.$apply();\n      $timeout.flush();\n      // test the active state, should be false\n      expect(element.hasClass(CONST.SWITCH_DISABLED_CLASS)).toBeTruthy();\n      expect(element.find(CONST.INPUT_SELECTOR).attr('disabled')).toBeTruthy();\n      // test the model, should be false\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n    };\n  }\n  it('should change the model, then deactivate the switch', inject(makeTestChangeModelThenDeactivate()));\n  it('should change the model, deactivate the switch (input)', inject(makeTestChangeModelThenDeactivate(true)));\n\n  // Test a model change when switch is deactivated\n  function makeTestChangeModelWhenSwitchIsDeactivated() {\n    return function () {\n      var element = compileDirective('active');\n      scope.model = false;\n      scope.isActive = false;\n      scope.$apply();\n      $timeout.flush();\n      // test the active state, should be false\n      expect(element.hasClass(CONST.SWITCH_DISABLED_CLASS)).toBeTruthy();\n      expect(element.find(CONST.INPUT_SELECTOR).attr('disabled')).toBeTruthy();\n      // test the model, should be false\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n\n      scope.model = true;\n      scope.$apply();\n\n      // test the active state, should be false\n      expect(element.hasClass(CONST.SWITCH_DISABLED_CLASS)).toBeTruthy();\n      expect(element.find(CONST.INPUT_SELECTOR).attr('disabled')).toBeTruthy();\n      // test the model, should be true\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should deactivate the switch, then change the model', inject(makeTestChangeModelWhenSwitchIsDeactivated()));\n\n  // Test the activation\n  function makeTestActivate(input) {\n    return function () {\n      var element = compileDirective('unactivated', input);\n      // need to flush since the element starts as deactivated\n      $timeout.flush();\n      expect(element.hasClass(CONST.SWITCH_DISABLED_CLASS)).toBeTruthy();\n      scope.isActive = true;\n      scope.$apply();\n      // no need to flush here since we are activating the switch\n      expect(element.hasClass(CONST.SWITCH_DISABLED_CLASS)).toBeFalsy();\n    };\n  }\n  it('should activate the switch', inject(makeTestActivate()));\n  it('should activate the switch (input)', inject(makeTestActivate(true)));\n\n  // Test the readonly\n  function makeTestReadonly(input) {\n    return function () {\n      var element = compileDirective('readonly', input);\n      expect(element.hasClass(CONST.SWITCH_READONLY_CLASS)).toBeFalsy();\n      expect(element.find(CONST.INPUT_SELECTOR).attr('readonly')).toBeFalsy();\n      scope.isReadonly = true;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_READONLY_CLASS)).toBeTruthy();\n      expect(element.find(CONST.INPUT_SELECTOR).attr('readonly')).toBeTruthy();\n    };\n  }\n  it('should set the switch as read only', inject(makeTestReadonly()));\n  it('should set the switch as read only (input)', inject(makeTestReadonly(true)));\n\n  // Test the size change\n  function makeTestChangeSize(input) {\n    return function () {\n      var element = compileDirective('size', input);\n      expect(element.hasClass(CONST.SWITCH_MINI_CLASS)).toBeFalsy();\n      scope.size = 'mini';\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_MINI_CLASS)).toBeTruthy();\n    };\n  }\n  it('should change the switch size', inject(makeTestChangeSize()));\n  it('should change the switch size (input)', inject(makeTestChangeSize(true)));\n\n  // Test the label width change\n  function makeTestChangeLabelWidth(input) {\n    return function () {\n      var element = compileDirective('size', input);\n      scope.labelWidth = '600';\n      scope.$apply();\n      expect(element.find(CONST.INPUT_SELECTOR).bootstrapSwitch('labelWidth')).toEqual('600');\n    };\n  }\n  it('should change the label width', inject(makeTestChangeLabelWidth()));\n  it('should change the label width (input)', inject(makeTestChangeLabelWidth(true)));\n\n  // Test the handle width change\n  function makeTestChangeHandleWidth(input) {\n    return function () {\n      var element = compileDirective('size', input);\n      scope.handleWidth = '600';\n      scope.$apply();\n      expect(element.find(CONST.INPUT_SELECTOR).bootstrapSwitch('handleWidth')).toEqual('600');\n    };\n  }\n  it('should change the handle width', inject(makeTestChangeHandleWidth()));\n  it('should change the handle width (input)', inject(makeTestChangeHandleWidth(true)));\n\n  // Test the \"on\" and \"off\" color change\n  function makeTestChangeColor(input) {\n    return function () {\n      var element = compileDirective('color', input);\n      expect(element.find(CONST.SWITCH_LEFT_SELECTOR).hasClass(CONST.SWITCH_INFO_CLASS)).toBeTruthy();\n      expect(element.find(CONST.SWITCH_RIGHT_SELECTOR).hasClass(CONST.SWITCH_WARNING_CLASS)).toBeTruthy();\n      scope.on = 'success';\n      scope.off = 'error';\n      scope.$apply();\n      expect(element.find(CONST.SWITCH_LEFT_SELECTOR).hasClass(CONST.SWITCH_SUCCESS_CLASS)).toBeTruthy();\n      expect(element.find(CONST.SWITCH_RIGHT_SELECTOR).hasClass(CONST.SWITCH_ERROR_CLASS)).toBeTruthy();\n    };\n  }\n  it('should change the switch colors', inject(makeTestChangeColor()));\n  it('should change the switch colors (input)', inject(makeTestChangeColor(true)));\n\n  // Test the \"on\" and \"off\" label change\n  function makeTestChangeLabel(input) {\n    return function () {\n      var element = compileDirective('label', input);\n      expect(element.find(CONST.SWITCH_LEFT_SELECTOR).html()).toBe(CONST.DEFAULT_TRUE_TEXT);\n      expect(element.find(CONST.SWITCH_RIGHT_SELECTOR).html()).toBe(CONST.DEFAULT_FALSE_TEXT);\n      scope.on = 'Yay';\n      scope.off = 'Nay';\n      scope.$apply();\n      expect(element.find(CONST.SWITCH_LEFT_SELECTOR).html()).toBe('Yay');\n      expect(element.find(CONST.SWITCH_RIGHT_SELECTOR).html()).toBe('Nay');\n    };\n  }\n  it('should change the switch labels', inject(makeTestChangeLabel()));\n  it('should change the switch labels (input)', inject(makeTestChangeLabel(true)));\n\n  // Test the middle label change\n  function makeTestChangeMiddleLabel(input) {\n    return function () {\n      var element = compileDirective('label', input);\n      expect(element.find(CONST.LABEL_SELECTOR).html()).toBe('&nbsp;');\n      scope.label = 'XYZ';\n      scope.$apply();\n      expect(element.find(CONST.LABEL_SELECTOR).html()).toBe('XYZ');\n    };\n  }\n  it('should change the switch middle label', inject(makeTestChangeMiddleLabel()));\n  it('should change the switch middle label (input)', inject(makeTestChangeMiddleLabel(true)));\n\n  // Test the middle icon change\n  function makeTestChangeMiddleIcon(input) {\n    return function () {\n      var element = compileDirective('icon', input);\n      expect(element.find(CONST.ICON_SELECTOR).hasClass('icon-youtube')).toBeTruthy();\n      scope.icon = 'icon-fullscreen';\n      scope.$apply();\n      expect(element.find(CONST.ICON_SELECTOR).hasClass('icon-youtube')).toBeFalsy();\n      expect(element.find(CONST.ICON_SELECTOR).hasClass('icon-fullscreen')).toBe(true);\n    };\n  }\n  it('should change the switch middle icon', inject(makeTestChangeMiddleIcon()));\n  it('should change the switch middle icon (input)', inject(makeTestChangeMiddleIcon(true)));\n\n  // Test the animation deactivation and reactivation\n  function makeTestAnimation(input) {\n    return function () {\n      jasmine.clock().install();\n      var element = compileDirective('animation', input);\n      jasmine.clock().tick(50);\n      expect(element.hasClass(CONST.SWITCH_ANIMATED_CLASS)).toBeTruthy();\n      scope.animate = false;\n      scope.$apply();\n      jasmine.clock().tick(50);\n      expect(element.hasClass(CONST.SWITCH_ANIMATED_CLASS)).toBeFalsy();\n      scope.animate = true;\n      scope.$apply();\n      jasmine.clock().tick(50);\n      expect(element.hasClass(CONST.SWITCH_ANIMATED_CLASS)).toBeTruthy();\n      jasmine.clock().uninstall();\n    };\n  }\n  it('should change the switch animation mode', inject(makeTestAnimation()));\n  it('should change the switch animation mode (input)', inject(makeTestAnimation(true)));\n\n  // Test the custom class modifiers\n  function makeTestClassModifiers(input) {\n    return function () {\n      var element = compileDirective('modifier', input);\n      expect(element.hasClass(CONST.SWITCH_WRAPPER_CLASS)).toBeTruthy();\n      scope.modifier = 'flat-switch';\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_WRAPPER_CLASS)).toBeFalsy();\n      expect(element.hasClass('bootstrap-switch-flat-switch')).toBeTruthy();\n      scope.modifier = '';\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_WRAPPER_CLASS)).toBeTruthy();\n      scope.modifier = undefined;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_WRAPPER_CLASS)).toBeTruthy();\n    };\n  }\n  it('should change the custom wrapper class', inject(makeTestClassModifiers()));\n  it('should change the custom wrapper class (input)', inject(makeTestClassModifiers(true)));\n\n  // Test the non-replacement if already an input element given\n  // to ensure IE8 compatibility\n  function makeTestReplacement(useInputElement) {\n    return function () {\n      var beforeCompile,\n          afterCompile,\n          content,\n          template = templates['default'];\n\n      angular.extend(scope, template.scope);\n      content = buildElement(template, useInputElement);\n      beforeCompile = angular.element(content).appendTo($sandbox);\n\n      $compile(beforeCompile)(scope);\n      afterCompile = $sandbox.find('input');\n      scope.$apply();\n\n      expect(beforeCompile.length).toBe(1);\n      expect(afterCompile.length).toBe(1);\n      expect(beforeCompile[0] === afterCompile[0]).toBe(true);\n    };\n  }\n  it('should replace non-input elements', inject(makeTestReplacement()));\n  it('should not replace input elements', inject(makeTestReplacement(true)));\n\n  // Test the custom true/false values\n  function makeTestCustomValues(input) {\n    return function () {\n      var element = compileDirective('customValues', input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n      scope.model = 'yep';\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should use \"yep\" and \"nope\" instead of true and false', inject(makeTestCustomValues()));\n  it('should use \"yep\" and \"nope\" instead of true and false (input)', inject(makeTestCustomValues(true)));\n\n  // Test the custom true/false values as generic objects\n  function makeTestCustomObjectsValues(input) {\n    return function () {\n      var element = compileDirective('customObjectsValues', input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n      scope.model = 0;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should use 0 and 1 instead of true and false', inject(makeTestCustomObjectsValues()));\n  it('should use 0 and 1 instead of true and false (input)', inject(makeTestCustomObjectsValues(true)));\n\n  // Test the inverse default option\n  function makeTestInverseUndefined(input) {\n    return function () {\n      var element = compileDirective('inverse', input);\n      expect(element.hasClass(CONST.SWITCH_INVERSE_CLASS)).toBeFalsy();\n      var children = element.find('.' + CONST.SWITCH_CONTAINER_CLASS).find('*[class^=\\'bootstrap-switch-handle-\\']');\n      expect(children.length).toBe(2);\n      expect(angular.element(children[0]).hasClass(CONST.SWITCH_LEFT_SELECTOR.substr(1))).toBeTruthy();\n      expect(angular.element(children[1]).hasClass(CONST.SWITCH_RIGHT_SELECTOR.substr(1))).toBeTruthy();\n    };\n  }\n  it('should default to inverse false when not defined', inject(makeTestInverseUndefined()));\n  it('should default to inverse false when not defined (input)', inject(makeTestInverseUndefined(true)));\n\n  // Test the inverse option\n  function makeTestInverse(input) {\n    return function () {\n      var element = compileDirective('inverse', input);\n      expect(element.hasClass(CONST.SWITCH_INVERSE_CLASS)).toBeFalsy();\n      // invert\n      scope.inverse = true;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INVERSE_CLASS)).toBeTruthy();\n      var children = element.find('.' + CONST.SWITCH_CONTAINER_CLASS).find('*[class^=\\'bootstrap-switch-handle-\\']');\n      expect(children.length).toBe(2);\n      expect(angular.element(children[1]).hasClass(CONST.SWITCH_LEFT_SELECTOR.substr(1))).toBeTruthy();\n      expect(angular.element(children[0]).hasClass(CONST.SWITCH_RIGHT_SELECTOR.substr(1))).toBeTruthy();\n      // reset\n      scope.inverse = false;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INVERSE_CLASS)).toBeFalsy();\n      children = element.find('.' + CONST.SWITCH_CONTAINER_CLASS).find('*[class^=\\'bootstrap-switch-handle-\\']');\n      expect(children.length).toBe(2);\n      expect(angular.element(children[0]).hasClass(CONST.SWITCH_LEFT_SELECTOR.substr(1))).toBeTruthy();\n      expect(angular.element(children[1]).hasClass(CONST.SWITCH_RIGHT_SELECTOR.substr(1))).toBeTruthy();\n    };\n  }\n  it('should invert the on and off switches and then reset them', inject(makeTestInverse()));\n  it('should invert the on and off switches and then reset them (input)', inject(makeTestInverse(true)));\n\n  // Test the getterSetter ng-model option\n  function makeTestGetterSetter(input) {\n    return function () {\n      var element = compileDirective('getterSetter', input);\n      var localValue = false;\n\n      scope.modelGetterSetter = function() {\n        return localValue;\n      };\n      scope.$apply();\n\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n\n      localValue = true;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should watch updates in getterSetter', inject(makeTestGetterSetter()));\n  it('should watch updates in getterSetter', inject(makeTestGetterSetter(true)));\n\n  function makeTestViewNgChange(input) {\n    return function () {\n      var element = compileDirective('ngChange', input);\n      scope.ngChange = jasmine.createSpy();\n\n      // On - model change\n      scope.model = true;\n      scope.$apply();\n      expect(scope.ngChange).not.toHaveBeenCalled();\n\n      // Indeterminate - model change\n      scope.model = undefined;\n      scope.$apply();\n      expect(scope.ngChange).not.toHaveBeenCalled();\n\n      // Off - view change\n      element.find('input').click();\n      expect(scope.ngChange).toHaveBeenCalled();\n      scope.ngChange.calls.reset();\n\n      // On - view change\n      element.find('input').click();\n      expect(scope.ngChange).toHaveBeenCalled();\n    };\n  }\n  it('should evaluate ngChange expression only when view changes', inject(makeTestViewNgChange()));\n  it('should evaluate ngChange expression only when view changes', inject(makeTestViewNgChange(true)));\n\n  function makeTestModelSwitchChange(input) {\n    return function () {\n      var element = compileDirective('change', input);\n      scope.switchChange = jasmine.createSpy();\n\n      // On - model change\n      scope.model = true;\n      scope.$apply();\n      expect(scope.switchChange).toHaveBeenCalled();\n      scope.switchChange.calls.reset();\n\n      // Off - view change\n      element.find('input').click();\n      expect(scope.switchChange).toHaveBeenCalled();\n    };\n  }\n  it('should evaluate change expression when model changes', inject(makeTestModelSwitchChange()));\n  it('should evaluate change expression when model changes', inject(makeTestModelSwitchChange(true)));\n\n  // Test the null model from true state\n  function makeTestToIndeterminateNullFromTrue(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = true;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      scope.model = null;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should change from true to the indeterminate state when the model is null', inject(makeTestToIndeterminateNullFromTrue()));\n  it('should change from true to the indeterminate state when the model is null (input)', inject(makeTestToIndeterminateNullFromTrue(true)));\n\n  // Test the null model from false state\n  function makeTestToIndeterminateNullFromFalse(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = false;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      scope.model = null;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n    };\n  }\n  it('should change from false to the indeterminate state when the model is null', inject(makeTestToIndeterminateNullFromFalse()));\n  it('should change from false to the indeterminate state when the model is null (input)', inject(makeTestToIndeterminateNullFromFalse(true)));\n\n  // Test the undefined model from true state\n  function makeTestToIndeterminateUndefinedFromTrue(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = true;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      scope.model = undefined;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should change from true to the indeterminate state when the model is null', inject(makeTestToIndeterminateUndefinedFromTrue()));\n  it('should change from true to the indeterminate state when the model is null (input)', inject(makeTestToIndeterminateUndefinedFromTrue(true)));\n\n  // Test the undefined model from false state\n  function makeTestToIndeterminateUndefinedFromFalse(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = false;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      scope.model = undefined;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n    };\n  }\n  it('should change from false to the indeterminate state when the model is null', inject(makeTestToIndeterminateUndefinedFromFalse()));\n  it('should change from false to the indeterminate state when the model is null (input)', inject(makeTestToIndeterminateUndefinedFromFalse(true)));\n\n  // Test the changing multiple state\n  function makeTestMultipleChangeOfStateIndeterminate(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = false;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      scope.model = undefined;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n      scope.model = true;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n    };\n  }\n  it('should change from false to the indeterminate state and to true', inject(makeTestMultipleChangeOfStateIndeterminate()));\n  it('should change from false to the indeterminate state and to true (input)', inject(makeTestMultipleChangeOfStateIndeterminate(true)));\n\n  // Test the changing multiple state other way round\n  function makeTestMultipleChangeOfStateIndeterminateReverse(input) {\n    return function () {\n      var element = compileDirective(undefined, input);\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = true;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = undefined;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeTruthy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeTruthy();\n      scope.model = false;\n      scope.$apply();\n      expect(element.hasClass(CONST.SWITCH_INDETERMINATE_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_ON_CLASS)).toBeFalsy();\n      expect(element.hasClass(CONST.SWITCH_OFF_CLASS)).toBeTruthy();\n    };\n  }\n  it('should change from false to the indeterminate state and to false', inject(makeTestMultipleChangeOfStateIndeterminateReverse()));\n  it('should change from false to the indeterminate state and to false (input)', inject(makeTestMultipleChangeOfStateIndeterminateReverse(true)));\n});\n"
  }
]