[
  {
    "path": ".gitignore",
    "content": "bower_components/\nnode_modules/\n"
  },
  {
    "path": ".npmignore",
    "content": "gulpfile.js\nsrc\ntest\n.gitignore\n.travis.yml"
  },
  {
    "path": ".travis.yml",
    "content": "sudo: false\nlanguage: node_js\ncache:\n  directories:\n    - node_modules\nnotifications:\n  email: false\nnode_js:\n  - '6'\nbefore_install:\n  - npm i -g npm@^3.10.7\nbefore_script:\n  - npm prune\nscript:\n  - npm run test\nbranches:\n  except:\n    - \"/^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$/\""
  },
  {
    "path": "ISSUE_TEMPLATE.md",
    "content": "> If you are going to be lazy asking me properly, I'll be lazy answering to you (@leocaseiro)\n\n### Please make sure you can mark all the options, before open this Issue. I'll prioritise the issues that are consistent and completed. \n\n\n- [ ] I've read the documentation on http://leocaseiro.github.io/angular-chosen.\n- [ ] I've searched on [github issues](https://github.com/leocaseiro/angular-chosen/issues?utf8=%E2%9C%93&q=is%3Aissue) and [stackoverflow](http://stackoverflow.com/questions/tagged/angular-chosen) before open this issue.\n- [ ] I've tested with the [angular native select input](https://docs.angularjs.org/api/ng/directive/select) without the chosen directive\n- [ ] I've tested with the oficial [jquery chosen](https://harvesthq.github.io/chosen/) without the angular chosen directive\n\n## Please, post your plunker link here:\n> (plunker link goes here)\n\n\nIf you need a starter plunker for a single select, use this one: https://plnkr.co/edit/Ec9l1C?p=preview\n\nIf you need a starter for a multiple select, use this one: https://plnkr.co/edit/vaRw1x?p=preview\n\n## Write your issue:\n\n\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License\n\nCopyright (c) 2013 Localytics http://www.localytics.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "Angular Chosen Localytics [![Bower](https://img.shields.io/bower/v/angular-chosen-localytics.svg)](https://github.com/leocaseiro/angular-chosen) [![npm](https://img.shields.io/npm/v/angular-chosen-localytics.svg)](https://www.npmjs.com/package/angular-chosen-localytics)\n==============\n\nAngularJS Chosen directive\n\nThis directive brings the [Chosen](http://harvesthq.github.com/chosen/) jQuery plugin\ninto AngularJS with ngModel and ngOptions integration.\n\nTo use, include `localytics.directives` as a dependency in your Angular module.  You can now\nuse the `chosen` directive as an attribute on any select element.  Angular version 1.3+ is required, but recommended 1.4.9+.\n\n# [Full Documentation with Examples](http://leocaseiro.github.io/angular-chosen/)\n* Documentation on [Github Page](http://leocaseiro.github.io/angular-chosen/)\n* Examples on [example/index.html](http://htmlpreview.github.io/?https://github.com/leocaseiro/angular-chosen/blob/master/example/index.html)\n\n\n\n## Installation (npm or bower)\n\nVia bower\n\n    $ bower install angular-chosen-localytics --save\n\nVia npm\n\n    $ npm install angular-chosen-localytics --save\n\n\nVia [cdn](https://cdnjs.com/libraries/angular-chosen-localytics)\n```html\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/angular-chosen-localytics/1.9.2/angular-chosen.min.js\"></script>\n```\n\n\n\nOr download zip file\n> [Download v1.9.2](https://github.com/leocaseiro/angular-chosen/archive/1.9.2.zip)\n\n\n\n\n## Yeoman or Bower install\nIf you use Yeoman or Bower install, you need to rename the `chosen.jquery.js` or the `chosen.proto.js` to `chosen.js`. Otherwise Chosen won't be included in your `index.html`.\n\n# Features\n  * Works with `ngModel` and `ngOptions`\n  * Supports usage of promises in `ngOptions`\n  * Provides a 'loading' animation when 'ngOptions' collection is a promise backed by a remote source\n  * Pass options to `Chosen` via attributes or by passing an object to the Chosen directive\n  * Provider with default values with `chosenProvider` ([read: Added config-provider](https://github.com/leocaseiro/angular-chosen/pull/231)) [since 1.6.0]\n\n# Usage\n\n### Simple example\nSimilar to `$(\"#states\").chosen()`\n\n```html\n<select chosen multiple id=\"states\">\n  <option value=\"AK\">Alaska</option>\n  <option value=\"AZ\">Arizona</option>\n  <option value=\"AR\">Arkansas</option>\n  <option value=\"CA\">California</option>\n</select>\n```\n\n### Pass any chosen options as attributes\n\n```html\n<select chosen\n        data-placeholder-text-single=\"'Pick one of these'\"\n        disable-search=\"true\"\n        allow-single-deselect=\"true\">\n  <option value=\"\"></option>\n  <option>This is fun</option>\n  <option>I like Chosen so much</option>\n  <option>I also like bunny rabbits</option>\n</select>\n```\n> Note: the empty option element is mandatory when using `allow-single-deselect`\n\n### Integration with `ngModel` and `ngOptions`\n\n```html\n<select multiple\n        chosen\n        ng-model=\"state\"\n        ng-options=\"s for s in states\">\n</select>\n```\n\n> Note: don't try to use `ngModel` with `ngRepeat`.  It won't work.  Use `ngOptions`.  It's better that way.\n\n> Also important: if your `ngModel` is null or undefined, you must manually include an empty option inside your `<select>`, otherwise you'll encounter strange off-by-one errors:\n\n```html\n<select multiple\n        chosen\n        ng-model=\"state\"\n        ng-options=\"s for s in states\">\n  <option value=\"\"></option>\n</select>\n```\n\n> This annoying behavior is alluded to in the examples in the [documentation for ngOptions](http://docs.angularjs.org/api/ng.directive:select).\n\n#### Works well with other AngularJS directives\n\n```html\n<select chosen\n        ng-model=\"state\"\n        ng-options=\"s for s in states\"\n        ng-disabled=\"editable\">\n  <option value=\"\"></option>\n</select>\n```\n\n### Loading from a remote data source\nInclude `chosen-spinner.css` and `spinner.gif` to show an Ajax spinner icon while your data is loading.  If the collection comes back empty, the directive will disable the element and show a default\n\"No values available\" message.  You can customize this message by passing in `noResultsText` in your options.\n\n##### app.js\n```js\nangular.module('App', ['ngResource', 'localytics.directives'])\n    .controller('BeerCtrl', function($scope, $resource) {\n      $scope.beers = $resource('api/beers').query()\n    });\n```\n\n##### index.html\n```html\n<div ng-controller=\"BeerCtrl\">\n  <select chosen\n          data-placeholder-text-single=\"'Choose a beer'\"\n          no-results-text=\"'Could not find any beers :('\"\n          ng-model=\"beer\"\n          ng-options=\"b for b in beers\">\n      <option value=\"\"></option>\n  </select>\n</div>\n```\n\nImage of select defined above in loading state:\n`<img src=\"https://raw.github.com/localytics/angular-chosen/master/example/choose-a-beer.png\">`\n\n> Note: Assigning promises directly to scope is now deprecated in Angular 1.2+.  Assign the results of the promise to scope\nonce the promise returns.  The loader animation will still work as long as the collection expression\nevaluates to `undefined` while your data is loading!\n\n\n### Default values with chosenProvider (thanks @zlodes) [since 1.6.0]\n```javascript\nangular.module('chosenExampleApp', ['localytics.directives'])\n    .config(['chosenProvider', function (chosenProvider) {\n        chosenProvider.setOption({\n            no_results_text: 'There is no results!',\n            placeholder_text_multiple: 'Choose one or more!'\n        });\n    }]);\n```\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"angular-chosen-localytics\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/leocaseiro/angular-chosen.git\"\n  },\n  \"main\": \"dist/angular-chosen.js\",\n  \"ignore\": [\n    \"gulpfile.js\",\n    \"src\",\n    \"test\"\n  ],\n  \"dependencies\": {\n    \"jquery\": \"^2.0.3\",\n    \"chosen\": \"^1.5.1\",\n    \"angular\": \"^1.4.9\"\n  },\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "chosen-spinner.css",
    "content": "/* Additional styles to display a spinner image while options are loading */\n.localytics-chosen.loading+.chosen-container-multi .chosen-choices {\n  background-image: url('spinner.gif');\n  background-repeat: no-repeat;\n  background-position: 95%;\n}\n.localytics-chosen.loading+.chosen-container-single .chosen-single span {\n  background: url('spinner.gif') no-repeat right;\n}\n.localytics-chosen.loading+.chosen-container-single .chosen-single .search-choice-close {\n  display: none;\n}"
  },
  {
    "path": "chosen.js",
    "content": "console.warn('the file ./chosen.js is deprecated, you must include ./dist/angular-chosen.js or ./dist/angular-chosen.min.js instead');\n"
  },
  {
    "path": "dist/angular-chosen.js",
    "content": "/**\n * angular-chosen-localytics - Angular Chosen directive is an AngularJS Directive that brings the Chosen jQuery in a Angular way\n * @version v1.9.2\n * @link http://github.com/leocaseiro/angular-chosen\n * @license MIT\n */\n(function() {\n  var chosenModule,\n    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };\n\n  angular.module('localytics.directives', []);\n\n  chosenModule = angular.module('localytics.directives');\n\n  chosenModule.provider('chosen', function() {\n    var options;\n    options = {};\n    return {\n      setOption: function(newOpts) {\n        angular.extend(options, newOpts);\n      },\n      $get: function() {\n        return options;\n      }\n    };\n  });\n\n  chosenModule.directive('chosen', [\n    'chosen', '$timeout', '$parse', function(config, $timeout, $parse) {\n      var CHOSEN_OPTION_WHITELIST, NG_OPTIONS_REGEXP, isEmpty, snakeCase;\n      NG_OPTIONS_REGEXP = /^\\s*([\\s\\S]+?)(?:\\s+as\\s+([\\s\\S]+?))?(?:\\s+group\\s+by\\s+([\\s\\S]+?))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+([\\s\\S]+?)(?:\\s+track\\s+by\\s+([\\s\\S]+?))?$/;\n      CHOSEN_OPTION_WHITELIST = ['allowSingleDeselect', 'disableSearch', 'disableSearchThreshold', 'enableSplitWordSearch', 'inheritSelectClasses', 'maxSelectedOptions', 'noResultsText', 'placeholderTextMultiple', 'placeholderTextSingle', 'searchContains', 'groupSearch', 'singleBackstrokeDelete', 'width', 'displayDisabledOptions', 'displaySelectedOptions', 'includeGroupLabelInSelected', 'maxShownResults', 'caseSensitiveSearch', 'hideResultsOnSelect', 'rtl'];\n      snakeCase = function(input) {\n        return input.replace(/[A-Z]/g, function($1) {\n          return \"_\" + ($1.toLowerCase());\n        });\n      };\n      isEmpty = function(value) {\n        var key;\n        if (angular.isArray(value)) {\n          return value.length === 0;\n        } else if (angular.isObject(value)) {\n          for (key in value) {\n            if (value.hasOwnProperty(key)) {\n              return false;\n            }\n          }\n        }\n        return true;\n      };\n      return {\n        restrict: 'A',\n        require: ['select', '?ngModel'],\n        priority: 1,\n        link: function(scope, element, attr, ctrls) {\n          var $render, chosen, directiveOptions, disableIfEmpty, empty, initIfNotInitialized, match, ngModel, ngSelect, options, startLoading, stopLoading, timer, trackBy, valuesExpr, viewWatch;\n          scope.disabledValuesHistory = scope.disabledValuesHistory ? scope.disabledValuesHistory : [];\n          element = $(element);\n          element.addClass('localytics-chosen');\n          ngSelect = ctrls[0];\n          ngModel = ctrls[1];\n          match = attr.ngOptions && attr.ngOptions.match(NG_OPTIONS_REGEXP);\n          valuesExpr = match && $parse(match[7]);\n          trackBy = match && match[8];\n          directiveOptions = scope.$eval(attr.chosen) || {};\n          options = angular.copy(config);\n          angular.extend(options, directiveOptions);\n          angular.forEach(attr, function(value, key) {\n            if (indexOf.call(CHOSEN_OPTION_WHITELIST, key) >= 0) {\n              return attr.$observe(key, function(value) {\n                var prefix;\n                prefix = String(element.attr(attr.$attr[key])).slice(0, 2);\n                options[snakeCase(key)] = prefix === '{{' ? value : scope.$eval(value);\n                return disableIfEmpty();\n              });\n            }\n          });\n          startLoading = function() {\n            return element.addClass('loading').attr('disabled', true).trigger('chosen:updated');\n          };\n          stopLoading = function() {\n            element.removeClass('loading');\n            if (angular.isDefined(attr.disabled)) {\n              element.attr('disabled', attr.disabled);\n            } else {\n              element.attr('disabled', false);\n            }\n            return element.trigger('chosen:updated');\n          };\n          chosen = null;\n          empty = false;\n          initIfNotInitialized = function() {\n            if (!chosen) {\n              return scope.$evalAsync(function() {\n                if (!chosen) {\n                  return chosen = element.chosen(options).data('chosen');\n                }\n              });\n            }\n          };\n          disableIfEmpty = function() {\n            if (chosen && empty) {\n              element.attr('disabled', true);\n            }\n            return element.trigger('chosen:updated');\n          };\n          if (ngModel) {\n            $render = ngModel.$render;\n            ngModel.$render = function() {\n              var isPrimitive, nextValue, previousValue, valueChanged;\n              initIfNotInitialized();\n              try {\n                previousValue = ngSelect.readValue();\n              } catch (error) {}\n              $render();\n              try {\n                nextValue = ngSelect.readValue();\n              } catch (error) {}\n              isPrimitive = !trackBy && !attr.multiple;\n              valueChanged = isPrimitive ? previousValue !== nextValue : !angular.equals(previousValue, nextValue);\n              if (valueChanged) {\n                return element.trigger('chosen:updated');\n              }\n            };\n            element.on('chosen:hiding_dropdown', function() {\n              return scope.$applyAsync(function() {\n                return ngModel.$setTouched();\n              });\n            });\n            if (attr.multiple) {\n              viewWatch = function() {\n                return ngModel.$viewValue;\n              };\n              scope.$watch(viewWatch, ngModel.$render, true);\n            }\n          } else {\n            initIfNotInitialized();\n          }\n          attr.$observe('disabled', function() {\n            return element.trigger('chosen:updated');\n          });\n          if (attr.ngOptions && ngModel) {\n            timer = null;\n            scope.$watchCollection(valuesExpr, function(newVal, oldVal) {\n              return timer = $timeout(function() {\n                if (angular.isUndefined(newVal)) {\n                  return startLoading();\n                } else {\n                  empty = isEmpty(newVal);\n                  stopLoading();\n                  return disableIfEmpty();\n                }\n              });\n            });\n            return scope.$on('$destroy', function(event) {\n              if (timer != null) {\n                return $timeout.cancel(timer);\n              }\n            });\n          }\n        }\n      };\n    }\n  ]);\n\n}).call(this);\n"
  },
  {
    "path": "example/index.html",
    "content": "<html ng-app=\"chosenExampleApp\">\n<head>\n\n  <script src=\"http://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js\"></script>\n  <script src=\"http://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js\"></script>\n  <script src=\"https://cdnjs.cloudflare.com/ajax/libs/chosen/1.5.1/chosen.jquery.min.js\"></script>\n\n  <script src=\"../dist/angular-chosen.min.js\"></script>\n  <script src=\"index.js\"></script>\n\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdnjs.cloudflare.com/ajax/libs/chosen/1.5.1/chosen.css\" />\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"../chosen-spinner.css\" />\n  <style>\n    select.localytics-chosen {\n      display: block !important;\n      position:absolute;\n      clip:rect(0,0,0,0);\n      height: 29px;\n    }\n    .border-red {\n      border: 1px solid red;\n    }\n  </style>\n</head>\n<body ng-controller=\"IndexCtrl\">\n  <h1>Chosen Directive Example Usage</h1>\n  <h2>Chosen with a promise: {{foo | json}}</h2>\n  <select\n    chosen\n    multiple\n    allow-single-deselect=\"true\"\n    placeholder-text-multiple=\"'Choose Your Own Adventure'\"\n    no-results-text=\"'Tough luck'\"\n    ng-model=\"foo\"\n    ng-options=\"value for value in optionsFromQuery\"\n    style=\"width:200px;\">\n    <option value=\"\"></option>\n  </select>\n\n  <h2>Chosen with a promised hash: {{baz | json}}</h2>\n  <select\n    chosen\n    allow-single-deselect=\"true\"\n    placeholder-text-single=\"'Choose Your Own Adventure'\"\n    no-results-text=\"'Tough luck'\"\n    ng-model=\"baz\"\n    ng-options=\"value for (key,value) in optionsFromQueryAsHash\"\n    style=\"width:200px;\">\n    <option value=\"\"></option>\n  </select>\n\n  <h2>Chosen with static options: {{ bar }}</h2>\n  <select chosen disable-search=\"true\" ng-model=\"bar\">\n    <option>Hi</option>\n    <option>This is fun</option>\n    <option>I like Chosen so much</option>\n    <option>I also like bunny rabbits</option>\n    <option value=\"\"></option>\n  </select>\n\n  <h2>Passing options in as a hash: {{ woo }}</h2>\n  <select\n    ng-model=\"woo\"\n    chosen=\"directiveOptions\"\n    ng-options=\"value for value in optionsFromQuery\"\n    style=\"width:200px;\">\n    <option value=\"\"></option>\n  </select>\n\n  <h2>Disabling the element with a message when the collection is empty: {{ whatever }}</h2>\n  <input type=\"checkbox\" ng-model=\"emptyCollection\" /> Empty?\n  <select\n    chosen\n    ng-model=\"whatever\"\n    no-results-text=\"'Sorry no options for you'\"\n    ng-options=\"value for value in emptyOptions\"\n    style=\"width:200px;\">\n    <option value=\"\"></option>\n  </select>\n\n  <h2>Changing the ngModel externally: {{ myPets }}</h2>\n  <select\n    multiple\n    ng-model=\"myPets\"\n    ng-options=\"value as label for (value, label) in pets\"\n    chosen\n    style=\"width:200px;\">\n  </select>\n\n  <h2>Disabling the selection:</h2>\n  <label for=\"disabled\">Disabled</label>\n  <input id=\"disabled\" type=\"checkbox\" ng-model=\"disabled\">\n  <br>\n  <select chosen disable-search=\"true\" ng-model=\"somemodel\" ng-disabled=\"disabled\">\n    <option>Great</option>\n    <option>fun</option>\n    <option>Great fun .. indeed</option>\n      <option value=\"\"></option>\n  </select>\n\n  <h2>Form validation</h2>\n  <p>Shows error after user selects nothing (works with Angular 1.3+, uses $touched + $invalid)</p>\n  <form name=\"form\">\n    <select chosen disable-search=\"true\" ng-model=\"somefun\" name=\"fun\" required>\n      <option></option>\n      <option>Great</option>\n      <option>fun</option>\n      <option>Great fun .. indeed</option>\n    </select>\n    <span ng-if=\"form.fun.$invalid && form.fun.$touched\">\n      Error: {{form.fun.$error}}\n    </span>\n    <select disable-search=\"true\" ng-model=\"somefun\" name=\"fun\" required>\n      <option></option>\n      <option>Great</option>\n      <option>fun</option>\n      <option>Great fun .. indeed</option>\n    </select>\n    <br>\n    <input type=\"submit\" />\n  </form>\n\n\n  <h2>#179 - inherit-select-class inside ng-if:</h2>\n  <label for=\"ngIfInherit\">Ng If {{ngIfInherit}}</label>\n  <input id=\"ngIfInherit\" type=\"checkbox\" value=\"1\" ng-model=\"ngIfInherit\">\n  <br>\n  <div>\n    <select ng-if=\"ngIfInherit\" multiple inherit-select-classes=\"true\" class=\"border-red\" chosen ng-model=\"myPets\"\n    ng-options=\"value as label for (value, label) in pets\" style=\"width:200px;\">\n      <option value=\"\"></option>\n    </select>\n  </div>\n\n  <h2>#59 - Don't scroll to top when selecting multiple items with ctrl</h2>\n  <div>\n    <select multiple chosen  ng-model=\"state\" ng-options=\"s for s in states\" style=\"width:200px;\">\n      <option value=\"\"></option>\n    </select>\n  </div>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "example/index.js",
    "content": "// Generated by CoffeeScript 1.6.2\n(function() {\n  angular.module('chosenExampleApp', ['localytics.directives'])\n      .config(['chosenProvider', function (chosenProvider) {\n\t\t  chosenProvider.setOption({\n\t\t\t  no_results_text: 'Haha! There is no results!',\n\t\t\t  placeholder_text_multiple: 'Choose a few!'\n\t\t  });\n\t  }])\n      .controller('IndexCtrl', [\n    '$scope', '$q', '$timeout', function($scope, $q, $timeout) {\n      var simulateAjax;\n\n      simulateAjax = function(result) {\n        var deferred, fn;\n\n        deferred = $q.defer();\n        fn = function() {\n          return deferred.resolve(result);\n        };\n        $timeout(fn, 3000);\n        return deferred.promise;\n      };\n      simulateAjax(['grooo', 'wowowowow', 'lakakalakakl', 'yadayada', 'insight', 'delve', 'synergy']).then(function(result) {\n        return $scope.optionsFromQuery = result;\n      });\n      $scope.optionsFromQueryAsHash = (function() {\n        var result;\n\n        result = {\n          win: \"Brilliant Escape\",\n          fail: \"Untimely Demise\"\n        };\n        return simulateAjax(result);\n      })();\n      $scope.$watch('emptyCollection', function(empty) {\n        return $scope.emptyOptions = simulateAjax(empty ? [] : ['look', 'i', 'have', 'data']);\n      });\n      $scope.directiveOptions = {\n        no_results_text: \"SO SORRY\"\n      };\n      $scope.ngIfInherit = true;\n      $scope.myPets = ['cat'];\n      $scope.pets = {\n        cat: 'Cat',\n        dog: 'Dog',\n        hamster: 'Hamster'\n      };\n      $scope.state = ['California', 'Arizona'];\n  $scope.states = {\n    \"AL\": \"Alabama\",\n    \"AK\": \"Alaska\",\n    \"AS\": \"American Samoa\",\n    \"AZ\": \"Arizona\",\n    \"AR\": \"Arkansas\",\n    \"CA\": \"California\",\n    \"CO\": \"Colorado\",\n    \"CT\": \"Connecticut\",\n    \"DE\": \"Delaware\",\n    \"DC\": \"District Of Columbia\",\n    \"FM\": \"Federated States Of Micronesia\",\n    \"FL\": \"Florida\",\n    \"GA\": \"Georgia\",\n    \"GU\": \"Guam\",\n    \"HI\": \"Hawaii\",\n    \"ID\": \"Idaho\",\n    \"IL\": \"Illinois\",\n    \"IN\": \"Indiana\",\n    \"IA\": \"Iowa\",\n    \"KS\": \"Kansas\",\n    \"KY\": \"Kentucky\",\n    \"LA\": \"Louisiana\",\n    \"ME\": \"Maine\",\n    \"MH\": \"Marshall Islands\",\n    \"MD\": \"Maryland\",\n    \"MA\": \"Massachusetts\",\n    \"MI\": \"Michigan\",\n    \"MN\": \"Minnesota\",\n    \"MS\": \"Mississippi\",\n    \"MO\": \"Missouri\",\n    \"MT\": \"Montana\",\n    \"NE\": \"Nebraska\",\n    \"NV\": \"Nevada\",\n    \"NH\": \"New Hampshire\",\n    \"NJ\": \"New Jersey\",\n    \"NM\": \"New Mexico\",\n    \"NY\": \"New York\",\n    \"NC\": \"North Carolina\",\n    \"ND\": \"North Dakota\",\n    \"MP\": \"Northern Mariana Islands\",\n    \"OH\": \"Ohio\",\n    \"OK\": \"Oklahoma\",\n    \"OR\": \"Oregon\",\n    \"PW\": \"Palau\",\n    \"PA\": \"Pennsylvania\",\n    \"PR\": \"Puerto Rico\",\n    \"RI\": \"Rhode Island\",\n    \"SC\": \"South Carolina\",\n    \"SD\": \"South Dakota\",\n    \"TN\": \"Tennessee\",\n    \"TX\": \"Texas\",\n    \"UT\": \"Utah\",\n    \"VT\": \"Vermont\",\n    \"VI\": \"Virgin Islands\",\n    \"VA\": \"Virginia\",\n    \"WA\": \"Washington\",\n    \"WV\": \"West Virginia\",\n    \"WI\": \"Wisconsin\",\n    \"WY\": \"Wyoming\"\n  };\n      $timeout(function() {\n        return $scope.$apply(function() {\n          return $scope.myPets.push('hamster');\n        });\n      }, 1000);\n      return $scope.disabled = true;\n    }\n  ]);\n\n}).call(this);\n"
  },
  {
    "path": "gulpfile.js",
    "content": "var config = {\n    test: './test',\n\tsrc: './src/',\n    dist: './dist/',\n    file: 'angular-chosen'\n};\n\nvar banner = ['/**',\n  ' * <%= pkg.name %> - <%= pkg.description %>',\n  ' * @version v<%= pkg.version %>',\n  ' * @link <%= pkg.homepage %>',\n  ' * @license <%= pkg.license %>',\n  ' */',\n  ''].join('\\n');\n\nvar args = require('yargs').argv,\n    gulp = require('gulp'),\n    karma = require('karma'),\n    del  = require('del'),\n    $    = require('gulp-load-plugins')({ lazy: true }),\n    pkg  = require('./package.json');\n\n// List Tasks by default\ngulp.task('default', $.taskListing.withFilters(null, ['build-hint']));\n\ngulp.task('build-hint', function() {\n    return gulp.src(config.src + '/*.coffee')\n        .pipe($.if(args.debug, $.debug()))\n        .pipe($.plumber())\n        .pipe($.coffeelint('./src/coffeelint.json'))\n        .pipe($.coffeelint.reporter());\n});\n\n/**\n * Compile CoffeeScript into ./dist/angular-chose.js\n */\ngulp.task('build-coffee-script', ['build-hint'], function() {\n    return gulp.src(config.src + '/*.coffee')\n        .pipe($.if(args.debug, $.debug()))\n        .pipe($.plumber())\n    \t.pipe($.coffee().on('error', $.util.log))\n    \t.pipe($.rename(config.file + '.js'))\n        .pipe($.header(banner, { pkg : pkg }))\n    \t.pipe(gulp.dest(config.dist));\n});\n\n/**\n * Minify ./dist/angular-chose.js into ./dist/angular-chose.min.js\n */\ngulp.task('build-minify', ['build-coffee-script'], function() {\n    return gulp.src(config.dist + '/angular-chosen.js')\n        .pipe($.if(args.debug, $.debug()))\n        .pipe($.plumber())\n        .pipe($.uglify({mangle: true}))\n        .pipe($.rename(config.file + '.min.js'))\n        .pipe($.header(banner, {pkg : pkg}))\n        .pipe(gulp.dest(config.dist));\n});\n\n/**\n * Run Clean Javascripts, than minify(coffee-script)\n */\ngulp.task('build', ['build-clean-javascripts'], function() {\n    gulp.start('build-minify');\n});\n\n/**\n * Clean Javascripts from .dist/\n */\ngulp.task('build-clean-javascripts', function() {\n    return del(config.dist);\n});\n\n/**\n * Watch files and compile Coffee Script in real-time\n */\ngulp.task('watcher', ['tests'], function() {\n    gulp.watch([config.src + '*.coffee', config.dist + '*.js'], ['tests']);\n});\n\ngulp.task('test', ['build'], function (done) {\n  new karma.Server({\n    configFile: __dirname + '/test/support/karma.conf.js',\n      singleRun: true\n  }, done).start();\n});\n\ngulp.task('tests', ['build'], function (done) {\n  new karma.Server({\n    configFile: __dirname + '/test/support/karma.conf.js',\n    singleRun: false\n  }, done).start();\n});\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"angular-chosen-localytics\",\n  \"filename\": \"chosen.js\",\n  \"main\": \"dist/angular-chosen.js\",\n  \"version\": \"1.9.2\",\n  \"description\": \"Angular Chosen directive is an AngularJS Directive that brings the Chosen jQuery in a Angular way\",\n  \"homepage\": \"http://github.com/leocaseiro/angular-chosen\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/leocaseiro/angular-chosen\"\n  },\n  \"keywords\": [\n    \"angularjs\",\n    \"select\",\n    \"multiselect\",\n    \"dropdown\",\n    \"form\",\n    \"input\",\n    \"ui\"\n  ],\n  \"license\": \"MIT\",\n  \"author\": \"jr314159\",\n  \"contributors\": [\n    \"abuggia\",\n    \"abyx\",\n    \"charandas\",\n    \"dariusriggins\",\n    \"darlanalves\",\n    \"dougludlow\",\n    \"failpunk\",\n    \"frnan\",\n    \"gaui\",\n    \"iamnewspecies\",\n    \"ilychkov\",\n    \"kfarst\",\n    \"leocaseiro\",\n    \"lpsBetty\",\n    \"lukeMason\",\n    \"nike-17\",\n    \"odi55555\",\n    \"paulpflug\",\n    \"simison\",\n    \"slobo\",\n    \"stefanvermaas\",\n    \"vantanev\",\n    \"vstene\",\n    \"zlodes\"\n  ],\n  \"dependencies\": {\n    \"angular\": \"^1.5.7\",\n    \"chosen-js\": \"^1.6.1\",\n    \"jquery\": \"^3.0.0\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/leocaseiro/angular-chosen/issues\"\n  },\n  \"devDependencies\": {\n    \"angular-mocks\": \"^1.4.9\",\n    \"del\": \"^2.2.0\",\n    \"gulp\": \"^3.9.1\",\n    \"gulp-coffee\": \"^2.3.1\",\n    \"gulp-coffeelint\": \"^0.6.0\",\n    \"gulp-debug\": \"^2.1.2\",\n    \"gulp-header\": \"^1.7.1\",\n    \"gulp-if\": \"^2.0.0\",\n    \"gulp-load-plugins\": \"^1.2.0\",\n    \"gulp-plumber\": \"^1.1.0\",\n    \"gulp-rename\": \"^1.2.2\",\n    \"gulp-task-listing\": \"^1.0.1\",\n    \"gulp-uglify\": \"^1.5.3\",\n    \"gulp-util\": \"^3.0.7\",\n    \"jasmine-core\": \"^2.4.1\",\n    \"karma\": \"^0.13.22\",\n    \"karma-coffee-preprocessor\": \"^0.3.0\",\n    \"karma-jasmine\": \"^0.3.7\",\n    \"karma-jasmine-matchers\": \"^2.0.2\",\n    \"karma-mocha-reporter\": \"^2.0.0\",\n    \"karma-phantomjs-launcher\": \"^1.0.0\",\n    \"phantomjs-prebuilt\": \"^2.1.5\",\n    \"yargs\": \"^4.2.0\"\n  },\n  \"scripts\": {\n    \"test\": \"gulp test\"\n  }\n}\n"
  },
  {
    "path": "src/.editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": "src/chosen.coffee",
    "content": "angular.module('localytics.directives', [])\n\nchosenModule = angular.module('localytics.directives')\n\nchosenModule.provider 'chosen', ->\n  options = {}\n  {\n    setOption: (newOpts) ->\n      angular.extend options, newOpts\n      return\n    $get: ->\n      options\n  }\n\nchosenModule.directive 'chosen', ['chosen', '$timeout', '$parse', (config, $timeout, $parse) ->\n  # coffeelint: disable=max_line_length\n  # This is stolen from Angular...\n  NG_OPTIONS_REGEXP =  /^\\s*([\\s\\S]+?)(?:\\s+as\\s+([\\s\\S]+?))?(?:\\s+group\\s+by\\s+([\\s\\S]+?))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+([\\s\\S]+?)(?:\\s+track\\s+by\\s+([\\s\\S]+?))?$/\n  # coffeelint: enable=max_line_length\n\n  # Whitelist of options that will be parsed from the element's attributes and passed into Chosen\n  #\n  # Can be updated by running the following script on the options page\n  # https://harvesthq.github.io/chosen/options.html\n  #\n  # Array.from(\n  #   document.querySelectorAll('table:first-of-type tr td:first-of-type')\n  # )\n  # .map(node => node.textContent)\n  # .map(option => option.replace(/_(\\w)/g, (_, letter) => letter.toUpperCase()))\n  #\n  CHOSEN_OPTION_WHITELIST = [\n    'allowSingleDeselect'\n    'disableSearch'\n    'disableSearchThreshold'\n    'enableSplitWordSearch'\n    'inheritSelectClasses'\n    'maxSelectedOptions'\n    'noResultsText'\n    'placeholderTextMultiple'\n    'placeholderTextSingle'\n    'searchContains'\n    'groupSearch'\n    'singleBackstrokeDelete'\n    'width'\n    'displayDisabledOptions'\n    'displaySelectedOptions'\n    'includeGroupLabelInSelected'\n    'maxShownResults'\n    'caseSensitiveSearch'\n    'hideResultsOnSelect'\n    'rtl'\n  ]\n\n  snakeCase = (input) -> input.replace /[A-Z]/g, ($1) -> \"_#{$1.toLowerCase()}\"\n  isEmpty = (value) ->\n    if angular.isArray(value)\n      return value.length is 0\n    else if angular.isObject(value)\n      return false for key of value when value.hasOwnProperty(key)\n    true\n\n  restrict: 'A'\n  require: ['select', '?ngModel']\n  priority: 1\n  link: (scope, element, attr, ctrls) ->\n    scope.disabledValuesHistory = if scope.disabledValuesHistory then scope.disabledValuesHistory else []\n    element = $ element # Use real JQuery if it wasn't loaded before Angular.\n    element.addClass('localytics-chosen')\n\n    ngSelect = ctrls[0]\n    ngModel = ctrls[1]\n\n    match = attr.ngOptions && attr.ngOptions.match(NG_OPTIONS_REGEXP)\n    valuesExpr = match && $parse(match[7])\n    trackBy = match && match[8]\n\n    # Take a hash of options from the chosen directive\n    directiveOptions = scope.$eval(attr.chosen) or {}\n\n    # Clone options from configProvider\n    options = angular.copy(config)\n\n    # Merge options from directive with options from configProvider\n    angular.extend(options, directiveOptions)\n\n    # Options defined as attributes take precedence\n    angular.forEach attr, (value, key) ->\n      if key in CHOSEN_OPTION_WHITELIST\n\n        # Observe attributes\n        # Update the value in options. Set the default texts again. Update message.\n        attr.$observe key, (value) ->\n          prefix = String(element.attr(attr.$attr[key])).slice(0, 2)\n          options[snakeCase(key)] = if prefix is '{{' then value else scope.$eval(value)\n          disableIfEmpty()\n\n    startLoading = -> element.addClass('loading').attr('disabled', true).trigger('chosen:updated')\n\n    stopLoading = ->\n      element.removeClass('loading')\n      if angular.isDefined attr.disabled\n        element.attr 'disabled', attr.disabled\n      else\n        element.attr 'disabled', false\n      element.trigger('chosen:updated')\n\n    chosen = null\n    empty = false\n\n    # async initialize chosen if it's not initialized yet\n    initIfNotInitialized = ->\n      if !chosen\n        scope.$evalAsync ->\n          if !chosen then chosen = element.chosen(options).data('chosen')\n\n    # Use Chosen's placeholder or no results found text depending on whether there are options available\n    disableIfEmpty = ->\n      if chosen && empty\n        element.attr('disabled', true)\n      element.trigger('chosen:updated')\n\n    # Watch the underlying ngModel for updates and trigger an update when they occur.\n    if ngModel\n      $render = ngModel.$render\n      ngModel.$render = ->\n        initIfNotInitialized()\n\n        # We need to try and detect if the select value was changed from outside of chosen\n        try previousValue = ngSelect.readValue()\n        $render()\n        try nextValue = ngSelect.readValue()\n\n        isPrimitive = !trackBy && !attr.multiple\n        valueChanged = if isPrimitive\n        then previousValue != nextValue\n        else !angular.equals(previousValue, nextValue)\n\n        # If it was changed, then we trigger a chosen re-render\n        if (valueChanged)\n          element.trigger('chosen:updated')\n\n      element.on 'chosen:hiding_dropdown', ->\n        scope.$applyAsync -> ngModel.$setTouched()\n\n      # This is basically taken from angular ngOptions source.  ngModel watches reference, not value,\n      # so when values are added or removed from array ngModels, $render won't be fired.\n      if attr.multiple\n        viewWatch = -> ngModel.$viewValue\n        scope.$watch viewWatch, ngModel.$render, true\n    else\n      initIfNotInitialized()\n\n    # Watch the disabled attribute (could be set by ngDisabled)\n    attr.$observe 'disabled', -> element.trigger('chosen:updated')\n\n    # Watch the collection in ngOptions and update chosen when it changes.  This works with promises!\n    # ngOptions doesn't do anything unless there is an ngModel, so neither do we.\n    if attr.ngOptions and ngModel\n      timer = null\n      scope.$watchCollection valuesExpr, (newVal, oldVal) ->\n        # Defer execution until DOM is loaded\n        timer = $timeout(->\n          if angular.isUndefined(newVal)\n            startLoading()\n          else\n            empty = isEmpty(newVal)\n            stopLoading()\n            disableIfEmpty()\n        )\n\n      scope.$on '$destroy', (event) ->\n        $timeout.cancel timer if timer?\n]\n"
  },
  {
    "path": "src/coffeelint.json",
    "content": "{\n  \"coffeescript_error\": {\n    \"level\": \"error\"\n  },\n  \"arrow_spacing\": {\n    \"name\": \"arrow_spacing\",\n    \"level\": \"warn\"\n  },\n  \"no_tabs\": {\n    \"name\": \"no_tabs\",\n    \"level\": \"error\"\n  },\n  \"no_trailing_whitespace\": {\n    \"name\": \"no_trailing_whitespace\",\n    \"level\": \"warn\",\n    \"allowed_in_comments\": false,\n    \"allowed_in_empty_lines\": false\n  },\n  \"max_line_length\": {\n    \"name\": \"max_line_length\",\n    \"value\": 120,\n    \"level\": \"error\",\n    \"limitComments\": true\n  },\n  \"line_endings\": {\n    \"name\": \"line_endings\",\n    \"level\": \"ignore\",\n    \"value\": \"unix\"\n  },\n  \"no_trailing_semicolons\": {\n    \"name\": \"no_trailing_semicolons\",\n    \"level\": \"error\"\n  },\n  \"indentation\": {\n    \"name\": \"indentation\",\n    \"value\": 2,\n    \"level\": \"error\"\n  },\n  \"camel_case_classes\": {\n    \"name\": \"camel_case_classes\",\n    \"level\": \"error\"\n  },\n  \"colon_assignment_spacing\": {\n    \"name\": \"colon_assignment_spacing\",\n    \"level\": \"warn\",\n    \"spacing\": {\n      \"left\": 0,\n      \"right\": 1\n    }\n  },\n  \"no_implicit_braces\": {\n    \"name\": \"no_implicit_braces\",\n    \"level\": \"ignore\",\n    \"strict\": true\n  },\n  \"no_plusplus\": {\n    \"name\": \"no_plusplus\",\n    \"level\": \"ignore\"\n  },\n  \"no_throwing_strings\": {\n    \"name\": \"no_throwing_strings\",\n    \"level\": \"error\"\n  },\n  \"no_backticks\": {\n    \"name\": \"no_backticks\",\n    \"level\": \"error\"\n  },\n  \"no_implicit_parens\": {\n    \"name\": \"no_implicit_parens\",\n    \"level\": \"ignore\"\n  },\n  \"no_empty_param_list\": {\n    \"name\": \"no_empty_param_list\",\n    \"level\": \"warn\"\n  },\n  \"no_stand_alone_at\": {\n    \"name\": \"no_stand_alone_at\",\n    \"level\": \"ignore\"\n  },\n  \"space_operators\": {\n    \"name\": \"space_operators\",\n    \"level\": \"warn\"\n  },\n  \"duplicate_key\": {\n    \"name\": \"duplicate_key\",\n    \"level\": \"error\"\n  },\n  \"empty_constructor_needs_parens\": {\n    \"name\": \"empty_constructor_needs_parens\",\n    \"level\": \"ignore\"\n  },\n  \"cyclomatic_complexity\": {\n    \"name\": \"cyclomatic_complexity\",\n    \"value\": 10,\n    \"level\": \"ignore\"\n  },\n  \"newlines_after_classes\": {\n    \"name\": \"newlines_after_classes\",\n    \"value\": 3,\n    \"level\": \"ignore\"\n  },\n  \"no_unnecessary_fat_arrows\": {\n    \"name\": \"no_unnecessary_fat_arrows\",\n    \"level\": \"warn\"\n  },\n  \"missing_fat_arrows\": {\n    \"name\": \"missing_fat_arrows\",\n    \"level\": \"ignore\"\n  },\n  \"non_empty_constructor_needs_parens\": {\n    \"name\": \"non_empty_constructor_needs_parens\",\n    \"level\": \"ignore\"\n  }\n}\n"
  },
  {
    "path": "test/base.spec.js",
    "content": "describe('base functionality', function() {\n  var element;\n\n  it('should work without ngModel', function() {\n    element = $compile('<select chosen><option value=\"one\">One</option></select>')($scope);\n    $scope.$apply();\n    var chosenSelected = element.next().find('.chosen-single span');\n    expect(chosenSelected.length).toBe(1)\n  })\n\n  beforeEach(function() {\n    $scope.currentLanguage = 'german';\n    $scope.languages = ['german', 'english'];\n\n    // Compile a piece of HTML containing the directive\n    element = $compile('<select chosen ng-options=\"lang for lang in languages\" ng-model=\"currentLanguage\"><option></option></select>')($scope);\n    $scope.$apply();\n    $timeout.flush();\n    element.trigger('chosen:open.chosen'); // fills dropdown (triggers chosen:showing_dropdown when finished)\n    element.trigger('chosen:close.chosen');\n  });\n\n  it('should add chosen dropdown', function() {\n    var chosenContainer = element.next();\n    var chosenSelected = chosenContainer.find('.chosen-single span');\n    var chosenList = chosenContainer.find('.chosen-drop ul li');\n\n    expect(chosenSelected.text()).toBe($scope.currentLanguage);\n\n    expect(chosenList.length).toBe(2);\n    expect(chosenList.first().text()).toBe($scope.languages[0]);\n    expect(chosenList.last().text()).toBe($scope.languages[1]);\n  });\n\n  it('should work when current model updates', function() {\n    var chosenContainer = element.next();\n    var chosenSelected = chosenContainer.find('.chosen-single span');\n\n    expect(chosenSelected.text()).toBe('german');\n\n    $scope.currentLanguage = 'english';\n    $scope.$apply();\n\n    expect(chosenSelected.text()).toBe('english');\n  });\n\n  it('should trigger ngChange function when selecting a chosen result', function() {\n    $scope.changed = false;\n\n    // Compile a piece of HTML containing the directive\n    element = $compile('<select chosen ng-options=\"lang for lang in languages\" ng-model=\"currentLanguage\" ng-change=\"changed=true\"><option></option></select>')($scope);\n    $scope.$apply();\n    $timeout.flush();\n\n    element.trigger('chosen:open.chosen');\n\n    var chosenContainer = element.next();\n    var chosenSelected = chosenContainer.find('.chosen-single span');\n    var chosenList = chosenContainer.find('.chosen-drop ul li');\n\n    expect(chosenSelected.text()).toBe('german');\n\n    chosenList.last().trigger('mouseup'); // select english = last item\n\n    expect(chosenSelected.text()).toBe('english');\n    expect($scope.changed).toBe(true);\n  });\n\n  it('should disable chosen with ngDisabled', function() {\n    $scope.disabled = true;\n\n    // Compile a piece of HTML containing the directive\n    element = $compile('<select chosen ng-options=\"lang for lang in languages\" ng-model=\"currentLanguage\" ng-disabled=\"disabled\"><option></option></select>')($scope);\n    $scope.$apply();\n    $timeout.flush();\n\n    var chosenContainer = element.next();\n\n    expect(chosenContainer.hasClass('chosen-disabled')).toBe(true);\n\n    $scope.disabled = false;\n    $scope.$apply();\n\n    expect(chosenContainer.hasClass('chosen-disabled')).toBe(false);\n  });\n});\n\n\n\n"
  },
  {
    "path": "test/chosenAttrSpec.js",
    "content": "describe('chosen attributes', function() {\n\n  var element;\n\n  it('should inherit class customclass from select', function() {\n    var customClass = 'customclass';\n    var chosenContainer;\n    var select = function(inheritSelectClasses, customClass) {\n      return '<select chosen inherit-select-classes=\"' + inheritSelectClasses + '\" class=\"' + customClass + '\" ng-model=\"currentLanguage\"><option></option></select>';\n    };\n\n    //inherit-select-classes = true\n    element = $compile(select(true, customClass))($scope);\n    $scope.$apply();\n    chosenContainer = element.next();\n    expect(chosenContainer.hasClass(customClass)).toBe(true);\n\n    //inherit-select-classes = false\n    element = $compile(select(false, customClass))($scope);\n    $scope.$apply();\n    chosenContainer = element.next();\n    expect(chosenContainer.hasClass(customClass)).toBe(false);\n  });\n\n});\n\n\n\n"
  },
  {
    "path": "test/chosenOptions/allowSingleDeselected.spec.js",
    "content": "describe('Chosen options: allow-single-deselect', function () {\n  beforeEach(function () {\n    chosenSelectHelper.compileWithAttributes({\n      allowSingleDeselect: true\n    });\n  });\n\n  it('removes the model value when deselected', function () {\n    var removeButton = chosenSelectHelper.chosenContainer().find('abbr.search-choice-close');\n\n    removeButton.trigger('mouseup.chosen');\n\n    expect($scope.currentLanguage).toBeNull();\n  });\n});\n"
  },
  {
    "path": "test/chosenOptions/disableSearch.spec.js",
    "content": "describe('Chosen options: disable-search', function () {\n  beforeEach(function () {\n    chosenSelectHelper.compileWithAttributes({\n      disableSearch: true\n    });\n  });\n\n  it('hides the search input', function () {\n    expect(chosenSelectHelper.searchInput().attr('readOnly')).toBeTruthy();\n  });\n});\n\n"
  },
  {
    "path": "test/chosenOptions/disableSearchThreshold.spec.js",
    "content": "describe('Chosen options: disable-search-threshold', function () {\n  it('disables the search when the results are lower than the threshold', function () {\n    chosenSelectHelper.compileWithAttributes({\n      disableSearchThreshold: 3\n    });\n\n    expect(chosenSelectHelper.searchInput().attr('readOnly')).toBeTruthy();\n  });\n\n  it('does not disable the search when the results are higher than the threshold', function () {\n    chosenSelectHelper.compileWithAttributes({\n      disableSearchThreshold: 1\n    });\n\n    expect(chosenSelectHelper.searchInput().attr('readOnly')).toBeFalsy();\n  });\n});\n\n"
  },
  {
    "path": "test/chosenOptions/inheritSelectClasses.spec.js",
    "content": "describe('Chosen options: inherit-select-classes', function () {\n\n  it('passes classes from the select tag to the chosen container', function () {\n    chosenSelectHelper.compileWithAttributes({\n      inheritSelectClasses: true,\n      'class': 'inherited-class'\n    });\n\n    expect(chosenSelectHelper.chosenContainer().hasClass('inherited-class')).toBeTruthy();\n  });\n\n  it('dont pass classes from the select tag to the chosen container', function () {\n    chosenSelectHelper.compileWithAttributes({\n      inheritSelectClasses: false,\n      'class': 'inherited-class'\n    });\n\n    expect(chosenSelectHelper.chosenContainer().hasClass('inherited-class')).toBeFalsy();\n  });\n});\n\n"
  },
  {
    "path": "test/chosenOptions/maxShownResults.spec.js",
    "content": "describe('Chosen options: max-shown-results', function () {\n  beforeEach(function () {\n    chosenSelectHelper.compileWithAttributes({\n      maxShownResults: 1\n    });\n\n    chosenSelectHelper.selectTag.trigger('chosen:open.chosen');\n    chosenSelectHelper.chosenResults().last().trigger('mouseup.chosen');\n  });\n\n  it('displays only the maximum number of results specified', function () {\n    expect(chosenSelectHelper.chosenResults().length).toBe(1);\n  });\n});\n\n"
  },
  {
    "path": "test/chosenOptions/noResultsText.spec.js",
    "content": "describe('Chosen options: no-results-text', function () {\n  beforeEach(function () {\n    chosenSelectHelper.compileWithAttributes({\n      noResultsText: \"'testing no results text'\"\n    });\n\n    chosenSelectHelper.searchInput().val('foo');\n    chosenSelectHelper.searchInput().trigger('keyup.chosen');\n  });\n\n  it('displays the specified message when a search returns no results', function () {\n    expect(chosenSelectHelper.chosenResults().html()).toMatch('testing no results text');\n  });\n});\n"
  },
  {
    "path": "test/chosenOptions/placeholderTextMultiple.spec.js",
    "content": "describe('Chosen options: placeholder-text-multiple', function () {\n  beforeEach(function () {\n    $scope.emptyModel = [];\n\n    chosenSelectHelper.compileWithAttributes({\n      multiple: true,\n      placeholderTextMultiple: \"'testing multi placeholder text'\",\n      ngModel: 'emptyModel'\n    });\n  });\n\n  it('shows the specified placeholder text for a multi-select chosen tag', function () {\n    expect(chosenSelectHelper.chosenContainer().find('.search-field input').attr('value')).toMatch('testing multi placeholder text');\n  });\n});\n\n"
  },
  {
    "path": "test/chosenOptions/placeholderTextSingle.spec.js",
    "content": "describe('Chosen options: placeholder-text-single', function () {\n  beforeEach(function () {\n    chosenSelectHelper.compileWithAttributes({\n      placeholderTextSingle: \"'testing single placeholder text'\",\n      ngModel: 'emptyModel'\n    });\n  });\n\n  it('shows the specified placeholder text for a single-select chosen tag', function () {\n    expect(chosenSelectHelper.chosenContainer().find('.chosen-default span').text()).toMatch('testing single placeholder text');\n  });\n});\n"
  },
  {
    "path": "test/chosenOptions/searchContains.spec.js",
    "content": "describe('Chosen options: search-contains', function () {\n  beforeEach(function () {\n    chosenSelectHelper.compileWithAttributes({\n      searchContains: true\n    });\n\n    chosenSelectHelper.searchInput().val('erma');\n    chosenSelectHelper.searchInput().trigger('keyup.chosen');\n  });\n\n  it('finds a match in the search result that is not at the beginning of the option text', function () {\n    expect(chosenSelectHelper.chosenResults().length).toBeTruthy();\n  });\n});\n"
  },
  {
    "path": "test/chosenOptions/width.spec.js",
    "content": "describe('Chosen options: width', function () {\n  beforeEach(function () {\n    chosenSelectHelper.compileWithAttributes({\n      width: 250\n    });\n  });\n\n  it('sets the dropdown width', function () {\n    expect(chosenSelectHelper.chosenContainer().attr('style')).toContain('width: 250');\n  });\n});\n"
  },
  {
    "path": "test/form.spec.js",
    "content": "describe('form validations', function() {\n\n  var element, ngModel;\n\n  beforeEach(function() {\n    $scope.currentLanguage = null;\n    $scope.languages = ['german', 'english'];\n\n    // Compile a piece of HTML containing the directive\n    var form = $compile('<form name=\"form\"><select chosen ng-options=\"lang for lang in languages\" ng-model=\"currentLanguage\" name=\"language\" required><option></option></select></form>')($scope);\n    element = form.find('select');\n    ngModel = $scope.form.language;\n\n    $scope.$apply();\n  });\n\n  it('should work with required form validation', function() {\n    expect(ngModel.$valid).toBe(false);\n    expect(ngModel.$error.required).toBe(true);\n\n    $scope.currentLanguage = 'german';\n    $scope.$apply();\n\n    expect(ngModel.$valid).toBe(true);\n  });\n\n  it('should set $touched of ngModel to true (for e.g. form validation)', function() {\n    expect(ngModel.$touched).toBe(false);\n\n    element.trigger('chosen:open.chosen');\n    $scope.$apply();\n\n    element.trigger('chosen:hiding_dropdown');\n    $scope.$apply();\n\n    expect(ngModel.$touched).toBe(true);\n  });\n\n});\n\n\n\n"
  },
  {
    "path": "test/issues/179-ng-if-breaks-inherit-select-classes.spec.js",
    "content": "describe('#179 inherit-select-classes inside ng-if', function () {\n\n  it('passes classes from the select tag to the chosen container inside ng-if', function () {\n    var element;\n    var customClass = 'customclass';\n    var chosenContainer;\n\n    $scope.test = true;\n\n    var select = function(inheritSelectClasses, customClass) {\n      return '<main><div ng-if=\"test\">{{test}}<select chosen inherit-select-classes=\"' + inheritSelectClasses + '\" class=\"' + customClass + '\" ng-model=\"currentLanguage\"><option></option></select></div></main>';\n    };\n\n    //inherit-select-classes = true\n    element = $compile(select(true, customClass))($scope);\n    $scope.$apply();\n\n    chosenContainer = element.find('select').next();\n    expect(chosenContainer.hasClass(customClass)).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/support/caseConvertFilter.js",
    "content": "angular.module('caseConvertFilter', [])\n.filter('caseConvert', function () {\n  var SNAKE_CASE_REGEXP = /[A-Z]/g;\n\n  return function (name, separator) {\n    var separator = separator || '_';\n\n    return name.replace(SNAKE_CASE_REGEXP, function (letter, pos) {\n      return (pos ? separator : '') + letter.toLowerCase();\n    });\n  };\n});\n"
  },
  {
    "path": "test/support/chosenSelectHelper.js",
    "content": "angular.module('chosenSelectHelper', [])\n.service('chosenSelectHelper', ['$filter', function ($filter) {\n  return {\n    compileWithAttributes: function (attributes) {\n      var attributes = attributes || {};\n\n      if (!attributes['ngModel']) {\n        $scope.currentLanguage = 'german';\n        attributes['ngModel'] = 'currentLanguage';\n      }\n\n      if (!attributes['ngOptions']) {\n        $scope.languages = ['german', 'english'];\n        attributes['ngOptions'] = 'lang for lang in languages';\n      }\n\n      for (attrName in attributes) {\n        this.selectTag.attr($filter('caseConvert')(attrName, '-'), attributes[attrName]);\n      }\n\n      $compile(this.selectTag)($scope);\n      $scope.$apply();\n      $timeout.flush();\n    },\n\n    selectTag: angular.element('<select chosen><option value=\"\"></option></select>'),\n\n    chosenContainer: function () {\n      return this.selectTag.next();\n    },\n\n    chosenResults: function () {\n      return this.chosenContainer().find('.chosen-results li');\n    },\n\n    searchInput: function () {\n      return this.chosenContainer().find('.chosen-search input');\n    }\n  };\n}]);\n"
  },
  {
    "path": "test/support/karma.conf.js",
    "content": "'use strict';\n\nmodule.exports = function(config) {\n  config.set({\n    basePath: '../../',\n\n    frameworks: [\n      'jasmine',\n      'jasmine-matchers'\n    ],\n\n    files: [\n      'node_modules/jquery/dist/jquery.js',\n      'node_modules/chosen-js/chosen.jquery.js',\n      'node_modules/angular/angular.js',\n      'node_modules/angular-mocks/angular-mocks.js',\n      'src/**/*.coffee',\n      'test/support/*.js',\n      'test/**/*.spec.js'\n    ],\n\n    preprocessors: {\n      'src/**/*.coffee': ['coffee']\n    },\n\n    reporters: ['mocha'],\n\n    // Start these browsers, currently available:\n    // - Chrome\n    // - ChromeCanary\n    // - Firefox\n    // - Opera\n    // - Safari (only Mac)\n    // - PhantomJS\n    // - IE (only Windows)\n    browsers: [\n      // 'PhantomJS', 'Chrome', 'Firefox', 'Safari'\n      'PhantomJS'\n    ],\n\n    // Which plugins to enable\n    plugins: [\n      'karma-mocha-reporter',\n      'karma-phantomjs-launcher',\n      // 'karma-chrome-launcher',\n      // 'karma-firefox-launcher',\n      // 'karma-safari-launcher',\n      'karma-jasmine',\n      'karma-jasmine-matchers',\n      'karma-coffee-preprocessor'\n    ],\n\n    singleRun: true\n  });\n};\n"
  },
  {
    "path": "test/support/specHelper.js",
    "content": "beforeEach(function() {\n  angular.module('testApp', [\n    'localytics.directives',\n    'caseConvertFilter',\n    'chosenSelectHelper'\n  ]);\n\n  angular.mock.module('testApp');\n});\n\nvar $scope;\nvar $timeout;\nvar $compile;\nvar chosenSelectHelper;\n\n/**\n * Assigns $scope, $timeout and $compile, these will be used in every test.\n */\nbeforeEach(inject(function(_$rootScope_, _$timeout_, _$compile_, _chosenSelectHelper_) {\n  $scope = _$rootScope_.$new();\n  $timeout = _$timeout_;\n  $compile = _$compile_;\n  chosenSelectHelper = _chosenSelectHelper_;\n}));\n"
  }
]