[
  {
    "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\nindent_style = space\nindent_size = 2\ncharset = utf-8\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[**/package.json]\nindent_size = 2\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"env\": {\n    \"browser\": true,\n    \"node\": true,\n    \"amd\": true\n  },\n  \"globals\": {\n    \"attachEvent\": false,\n    \"detachEvent\": false\n  },\n  \"rules\": {\n    \"array-bracket-spacing\": 2,\n    \"block-scoped-var\": 2,\n    \"brace-style\": [1, \"1tbs\", {\"allowSingleLine\": true}],\n    \"camelcase\": 2,\n    \"comma-dangle\": [2, \"never\"],\n    \"comma-spacing\": 2,\n    \"computed-property-spacing\": [2, \"never\"],\n    \"dot-notation\": [2, { \"allowKeywords\": false }],\n    \"eol-last\": 2,\n    \"eqeqeq\": [2, \"smart\"],\n    \"indent\": [2, 2, {\n      \"MemberExpression\": 0,\n      \"SwitchCase\": 1,\n      \"VariableDeclarator\": 2\n    }],\n    \"key-spacing\": 1,\n    \"keyword-spacing\": [2, { \"after\": true }],\n    \"linebreak-style\": 2,\n    \"max-depth\": [1, 4],\n    \"max-params\": [1, 5],\n    \"new-cap\": [2, {\"newIsCapExceptions\": [\"model\"]}],\n    \"no-alert\": 2,\n    \"no-caller\": 2,\n    \"no-catch-shadow\": 2,\n    \"no-console\": 2,\n    \"no-debugger\": 2,\n    \"no-delete-var\": 2,\n    \"no-div-regex\": 1,\n    \"no-dupe-args\": 2,\n    \"no-dupe-keys\": 2,\n    \"no-duplicate-case\": 2,\n    \"no-else-return\": 1,\n    \"no-empty-character-class\": 2,\n    \"no-eval\": 2,\n    \"no-ex-assign\": 2,\n    \"no-extend-native\": 2,\n    \"no-extra-boolean-cast\": 2,\n    \"no-extra-parens\": 1,\n    \"no-extra-semi\": 2,\n    \"no-fallthrough\": 2,\n    \"no-floating-decimal\": 2,\n    \"no-func-assign\": 2,\n    \"no-implied-eval\": 2,\n    \"no-inner-declarations\": 2,\n    \"no-irregular-whitespace\": 2,\n    \"no-label-var\": 2,\n    \"no-labels\": 2,\n    \"no-lone-blocks\": 2,\n    \"no-lonely-if\": 2,\n    \"no-multi-str\": 2,\n    \"no-native-reassign\": 2,\n    \"no-negated-in-lhs\": 1,\n    \"no-new-object\": 2,\n    \"no-new-wrappers\": 2,\n    \"no-obj-calls\": 2,\n    \"no-octal\": 2,\n    \"no-octal-escape\": 2,\n    \"no-proto\": 2,\n    \"no-redeclare\": 2,\n    \"no-shadow\": 2,\n    \"no-spaced-func\": 2,\n    \"no-throw-literal\": 2,\n    \"no-trailing-spaces\": 2,\n    \"no-undef\": 2,\n    \"no-undef-init\": 2,\n    \"no-undefined\": 2,\n    \"no-unneeded-ternary\": 2,\n    \"no-unreachable\": 2,\n    \"no-unused-expressions\": [2, {\"allowTernary\": true, \"allowShortCircuit\": true}],\n    \"no-with\": 2,\n    \"object-curly-spacing\": [2, \"never\"],\n    \"quote-props\": [1, \"consistent-as-needed\", {\"keywords\": true}],\n    \"quotes\": [2, \"single\", \"avoid-escape\"],\n    \"radix\": 2,\n    \"semi\": 2,\n    \"space-before-function-paren\": [2, {\"anonymous\": \"never\", \"named\": \"never\"}],\n    \"space-infix-ops\": 2,\n    \"space-unary-ops\": [2, { \"words\": true, \"nonwords\": false }],\n    \"use-isnan\": 2,\n    \"valid-typeof\": 2,\n    \"wrap-iife\": [2, \"inside\"]\n  }\n}\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "tidelift: \"npm/backbone\"\npatreon: juliangonggrijp\ngithub: [jgonggrijp]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Bugs.yml",
    "content": "name: Bug report\ndescription: |\n  Report something that is not working correctly.\n  Not intended for security issues!\ntitle: Foo.bar should bazoonite, but frobulates instead\nbody:\n  - type: markdown\n    attributes:\n      value: \"\n        Thank you for taking the effort to report a bug.\\n\\n\n\n        Is your bug a security issue? In that case, **please do not use this\n        form!** Instead, see the [security\n        policy](https://github.com/jashkenas/backbone/security/policy) on how to\n        report the issue.\\n\\n\n\n        ## Identification\\n\\n\n\n        To start, some quick questions to pinpoint the issue.\"\n  - type: input\n    id: component\n    attributes:\n      label: Affected component\n      description: >\n        Which part of Backbone is affected? Please be as specific as possible,\n        for example &ldquo;the silent option of Collection.reset&rdquo; or\n        &ldquo;importing Backbone with require.js&rdquo;.\n      placeholder: the sync event triggered after Model.fetch\n    validations:\n      required: true\n  - type: input\n    id: expected\n    attributes:\n      label: Expected behavior\n      description: |\n        In one sentence, what *should* the affected component do?\n      placeholder: |\n        Forward all options passed to Model.fetch to the event handler\n    validations:\n      required: true\n  - type: input\n    id: actual\n    attributes:\n      label: Actual behavior\n      description: |\n        In one sentence, what does the affected component *actually* do?\n      placeholder: |\n        Forward options to the method called last, e.g. save.\n    validations:\n      required: true\n  - type: markdown\n    attributes:\n      value: \"\n        After filling the above three fields, please review the issue title. It\n        should be short, including elements of all three fields and not much\n        else.\\n\\n\n\n        For example: **After Model.fetch, sync event may include\n        options of a later sync, save or destroy call**\\n\\n\n\n        ## Context\"\n  - type: textarea\n    id: docs\n    attributes:\n      label: Relevant documentation\n      description: |\n        Which documentation, if any, did you base your above expectation on?\n        Provide one link per line.\n      placeholder: |\n        - https://backbonejs.org/#Model-fetch\n        - https://backbonejs.org/#Events-catalog\n  - type: textarea\n    id: stack\n    attributes:\n      label: Software stack\n      description: \"\n        With which version(s) of Backbone, Underscore/Lodash, jQuery/Zepto,\n        other relevant libraries or tools, your browser, etcetera, did you\n        experience this problem? Please list one per line, including name,\n        version number(s) and variant(s) if applicable.\\n\\n\n\n        **Tip:** if you are using the bleeding-edge version of\n        Backbone, much of this information can be obtained by using\n        [debugInfo](https://backbonejs.org/#Utility-Backbone-debugInfo)\n        and copy-pasting its console output below.\"\n      placeholder: \"\n        - Backbone 1.4.1 and latest `master` (commit fcf5df6)\\n\n        - Underscore 1.13.6\\n\n        - jQuery 3.6.3 (slim build)\\n\n        - Marionette 4.1.2\\n\n        - Firefox 100\\n\n        - Node.js 14.6\\n\n\n        OR (stretch form field to see example content):\\n\n\n        ```json\\n\n        Backbone debug info:  {\\n\n        \\ \\ \\\"backbone\\\": \\\"1.5.0\\\",\\n\n        \\ \\ \\\"distribution\\\": \\\"MARK_DEVELOPMENT\\\",\\n\n        \\ \\ \\\"_\\\": \\\"lodash 4.17.21\\\",\\n\n        \\ \\ \\\"$\\\": \\\"3.6.0\\\",\\n\n        \\ \\ \\\"navigator\\\": {\\n\n        \\ \\ \\ \\ \\\"userAgent\\\": \\\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0\\\",\\n\n        \\ \\ \\ \\ \\\"platform\\\": \\\"MacIntel\\\",\\n\n        \\ \\ \\ \\ \\\"webdriver\\\": false\\n\n        \\ \\ }\\n\n        }\\n\n        ```\\n\n\n        - Backbone `master` checked out on August 10, 2023\\n\n        - Marionette 4.1.2\"\n    validations:\n      required: true\n  - type: textarea\n    id: discourse\n    attributes:\n      label: Related issues, prior discussion and CCs\n      description: >\n        Please list any issue numbers, pull requests or links to discussions\n        elsewhere on the internet that may be relevant. You can also attract the\n        attention of other GitHub users by listing their `@handles` here.\n      placeholder: \"\n        #4229, #3410\\n\n        a Stack Overflow or Matrix link\\n\n        @jgonggrijp\"\n  - type: markdown\n    attributes:\n      value: \"## Bug details\"\n  - type: input\n    id: error\n    attributes:\n      label: Error\n      description: >\n        If possible, name the error that you observed and that anyone trying to\n        reproduce the bug should look for.\n      placeholder: TypeError (options.success is not an object)\n  - type: textarea\n    id: repro\n    attributes:\n      label: Steps to reproduce\n      description: >\n        List the minimal steps needed to make the bug happen. Include code\n        examples as needed.\n    validations:\n      required: true\n  - type: textarea\n    id: details\n    attributes:\n      label: Additional information\n      description: >-\n        This is a free-form field where you can add any further details that may\n        help to understand the bug. For example, you might provide permalinks to\n        the affected lines of code in your actual project, attach logs or\n        screenshots, point out things you noticed while debugging, and explain\n        why the bug is especially problematic for your use case.\n  - type: markdown\n    attributes:\n      value: \"## Closing\"\n  - type: textarea\n    id: solution\n    attributes:\n      label: Suggested solution(s)\n      description: >\n        If you have any idea on how the problem could (or should) be solved,\n        please feel welcome to describe it here. Of course, if your idea is very\n        concrete, you may as well submit a pull request!\n  - type: textarea\n    id: remarks\n    attributes:\n      label: Other remarks\n      description: >-\n        If there is anything else you would like to say about the issue, you can\n        do so here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Documentation.yml",
    "content": "name: Documentation issue\ndescription: >-\n  Report information that is missing, incomplete, vague, misleading or plain\n  wrong in online documentation such as the website, the README, the wiki,\n  etcetera.\nbody:\n  - type: markdown\n    attributes:\n      value: >-\n        Thank you for taking the time to help us improve the documentation.\n  - type: input\n    id: reference\n    attributes:\n      label: Reference to current documentation\n      description: >-\n        If you can identify an existing piece of documentation that is lacking,\n        please provide a URL (or multiple) below. If your report is about\n        missing information and there is no single obvious place where it should\n        be added, you can leave this empty.\n      placeholder: \"https://backbonejs.org/#Model-changedAttributes\"\n  - type: textarea\n    id: quote\n    attributes:\n      label: Quote of current documentation\n      description: >-\n        If you provided a URL in the previous field, please quote the\n        problematic documentation below. This ensures that future readers\n        understand what you were responding to, in case the referred page\n        disappears or changes content.\n      placeholder: \"\n        > Retrieve a hash of only the model's attributes that have changed since\n        the last\n        [set](https://backbonejs.org/#Model-set), or `false` if there are none.\n        Optionally, an external **attributes** hash can be passed in, returning\n        the attributes in that hash which differ from the model. This can be\n        used to figure out which portions of a view should be updated, or what\n        calls need to be made to sync the changes to the server.\"\n  - type: textarea\n    id: effect\n    attributes:\n      label: Effect of the problem\n      description: >-\n        What did you or someone else not know, misunderstand or falsely believe\n        due to the current state of the documentation? How has this misguided\n        your or someone else's behavior?\n      placeholder: >-\n        I did not know that I could ..., so I needlessly ...\n    validations:\n      required: true\n  - type: textarea\n    id: cause\n    attributes:\n      label: Cause of the problem\n      description: >-\n        What is it about the current documentation that caused your problem?\n        What is missing, ambiguous or wrong? Pinpoint specific words or phrases\n        if possible.\n      placeholder: >-\n        It says \"...\", which seems to suggest that ..., while actually, ...\n    validations:\n      required: true\n  - type: textarea\n    id: suggestion\n    attributes:\n      label: Suggestion\n      description: >-\n        If you have any idea on how the documentation could be improved, please\n        share it here. Of course, if your idea is very concrete, you can also\n        submit a pull request!\n  - type: textarea\n    id: remarks\n    attributes:\n      label: Other remarks\n      description: >-\n        If there is anything else you would like to say about the issue, you can\n        do so here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Features.yml",
    "content": "name: Feature request\ndescription: >-\n  Tell us about functionality that you miss in Backbone.\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thank you for proposing a new feature.\n\n        Let us begin with the end in mind.\n  - type: textarea\n    id: goal\n    attributes:\n      label: Ultimate goal\n      description: >-\n        This first question is not about Backbone but about the mission that you\n        hope to accomplish with Backbone. What work do you need to get done?\n      placeholder: |\n        GOOD: I work on an application that needs to ...\n        BAD (later question): I think Backbone.Collection should have a method that ...\n    validations:\n      required: true\n  - type: textarea\n    id: shortcoming\n    attributes:\n      label: Shortcomings\n      description: >-\n        Working towards your end goal, what task is currently difficult to\n        achieve with Backbone as it is? Which features in Backbone or other\n        libraries are currently available to you, which do not quite do what you\n        need?\n      placeholder: |\n        In my application, I need to ..., but when I define a\n        Backbone.Collection subclass, there does not seem to be any way to ...\n\n        - I could use `Collection.slice`, but ...\n        - I could use <some other library>, but ...\n    validations:\n      required: true\n  - type: textarea\n    id: justification\n    attributes:\n      label: Justification\n      description: >-\n        Why do you believe that the missing functionality belongs in Backbone\n        proper? Why could or should it not be provided by another library or\n        tool?\n    validations:\n      required: true\n  - type: textarea\n    id: proposal\n    attributes:\n      label: Proposal\n      description: >-\n        Go ahead, describe your ideal solution. Show what it should look like\n        and explain how it should behave.\n    validations:\n      required: true\n  - type: textarea\n    id: alternatives\n    attributes:\n      label: Possible alternatives\n      description: >-\n        Can you think of other ways in which your desired functionality could be\n        provided? If they appeal less to you, why is this the case?\n  - type: textarea\n    id: remarks\n    attributes:\n      label: Other remarks\n      description: >-\n        If there is anything else you would like to say about your feature\n        request, you can do so here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "contact_links:\n  - name: Security issue\n    url: https://github.com/jashkenas/backbone/security/policy\n    about: Go here if you would like to report a security issue.\n  - name: Stack Overflow\n    url: https://stackoverflow.com/questions/tagged/backbone.js\n    about: The best place to get help making your code work (be sure to include the `backbone.js` tag).\n  - name: Matrix/Gitter\n    url: https://matrix.to/#/#jashkenas_backbone:gitter.im\n    about: Discussions about, and general help with, Backbone.\n"
  },
  {
    "path": ".github/workflows/tests.yml",
    "content": "name: Test\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n    paths:\n      - '.github/workflows/**'\n      - 'test/**'\n      - '*.js'\n      - 'package.json'\n\njobs:\n  tests:\n    env:\n      NPM_CONFIG_PROGRESS: \"false\"\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 16\n          cache: 'npm'\n      - name: Install dependencies\n        run: |\n          npm ci\n          npm install --no-audit karma-cli karma-sauce-launcher\n      - name: Test in Sauce Labs\n        run: BUILD_NUMBER=\"$GITHUB_RUN_NUMBER\" BUILD_ID=\"$GITHUB_RUN_ID\" JOB_NUMBER=\"$GITHUB_JOB\" ./node_modules/.bin/karma start karma.conf-sauce.js\n        env:\n          SAUCE_USERNAME: ${{ secrets.SauceUsername }}\n          SAUCE_ACCESS_KEY: ${{ secrets.SauceAccessKey }}\n"
  },
  {
    "path": ".gitignore",
    "content": "raw\n*.sw?\n.DS_Store\nnode_modules\nbower_components\n"
  },
  {
    "path": "CNAME",
    "content": "backbonejs.org"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, caste, color, religion, or sexual\nidentity and orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the overall\n  community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery and sexual attention or advances of\n  any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email address,\n  without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\njashkenas@gmail.com.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series of\nactions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or permanent\nban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior, harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within the\ncommunity.\n\n## Moderation\n\nEdits of another user's comment must be clearly marked with \"**edit**\", the\nmoderator's username, and a timestamp for each occurrence. The only acceptable\nreasons for editing another user's comment are:\n\n1. to edit out violations of Our Pledge. These edits must include a rationale.\n2. to direct future readers to a relevant point later in the conversation\n   (usually the resolution). These edits must be append-only.\n\nDeletion of another user's comment is only acceptable when the comment includes\nno original value, such as \"+1\", \":+1:\", or \"me too\".\n\n## Self-Moderation\n\nEdits of your own comment after someone has responded must be append-only and\nclearly marked with \"**edit**\". Typographical and formatting fixes to your own\ncomment which do not affect its meaning are exempt from this requirement.\nDeletion of your own comment is only acceptable before any later comments have\nbeen posted.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.1, available at\n[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].\n\nCommunity Impact Guidelines were inspired by\n[Mozilla's code of conduct enforcement ladder][Mozilla CoC].\n\nFor answers to common questions about this code of conduct, see the FAQ at\n[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at\n[https://www.contributor-covenant.org/translations][translations].\n\n[homepage]: https://www.contributor-covenant.org\n[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html\n[Mozilla CoC]: https://github.com/mozilla/diversity\n[FAQ]: https://www.contributor-covenant.org/faq\n[translations]: https://www.contributor-covenant.org/translations\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## How to Open a Backbone.js Ticket\n\n* Do not use tickets to ask for help with (debugging) your application. Ask on\nthe [mailing list](https://groups.google.com/forum/#!forum/backbonejs),\nin the IRC channel (`#documentcloud` on Freenode), or if you understand your\nspecific problem, on [StackOverflow](http://stackoverflow.com/questions/tagged/backbone.js).\n\n* Before you open a ticket or send a pull request,\n[search](https://github.com/jashkenas/backbone/issues) for previous\ndiscussions about the same feature or issue. Add to the earlier ticket if you\nfind one.\n\n* Before sending a pull request for a feature or bug fix, be sure to have\n[tests](http://backbonejs.org/test/) and to document any new functionality in\nthe `index.html`.\n\n* Use the same coding style as the rest of the\n[codebase](https://github.com/jashkenas/backbone/blob/master/backbone.js).\n\n* In your pull request, do not regenerate the annotated sources or rebuild the\nminified `backbone-min.js` file. We'll do that before cutting a new release.\n\n* All pull requests should be made to the `master` branch.\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2010-2024 Jeremy Ashkenas, DocumentCloud\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "     ____                     __      __\n    /\\  _`\\                  /\\ \\    /\\ \\                                   __\n    \\ \\ \\ \\ \\     __      ___\\ \\ \\/'\\\\ \\ \\____    ___     ___      __      /\\_\\    ____\n     \\ \\  _ <'  /'__`\\   /'___\\ \\ , < \\ \\ '__`\\  / __`\\ /' _ `\\  /'__`\\    \\/\\ \\  /',__\\\n      \\ \\ \\ \\ \\/\\ \\ \\.\\_/\\ \\__/\\ \\ \\\\`\\\\ \\ \\ \\ \\/\\ \\ \\ \\/\\ \\/\\ \\/\\  __/  __ \\ \\ \\/\\__, `\\\n       \\ \\____/\\ \\__/.\\_\\ \\____\\\\ \\_\\ \\_\\ \\_,__/\\ \\____/\\ \\_\\ \\_\\ \\____\\/\\_\\_\\ \\ \\/\\____/\n        \\/___/  \\/__/\\/_/\\/____/ \\/_/\\/_/\\/___/  \\/___/  \\/_/\\/_/\\/____/\\/_/\\ \\_\\ \\/___/\n                                                                           \\ \\____/\n                                                                            \\/___/\n    (_'_______________________________________________________________________________'_)\n    (_.———————————————————————————————————————————————————————————————————————————————._)\n\n\nBackbone supplies structure to JavaScript-heavy applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface.\n\nFor Docs, License, Tests, pre-packed downloads, and everything else, really, see:\nhttps://backbonejs.org\n\nTo suggest a feature or report a bug:\nhttps://github.com/jashkenas/backbone/issues\n\nFor questions on working with Backbone or general discussions:\n[security policy](SECURITY.md),\nhttps://stackoverflow.com/questions/tagged/backbone.js,\nhttps://matrix.to/#/#jashkenas_backbone:gitter.im or\nhttps://groups.google.com/g/backbonejs\n\nBackbone is an open-sourced component of DocumentCloud:\nhttps://github.com/documentcloud\n\nTesting powered by SauceLabs:\nhttps://saucelabs.com\n\nMany thanks to our contributors:\nhttps://github.com/jashkenas/backbone/graphs/contributors\n\nSpecial thanks to Robert Kieffer for the original philosophy behind Backbone.\nhttps://github.com/broofa\n\nThis project adheres to a [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nWe currently support the following versions of Backbone with security updates:\n\n- the latest commit on the `master` branch (published as \"edge\" on the\n  [project website][website]);\n- the 1.x release tagged as [latest][npm-latest] on npm;\n- any release tagged as [preview][npm-preview] on npm, if present.\n\n[website]: https://backbonejs.org\n[npm-latest]: https://www.npmjs.com/package/backbone/v/latest\n[npm-preview]: https://www.npmjs.com/package/backbone/v/preview\n\n## Reporting a Vulnerability\n\nPlease report security issues by sending an email to\ndev@juliangonggrijp.com and jashkenas@gmail.com.\n\nDo __not__ submit an issue ticket or pull request or otherwise publicly\ndisclose the issue.\n\nAfter receiving your email, we will respond as soon as possible and indicate\nwhat we plan to do.\n\n## Disclosure policy\n\nAfter confirming a vulnerability, we will generally release a security update\nas soon as possible, including the minimum amount of information required for\nsoftware maintainers and system administrators to assess the urgency of the\nupdate for their particular situation.\n\nWe postpone the publication of any further details such as code comments,\ntests, commit history and diffs, in order to enable a substantial share of the\nusers to install the security fix before this time.\n\nUpon publication of full details, we will credit the reporter if the reporter wishes to be publicly identified.\n"
  },
  {
    "path": "backbone-min.js",
    "content": "(function(r){var n=typeof self==\"object\"&&self.self===self&&self||typeof global==\"object\"&&global.global===global&&global;if(typeof define===\"function\"&&define.amd){define([\"underscore\",\"jquery\",\"exports\"],function(t,e,i){n.Backbone=r(n,i,t,e)})}else if(typeof exports!==\"undefined\"){var t=require(\"underscore\"),e;try{e=require(\"jquery\")}catch(t){}r(n,exports,t,e)}else{n.Backbone=r(n,{},n._,n.jQuery||n.Zepto||n.ender||n.$)}})(function(t,h,x,e){var i=t.Backbone;var a=Array.prototype.slice;h.VERSION=\"1.6.1\";h.$=e;h.noConflict=function(){t.Backbone=i;return this};h.emulateHTTP=false;h.emulateJSON=false;var r=h.Events={};var o=/\\s+/;var l;var u=function(t,e,i,r,n){var s=0,a;if(i&&typeof i===\"object\"){if(r!==void 0&&\"context\"in n&&n.context===void 0)n.context=r;for(a=x.keys(i);s<a.length;s++){e=u(t,e,a[s],i[a[s]],n)}}else if(i&&o.test(i)){for(a=i.split(o);s<a.length;s++){e=t(e,a[s],r,n)}}else{e=t(e,i,r,n)}return e};r.on=function(t,e,i){this._events=u(n,this._events||{},t,e,{context:i,ctx:this,listening:l});if(l){var r=this._listeners||(this._listeners={});r[l.id]=l;l.interop=false}return this};r.listenTo=function(t,e,i){if(!t)return this;var r=t._listenId||(t._listenId=x.uniqueId(\"l\"));var n=this._listeningTo||(this._listeningTo={});var s=l=n[r];if(!s){this._listenId||(this._listenId=x.uniqueId(\"l\"));s=l=n[r]=new p(this,t)}var a=c(t,e,i,this);l=void 0;if(a)throw a;if(s.interop)s.on(e,i);return this};var n=function(t,e,i,r){if(i){var n=t[e]||(t[e]=[]);var s=r.context,a=r.ctx,o=r.listening;if(o)o.count++;n.push({callback:i,context:s,ctx:s||a,listening:o})}return t};var c=function(t,e,i,r){try{t.on(e,i,r)}catch(t){return t}};r.off=function(t,e,i){if(!this._events)return this;this._events=u(s,this._events,t,e,{context:i,listeners:this._listeners});return this};r.stopListening=function(t,e,i){var r=this._listeningTo;if(!r)return this;var n=t?[t._listenId]:x.keys(r);for(var s=0;s<n.length;s++){var a=r[n[s]];if(!a)break;a.obj.off(e,i,this);if(a.interop)a.off(e,i)}if(x.isEmpty(r))this._listeningTo=void 0;return this};var s=function(t,e,i,r){if(!t)return;var n=r.context,s=r.listeners;var a=0,o;if(!e&&!n&&!i){for(o=x.keys(s);a<o.length;a++){s[o[a]].cleanup()}return}o=e?[e]:x.keys(t);for(;a<o.length;a++){e=o[a];var h=t[e];if(!h)break;var l=[];for(var u=0;u<h.length;u++){var c=h[u];if(i&&i!==c.callback&&i!==c.callback._callback||n&&n!==c.context){l.push(c)}else{var f=c.listening;if(f)f.off(e,i)}}if(l.length){t[e]=l}else{delete t[e]}}return t};r.once=function(t,e,i){var r=u(f,{},t,e,this.off.bind(this));if(typeof t===\"string\"&&i==null)e=void 0;return this.on(r,e,i)};r.listenToOnce=function(t,e,i){var r=u(f,{},e,i,this.stopListening.bind(this,t));return this.listenTo(t,r)};var f=function(t,e,i,r){if(i){var n=t[e]=x.once(function(){r(e,n);i.apply(this,arguments)});n._callback=i}return t};r.trigger=function(t){if(!this._events)return this;var e=Math.max(0,arguments.length-1);var i=Array(e);for(var r=0;r<e;r++)i[r]=arguments[r+1];u(d,this._events,t,void 0,i);return this};var d=function(t,e,i,r){if(t){var n=t[e];var s=t.all;if(n&&s)s=s.slice();if(n)v(n,r);if(s)v(s,[e].concat(r))}return t};var v=function(t,e){var i,r=-1,n=t.length,s=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<n)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<n)(i=t[r]).callback.call(i.ctx,s);return;case 2:while(++r<n)(i=t[r]).callback.call(i.ctx,s,a);return;case 3:while(++r<n)(i=t[r]).callback.call(i.ctx,s,a,o);return;default:while(++r<n)(i=t[r]).callback.apply(i.ctx,e);return}};var p=function(t,e){this.id=t._listenId;this.listener=t;this.obj=e;this.interop=true;this.count=0;this._events=void 0};p.prototype.on=r.on;p.prototype.off=function(t,e){var i;if(this.interop){this._events=u(s,this._events,t,e,{context:void 0,listeners:void 0});i=!this._events}else{this.count--;i=this.count===0}if(i)this.cleanup()};p.prototype.cleanup=function(){delete this.listener._listeningTo[this.obj._listenId];if(!this.interop)delete this.obj._listeners[this.id]};r.bind=r.on;r.unbind=r.off;x.extend(h,r);var g=h.Model=function(t,e){var i=t||{};e||(e={});this.preinitialize.apply(this,arguments);this.cid=x.uniqueId(this.cidPrefix);this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)i=this.parse(i,e)||{};var r=x.result(this,\"defaults\");i=x.defaults(x.extend({},r,i),r);this.set(i,e);this.changed={};this.initialize.apply(this,arguments)};x.extend(g.prototype,r,{changed:null,validationError:null,idAttribute:\"id\",cidPrefix:\"c\",preinitialize:function(){},initialize:function(){},toJSON:function(t){return x.clone(this.attributes)},sync:function(){return h.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return x.escape(this.get(t))},has:function(t){return this.get(t)!=null},matches:function(t){return!!x.iteratee(t,this)(this.attributes)},set:function(t,e,i){if(t==null)return this;var r;if(typeof t===\"object\"){r=t;i=e}else{(r={})[t]=e}i||(i={});if(!this._validate(r,i))return false;var n=i.unset;var s=i.silent;var a=[];var o=this._changing;this._changing=true;if(!o){this._previousAttributes=x.clone(this.attributes);this.changed={}}var h=this.attributes;var l=this.changed;var u=this._previousAttributes;for(var c in r){e=r[c];if(!x.isEqual(h[c],e))a.push(c);if(!x.isEqual(u[c],e)){l[c]=e}else{delete l[c]}n?delete h[c]:h[c]=e}if(this.idAttribute in r){var f=this.id;this.id=this.get(this.idAttribute);if(this.id!==f){this.trigger(\"changeId\",this,f,i)}}if(!s){if(a.length)this._pending=i;for(var d=0;d<a.length;d++){this.trigger(\"change:\"+a[d],this,h[a[d]],i)}}if(o)return this;if(!s){while(this._pending){i=this._pending;this._pending=false;this.trigger(\"change\",this,i)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,x.extend({},e,{unset:true}))},clear:function(t){var e={};for(var i in this.attributes)e[i]=void 0;return this.set(e,x.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!x.isEmpty(this.changed);return x.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?x.clone(this.changed):false;var e=this._changing?this._previousAttributes:this.attributes;var i={};var r;for(var n in t){var s=t[n];if(x.isEqual(e[n],s))continue;i[n]=s;r=true}return r?i:false},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return x.clone(this._previousAttributes)},fetch:function(i){i=x.extend({parse:true},i);var r=this;var n=i.success;i.success=function(t){var e=i.parse?r.parse(t,i):t;if(!r.set(e,i))return false;if(n)n.call(i.context,r,t,i);r.trigger(\"sync\",r,t,i)};G(this,i);return this.sync(\"read\",this,i)},save:function(t,e,i){var r;if(t==null||typeof t===\"object\"){r=t;i=e}else{(r={})[t]=e}i=x.extend({validate:true,parse:true},i);var n=i.wait;if(r&&!n){if(!this.set(r,i))return false}else if(!this._validate(r,i)){return false}var s=this;var a=i.success;var o=this.attributes;i.success=function(t){s.attributes=o;var e=i.parse?s.parse(t,i):t;if(n)e=x.extend({},r,e);if(e&&!s.set(e,i))return false;if(a)a.call(i.context,s,t,i);s.trigger(\"sync\",s,t,i)};G(this,i);if(r&&n)this.attributes=x.extend({},o,r);var h=this.isNew()?\"create\":i.patch?\"patch\":\"update\";if(h===\"patch\"&&!i.attrs)i.attrs=r;var l=this.sync(h,this,i);this.attributes=o;return l},destroy:function(e){e=e?x.clone(e):{};var i=this;var r=e.success;var n=e.wait;var s=function(){i.stopListening();i.trigger(\"destroy\",i,i.collection,e)};e.success=function(t){if(n)s();if(r)r.call(e.context,i,t,e);if(!i.isNew())i.trigger(\"sync\",i,t,e)};var t=false;if(this.isNew()){x.defer(e.success)}else{G(this,e);t=this.sync(\"delete\",this,e)}if(!n)s();return t},url:function(){var t=x.result(this,\"urlRoot\")||x.result(this.collection,\"url\")||V();if(this.isNew())return t;var e=this.get(this.idAttribute);return t.replace(/[^\\/]$/,\"$&/\")+encodeURIComponent(e)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},x.extend({},t,{validate:true}))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=x.extend({},this.attributes,t);var i=this.validationError=this.validate(t,e)||null;if(!i)return true;this.trigger(\"invalid\",this,i,x.extend(e,{validationError:i}));return false}});var m=h.Collection=function(t,e){e||(e={});this.preinitialize.apply(this,arguments);if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,x.extend({silent:true},e))};var w={add:true,remove:true,merge:true};var _={add:true,remove:false};var E=function(t,e,i){i=Math.min(Math.max(i,0),t.length);var r=Array(t.length-i);var n=e.length;var s;for(s=0;s<r.length;s++)r[s]=t[s+i];for(s=0;s<n;s++)t[s+i]=e[s];for(s=0;s<r.length;s++)t[s+n+i]=r[s]};x.extend(m.prototype,r,{model:g,preinitialize:function(){},initialize:function(){},toJSON:function(e){return this.map(function(t){return t.toJSON(e)})},sync:function(){return h.sync.apply(this,arguments)},add:function(t,e){return this.set(t,x.extend({merge:false},e,_))},remove:function(t,e){e=x.extend({},e);var i=!x.isArray(t);t=i?[t]:t.slice();var r=this._removeModels(t,e);if(!e.silent&&r.length){e.changes={added:[],merged:[],removed:r};this.trigger(\"update\",this,e)}return i?r[0]:r},set:function(t,e){if(t==null)return;e=x.extend({},w,e);if(e.parse&&!this._isModel(t)){t=this.parse(t,e)||[]}var i=!x.isArray(t);t=i?[t]:t.slice();var r=e.at;if(r!=null)r=+r;if(r>this.length)r=this.length;if(r<0)r+=this.length+1;var n=[];var s=[];var a=[];var o=[];var h={};var l=e.add;var u=e.merge;var c=e.remove;var f=false;var d=this.comparator&&r==null&&e.sort!==false;var v=x.isString(this.comparator)?this.comparator:null;var p,g;for(g=0;g<t.length;g++){p=t[g];var m=this.get(p);if(m){if(u&&p!==m){var _=this._isModel(p)?p.attributes:p;if(e.parse)_=m.parse(_,e);m.set(_,e);a.push(m);if(d&&!f)f=m.hasChanged(v)}if(!h[m.cid]){h[m.cid]=true;n.push(m)}t[g]=m}else if(l){p=t[g]=this._prepareModel(p,e);if(p){s.push(p);this._addReference(p,e);h[p.cid]=true;n.push(p)}}}if(c){for(g=0;g<this.length;g++){p=this.models[g];if(!h[p.cid])o.push(p)}if(o.length)this._removeModels(o,e)}var y=false;var b=!d&&l&&c;if(n.length&&b){y=this.length!==n.length||x.some(this.models,function(t,e){return t!==n[e]});this.models.length=0;E(this.models,n,0);this.length=this.models.length}else if(s.length){if(d)f=true;E(this.models,s,r==null?this.length:r);this.length=this.models.length}if(f)this.sort({silent:true});if(!e.silent){for(g=0;g<s.length;g++){if(r!=null)e.index=r+g;p=s[g];p.trigger(\"add\",p,this,e)}if(f||y)this.trigger(\"sort\",this,e);if(s.length||o.length||a.length){e.changes={added:s,removed:o,merged:a};this.trigger(\"update\",this,e)}}return i?t[0]:t},reset:function(t,e){e=e?x.clone(e):{};for(var i=0;i<this.models.length;i++){this._removeReference(this.models[i],e)}e.previousModels=this.models;this._reset();t=this.add(t,x.extend({silent:true},e));if(!e.silent)this.trigger(\"reset\",this,e);return t},push:function(t,e){return this.add(t,x.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);return this.remove(e,t)},unshift:function(t,e){return this.add(t,x.extend({at:0},e))},shift:function(t){var e=this.at(0);return this.remove(e,t)},slice:function(){return a.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;return this._byId[t]||this._byId[this.modelId(this._isModel(t)?t.attributes:t,t.idAttribute)]||t.cid&&this._byId[t.cid]},has:function(t){return this.get(t)!=null},at:function(t){if(t<0)t+=this.length;return this.models[t]},where:function(t,e){return this[e?\"find\":\"filter\"](t)},findWhere:function(t){return this.where(t,true)},sort:function(t){var e=this.comparator;if(!e)throw new Error(\"Cannot sort a set without a comparator\");t||(t={});var i=e.length;if(x.isFunction(e))e=e.bind(this);if(i===1||x.isString(e)){this.models=this.sortBy(e)}else{this.models.sort(e)}if(!t.silent)this.trigger(\"sort\",this,t);return this},pluck:function(t){return this.map(t+\"\")},fetch:function(i){i=x.extend({parse:true},i);var r=i.success;var n=this;i.success=function(t){var e=i.reset?\"reset\":\"set\";n[e](t,i);if(r)r.call(i.context,n,t,i);n.trigger(\"sync\",n,t,i)};G(this,i);return this.sync(\"read\",this,i)},create:function(t,e){e=e?x.clone(e):{};var r=e.wait;t=this._prepareModel(t,e);if(!t)return false;if(!r)this.add(t,e);var n=this;var s=e.success;e.success=function(t,e,i){if(r){t.off(\"error\",n._forwardPristineError,n);n.add(t,i)}if(s)s.call(i.context,t,e,i)};if(r){t.once(\"error\",this._forwardPristineError,this)}t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models,{model:this.model,comparator:this.comparator})},modelId:function(t,e){return t[e||this.model.prototype.idAttribute||\"id\"]},values:function(){return new b(this,S)},keys:function(){return new b(this,I)},entries:function(){return new b(this,k)},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(this._isModel(t)){if(!t.collection)t.collection=this;return t}e=e?x.clone(e):{};e.collection=this;var i;if(this.model.prototype){i=new this.model(t,e)}else{i=this.model(t,e)}if(!i.validationError)return i;this.trigger(\"invalid\",this,i.validationError,e);return false},_removeModels:function(t,e){var i=[];for(var r=0;r<t.length;r++){var n=this.get(t[r]);if(!n)continue;var s=this.indexOf(n);this.models.splice(s,1);this.length--;delete this._byId[n.cid];var a=this.modelId(n.attributes,n.idAttribute);if(a!=null)delete this._byId[a];if(!e.silent){e.index=s;n.trigger(\"remove\",n,this,e)}i.push(n);this._removeReference(n,e)}if(t.length>0&&!e.silent)delete e.index;return i},_isModel:function(t){return t instanceof g},_addReference:function(t,e){this._byId[t.cid]=t;var i=this.modelId(t.attributes,t.idAttribute);if(i!=null)this._byId[i]=t;t.on(\"all\",this._onModelEvent,this)},_removeReference:function(t,e){delete this._byId[t.cid];var i=this.modelId(t.attributes,t.idAttribute);if(i!=null)delete this._byId[i];if(this===t.collection)delete t.collection;t.off(\"all\",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if(e){if((t===\"add\"||t===\"remove\")&&i!==this)return;if(t===\"destroy\")this.remove(e,r);if(t===\"changeId\"){var n=this.modelId(e.previousAttributes(),e.idAttribute);var s=this.modelId(e.attributes,e.idAttribute);if(n!=null)delete this._byId[n];if(s!=null)this._byId[s]=e}}this.trigger.apply(this,arguments)},_forwardPristineError:function(t,e,i){if(this.has(t))return;this._onModelEvent(\"error\",t,e,i)}});var y=typeof Symbol===\"function\"&&Symbol.iterator;if(y){m.prototype[y]=m.prototype.values}var b=function(t,e){this._collection=t;this._kind=e;this._index=0};var S=1;var I=2;var k=3;if(y){b.prototype[y]=function(){return this}}b.prototype.next=function(){if(this._collection){if(this._index<this._collection.length){var t=this._collection.at(this._index);this._index++;var e;if(this._kind===S){e=t}else{var i=this._collection.modelId(t.attributes,t.idAttribute);if(this._kind===I){e=i}else{e=[i,t]}}return{value:e,done:false}}this._collection=void 0}return{value:void 0,done:true}};var A=h.View=function(t){this.cid=x.uniqueId(\"view\");this.preinitialize.apply(this,arguments);x.extend(this,x.pick(t,T));this._ensureElement();this.initialize.apply(this,arguments)};var P=/^(\\S+)\\s*(.*)$/;var T=[\"model\",\"collection\",\"el\",\"id\",\"attributes\",\"className\",\"tagName\",\"events\"];x.extend(A.prototype,r,{tagName:\"div\",$:function(t){return this.$el.find(t)},preinitialize:function(){},initialize:function(){},render:function(){return this},remove:function(){this._removeElement();this.stopListening();return this},_removeElement:function(){this.$el.remove()},setElement:function(t){this.undelegateEvents();this._setElement(t);this.delegateEvents();return this},_setElement:function(t){this.$el=t instanceof h.$?t:h.$(t);this.el=this.$el[0]},delegateEvents:function(t){t||(t=x.result(this,\"events\"));if(!t)return this;this.undelegateEvents();for(var e in t){var i=t[e];if(!x.isFunction(i))i=this[i];if(!i)continue;var r=e.match(P);this.delegate(r[1],r[2],i.bind(this))}return this},delegate:function(t,e,i){this.$el.on(t+\".delegateEvents\"+this.cid,e,i);return this},undelegateEvents:function(){if(this.$el)this.$el.off(\".delegateEvents\"+this.cid);return this},undelegate:function(t,e,i){this.$el.off(t+\".delegateEvents\"+this.cid,e,i);return this},_createElement:function(t){return document.createElement(t)},_ensureElement:function(){if(!this.el){var t=x.extend({},x.result(this,\"attributes\"));if(this.id)t.id=x.result(this,\"id\");if(this.className)t[\"class\"]=x.result(this,\"className\");this.setElement(this._createElement(x.result(this,\"tagName\")));this._setAttributes(t)}else{this.setElement(x.result(this,\"el\"))}},_setAttributes:function(t){this.$el.attr(t)}});var H=function(r,t,n,s){switch(t){case 1:return function(){return r[n](this[s])};case 2:return function(t){return r[n](this[s],t)};case 3:return function(t,e){return r[n](this[s],C(t,this),e)};case 4:return function(t,e,i){return r[n](this[s],C(t,this),e,i)};default:return function(){var t=a.call(arguments);t.unshift(this[s]);return r[n].apply(r,t)}}};var $=function(i,r,t,n){x.each(t,function(t,e){if(r[e])i.prototype[e]=H(r,t,e,n)})};var C=function(e,t){if(x.isFunction(e))return e;if(x.isObject(e)&&!t._isModel(e))return R(e);if(x.isString(e))return function(t){return t.get(e)};return e};var R=function(t){var e=x.matches(t);return function(t){return e(t.attributes)}};var M={forEach:3,each:3,map:3,collect:3,reduce:0,foldl:0,inject:0,reduceRight:0,foldr:0,find:3,detect:3,filter:3,select:3,reject:3,every:3,all:3,some:3,any:3,include:3,includes:3,contains:3,invoke:0,max:3,min:3,toArray:1,size:1,first:3,head:3,take:3,initial:3,rest:3,tail:3,drop:3,last:3,without:0,difference:0,indexOf:3,shuffle:1,lastIndexOf:3,isEmpty:1,chain:1,sample:3,partition:3,groupBy:3,countBy:3,sortBy:3,indexBy:3,findIndex:3,findLastIndex:3};var N={keys:1,values:1,pairs:1,invert:1,pick:0,omit:0,chain:1,isEmpty:1};x.each([[m,M,\"models\"],[g,N,\"attributes\"]],function(t){var i=t[0],e=t[1],r=t[2];i.mixin=function(t){var e=x.reduce(x.functions(t),function(t,e){t[e]=0;return t},{});$(i,t,e,r)};$(i,x,e,r)});h.sync=function(t,e,r){var i=j[t];x.defaults(r||(r={}),{emulateHTTP:h.emulateHTTP,emulateJSON:h.emulateJSON});var n={type:i,dataType:\"json\"};if(!r.url){n.url=x.result(e,\"url\")||V()}if(r.data==null&&e&&(t===\"create\"||t===\"update\"||t===\"patch\")){n.contentType=\"application/json\";n.data=JSON.stringify(r.attrs||e.toJSON(r))}if(r.emulateJSON){n.contentType=\"application/x-www-form-urlencoded\";n.data=n.data?{model:n.data}:{}}if(r.emulateHTTP&&(i===\"PUT\"||i===\"DELETE\"||i===\"PATCH\")){n.type=\"POST\";if(r.emulateJSON)n.data._method=i;var s=r.beforeSend;r.beforeSend=function(t){t.setRequestHeader(\"X-HTTP-Method-Override\",i);if(s)return s.apply(this,arguments)}}if(n.type!==\"GET\"&&!r.emulateJSON){n.processData=false}var a=r.error;r.error=function(t,e,i){r.textStatus=e;r.errorThrown=i;if(a)a.call(r.context,t,e,i)};var o=r.xhr=h.ajax(x.extend(n,r));e.trigger(\"request\",e,o,r);return o};var j={create:\"POST\",update:\"PUT\",patch:\"PATCH\",delete:\"DELETE\",read:\"GET\"};h.ajax=function(){return h.$.ajax.apply(h.$,arguments)};var O=h.Router=function(t){t||(t={});this.preinitialize.apply(this,arguments);if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var U=/\\((.*?)\\)/g;var z=/(\\(\\?)?:\\w+/g;var q=/\\*\\w+/g;var F=/[\\-{}\\[\\]+?.,\\\\\\^$|#\\s]/g;x.extend(O.prototype,r,{preinitialize:function(){},initialize:function(){},route:function(i,r,n){if(!x.isRegExp(i))i=this._routeToRegExp(i);if(x.isFunction(r)){n=r;r=\"\"}if(!n)n=this[r];var s=this;h.history.route(i,function(t){var e=s._extractParameters(i,t);if(s.execute(n,e,r)!==false){s.trigger.apply(s,[\"route:\"+r].concat(e));s.trigger(\"route\",r,e);h.history.trigger(\"route\",s,r,e)}});return this},execute:function(t,e,i){if(t)t.apply(this,e)},navigate:function(t,e){h.history.navigate(t,e);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=x.result(this,\"routes\");var t,e=x.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(F,\"\\\\$&\").replace(U,\"(?:$1)?\").replace(z,function(t,e){return e?t:\"([^/?]+)\"}).replace(q,\"([^?]*?)\");return new RegExp(\"^\"+t+\"(?:\\\\?([\\\\s\\\\S]*))?$\")},_extractParameters:function(t,e){var i=t.exec(e).slice(1);return x.map(i,function(t,e){if(e===i.length-1)return t||null;return t?decodeURIComponent(t):null})}});var B=h.History=function(){this.handlers=[];this.checkUrl=this.checkUrl.bind(this);if(typeof window!==\"undefined\"){this.location=window.location;this.history=window.history}};var J=/^[#\\/]|\\s+$/g;var L=/^\\/+|\\/+$/g;var W=/#.*$/;B.started=false;x.extend(B.prototype,r,{interval:50,atRoot:function(){var t=this.location.pathname.replace(/[^\\/]$/,\"$&/\");return t===this.root&&!this.getSearch()},matchRoot:function(){var t=this.decodeFragment(this.location.pathname);var e=t.slice(0,this.root.length-1)+\"/\";return e===this.root},decodeFragment:function(t){return decodeURI(t.replace(/%25/g,\"%2525\"))},getSearch:function(){var t=this.location.href.replace(/#.*/,\"\").match(/\\?.+/);return t?t[0]:\"\"},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:\"\"},getPath:function(){var t=this.decodeFragment(this.location.pathname+this.getSearch()).slice(this.root.length-1);return t.charAt(0)===\"/\"?t.slice(1):t},getFragment:function(t){if(t==null){if(this._usePushState||!this._wantsHashChange){t=this.getPath()}else{t=this.getHash()}}return t.replace(J,\"\")},start:function(t){if(B.started)throw new Error(\"Backbone.history has already been started\");B.started=true;this.options=x.extend({root:\"/\"},this.options,t);this.root=this.options.root;this._trailingSlash=this.options.trailingSlash;this._wantsHashChange=this.options.hashChange!==false;this._hasHashChange=\"onhashchange\"in window&&(document.documentMode===void 0||document.documentMode>7);this._useHashChange=this._wantsHashChange&&this._hasHashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.history&&this.history.pushState);this._usePushState=this._wantsPushState&&this._hasPushState;this.fragment=this.getFragment();this.root=(\"/\"+this.root+\"/\").replace(L,\"/\");if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){var e=this.root.slice(0,-1)||\"/\";this.location.replace(e+\"#\"+this.getPath());return true}else if(this._hasPushState&&this.atRoot()){this.navigate(this.getHash(),{replace:true})}}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){this.iframe=document.createElement(\"iframe\");this.iframe.src=\"javascript:0\";this.iframe.style.display=\"none\";this.iframe.tabIndex=-1;var i=document.body;var r=i.insertBefore(this.iframe,i.firstChild).contentWindow;r.document.open();r.document.close();r.location.hash=\"#\"+this.fragment}var n=window.addEventListener||function(t,e){return attachEvent(\"on\"+t,e)};if(this._usePushState){n(\"popstate\",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){n(\"hashchange\",this.checkUrl,false)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}if(!this.options.silent)return this.loadUrl()},stop:function(){var t=window.removeEventListener||function(t,e){return detachEvent(\"on\"+t,e)};if(this._usePushState){t(\"popstate\",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){t(\"hashchange\",this.checkUrl,false)}if(this.iframe){document.body.removeChild(this.iframe);this.iframe=null}if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);B.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getHash(this.iframe.contentWindow)}if(e===this.fragment){if(!this.matchRoot())return this.notfound();return false}if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(e){if(!this.matchRoot())return this.notfound();e=this.fragment=this.getFragment(e);return x.some(this.handlers,function(t){if(t.route.test(e)){t.callback(e);return true}})||this.notfound()},notfound:function(){this.trigger(\"notfound\");return false},navigate:function(t,e){if(!B.started)return false;if(!e||e===true)e={trigger:!!e};t=this.getFragment(t||\"\");var i=this.root;if(!this._trailingSlash&&(t===\"\"||t.charAt(0)===\"?\")){i=i.slice(0,-1)||\"/\"}var r=i+t;t=t.replace(W,\"\");var n=this.decodeFragment(t);if(this.fragment===n)return;this.fragment=n;if(this._usePushState){this.history[e.replace?\"replaceState\":\"pushState\"]({},document.title,r)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getHash(this.iframe.contentWindow)){var s=this.iframe.contentWindow;if(!e.replace){s.document.open();s.document.close()}this._updateHash(s.location,t,e.replace)}}else{return this.location.assign(r)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,\"\");t.replace(r+\"#\"+e)}else{t.hash=\"#\"+e}}});h.history=new B;var D=function(t,e){var i=this;var r;if(t&&x.has(t,\"constructor\")){r=t.constructor}else{r=function(){return i.apply(this,arguments)}}x.extend(r,i,e);r.prototype=x.create(i.prototype,t);r.prototype.constructor=r;r.__super__=i.prototype;return r};g.extend=m.extend=O.extend=A.extend=B.extend=D;var V=function(){throw new Error('A \"url\" property or function must be specified')};var G=function(e,i){var r=i.error;i.error=function(t){if(r)r.call(i.context,e,t,i);e.trigger(\"error\",e,t,i)}};h._debug=function(){return{root:t,_:x}};return h});\n//# sourceMappingURL=backbone-min.js.map"
  },
  {
    "path": "backbone.js",
    "content": "//     Backbone.js 1.6.1\n\n//     (c) 2010-2024 Jeremy Ashkenas and DocumentCloud\n//     Backbone may be freely distributed under the MIT license.\n//     For all details and documentation:\n//     http://backbonejs.org\n\n(function(factory) {\n\n  // Establish the root object, `window` (`self`) in the browser, or `global` on the server.\n  // We use `self` instead of `window` for `WebWorker` support.\n  var root = typeof self == 'object' && self.self === self && self ||\n            typeof global == 'object' && global.global === global && global;\n\n  // Set up Backbone appropriately for the environment. Start with AMD.\n  if (typeof define === 'function' && define.amd) {\n    define(['underscore', 'jquery', 'exports'], function(_, $, exports) {\n      // Export global even in AMD case in case this script is loaded with\n      // others that may still expect a global Backbone.\n      root.Backbone = factory(root, exports, _, $);\n    });\n\n  // Next for Node.js or CommonJS. jQuery may not be needed as a module.\n  } else if (typeof exports !== 'undefined') {\n    var _ = require('underscore'), $;\n    try { $ = require('jquery'); } catch (e) {}\n    factory(root, exports, _, $);\n\n  // Finally, as a browser global.\n  } else {\n    root.Backbone = factory(root, {}, root._, root.jQuery || root.Zepto || root.ender || root.$);\n  }\n\n})(function(root, Backbone, _, $) {\n\n  // Initial Setup\n  // -------------\n\n  // Save the previous value of the `Backbone` variable, so that it can be\n  // restored later on, if `noConflict` is used.\n  var previousBackbone = root.Backbone;\n\n  // Create a local reference to a common array method we'll want to use later.\n  var slice = Array.prototype.slice;\n\n  // Current version of the library. Keep in sync with `package.json`.\n  Backbone.VERSION = '1.6.1';\n\n  // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns\n  // the `$` variable.\n  Backbone.$ = $;\n\n  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable\n  // to its previous owner. Returns a reference to this Backbone object.\n  Backbone.noConflict = function() {\n    root.Backbone = previousBackbone;\n    return this;\n  };\n\n  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option\n  // will fake `\"PATCH\"`, `\"PUT\"` and `\"DELETE\"` requests via the `_method` parameter and\n  // set a `X-Http-Method-Override` header.\n  Backbone.emulateHTTP = false;\n\n  // Turn on `emulateJSON` to support legacy servers that can't deal with direct\n  // `application/json` requests ... this will encode the body as\n  // `application/x-www-form-urlencoded` instead and will send the model in a\n  // form param named `model`.\n  Backbone.emulateJSON = false;\n\n  // Backbone.Events\n  // ---------------\n\n  // A module that can be mixed in to *any object* in order to provide it with\n  // a custom event channel. You may bind a callback to an event with `on` or\n  // remove with `off`; `trigger`-ing an event fires all callbacks in\n  // succession.\n  //\n  //     var object = {};\n  //     _.extend(object, Backbone.Events);\n  //     object.on('expand', function(){ alert('expanded'); });\n  //     object.trigger('expand');\n  //\n  var Events = Backbone.Events = {};\n\n  // Regular expression used to split event strings.\n  var eventSplitter = /\\s+/;\n\n  // A private global variable to share between listeners and listenees.\n  var _listening;\n\n  // Iterates over the standard `event, callback` (as well as the fancy multiple\n  // space-separated events `\"change blur\", callback` and jQuery-style event\n  // maps `{event: callback}`).\n  var eventsApi = function(iteratee, events, name, callback, opts) {\n    var i = 0, names;\n    if (name && typeof name === 'object') {\n      // Handle event maps.\n      if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;\n      for (names = _.keys(name); i < names.length ; i++) {\n        events = eventsApi(iteratee, events, names[i], name[names[i]], opts);\n      }\n    } else if (name && eventSplitter.test(name)) {\n      // Handle space-separated event names by delegating them individually.\n      for (names = name.split(eventSplitter); i < names.length; i++) {\n        events = iteratee(events, names[i], callback, opts);\n      }\n    } else {\n      // Finally, standard events.\n      events = iteratee(events, name, callback, opts);\n    }\n    return events;\n  };\n\n  // Bind an event to a `callback` function. Passing `\"all\"` will bind\n  // the callback to all events fired.\n  Events.on = function(name, callback, context) {\n    this._events = eventsApi(onApi, this._events || {}, name, callback, {\n      context: context,\n      ctx: this,\n      listening: _listening\n    });\n\n    if (_listening) {\n      var listeners = this._listeners || (this._listeners = {});\n      listeners[_listening.id] = _listening;\n      // Allow the listening to use a counter, instead of tracking\n      // callbacks for library interop\n      _listening.interop = false;\n    }\n\n    return this;\n  };\n\n  // Inversion-of-control versions of `on`. Tell *this* object to listen to\n  // an event in another object... keeping track of what it's listening to\n  // for easier unbinding later.\n  Events.listenTo = function(obj, name, callback) {\n    if (!obj) return this;\n    var id = obj._listenId || (obj._listenId = _.uniqueId('l'));\n    var listeningTo = this._listeningTo || (this._listeningTo = {});\n    var listening = _listening = listeningTo[id];\n\n    // This object is not listening to any other events on `obj` yet.\n    // Setup the necessary references to track the listening callbacks.\n    if (!listening) {\n      this._listenId || (this._listenId = _.uniqueId('l'));\n      listening = _listening = listeningTo[id] = new Listening(this, obj);\n    }\n\n    // Bind callbacks on obj.\n    var error = tryCatchOn(obj, name, callback, this);\n    _listening = void 0;\n\n    if (error) throw error;\n    // If the target obj is not Backbone.Events, track events manually.\n    if (listening.interop) listening.on(name, callback);\n\n    return this;\n  };\n\n  // The reducing API that adds a callback to the `events` object.\n  var onApi = function(events, name, callback, options) {\n    if (callback) {\n      var handlers = events[name] || (events[name] = []);\n      var context = options.context, ctx = options.ctx, listening = options.listening;\n      if (listening) listening.count++;\n\n      handlers.push({callback: callback, context: context, ctx: context || ctx, listening: listening});\n    }\n    return events;\n  };\n\n  // An try-catch guarded #on function, to prevent poisoning the global\n  // `_listening` variable.\n  var tryCatchOn = function(obj, name, callback, context) {\n    try {\n      obj.on(name, callback, context);\n    } catch (e) {\n      return e;\n    }\n  };\n\n  // Remove one or many callbacks. If `context` is null, removes all\n  // callbacks with that function. If `callback` is null, removes all\n  // callbacks for the event. If `name` is null, removes all bound\n  // callbacks for all events.\n  Events.off = function(name, callback, context) {\n    if (!this._events) return this;\n    this._events = eventsApi(offApi, this._events, name, callback, {\n      context: context,\n      listeners: this._listeners\n    });\n\n    return this;\n  };\n\n  // Tell this object to stop listening to either specific events ... or\n  // to every object it's currently listening to.\n  Events.stopListening = function(obj, name, callback) {\n    var listeningTo = this._listeningTo;\n    if (!listeningTo) return this;\n\n    var ids = obj ? [obj._listenId] : _.keys(listeningTo);\n    for (var i = 0; i < ids.length; i++) {\n      var listening = listeningTo[ids[i]];\n\n      // If listening doesn't exist, this object is not currently\n      // listening to obj. Break out early.\n      if (!listening) break;\n\n      listening.obj.off(name, callback, this);\n      if (listening.interop) listening.off(name, callback);\n    }\n    if (_.isEmpty(listeningTo)) this._listeningTo = void 0;\n\n    return this;\n  };\n\n  // The reducing API that removes a callback from the `events` object.\n  var offApi = function(events, name, callback, options) {\n    if (!events) return;\n\n    var context = options.context, listeners = options.listeners;\n    var i = 0, names;\n\n    // Delete all event listeners and \"drop\" events.\n    if (!name && !context && !callback) {\n      for (names = _.keys(listeners); i < names.length; i++) {\n        listeners[names[i]].cleanup();\n      }\n      return;\n    }\n\n    names = name ? [name] : _.keys(events);\n    for (; i < names.length; i++) {\n      name = names[i];\n      var handlers = events[name];\n\n      // Bail out if there are no events stored.\n      if (!handlers) break;\n\n      // Find any remaining events.\n      var remaining = [];\n      for (var j = 0; j < handlers.length; j++) {\n        var handler = handlers[j];\n        if (\n          callback && callback !== handler.callback &&\n            callback !== handler.callback._callback ||\n              context && context !== handler.context\n        ) {\n          remaining.push(handler);\n        } else {\n          var listening = handler.listening;\n          if (listening) listening.off(name, callback);\n        }\n      }\n\n      // Replace events if there are any remaining.  Otherwise, clean up.\n      if (remaining.length) {\n        events[name] = remaining;\n      } else {\n        delete events[name];\n      }\n    }\n\n    return events;\n  };\n\n  // Bind an event to only be triggered a single time. After the first time\n  // the callback is invoked, its listener will be removed. If multiple events\n  // are passed in using the space-separated syntax, the handler will fire\n  // once for each event, not once for a combination of all events.\n  Events.once = function(name, callback, context) {\n    // Map the event into a `{event: once}` object.\n    var events = eventsApi(onceMap, {}, name, callback, this.off.bind(this));\n    if (typeof name === 'string' && context == null) callback = void 0;\n    return this.on(events, callback, context);\n  };\n\n  // Inversion-of-control versions of `once`.\n  Events.listenToOnce = function(obj, name, callback) {\n    // Map the event into a `{event: once}` object.\n    var events = eventsApi(onceMap, {}, name, callback, this.stopListening.bind(this, obj));\n    return this.listenTo(obj, events);\n  };\n\n  // Reduces the event callbacks into a map of `{event: onceWrapper}`.\n  // `offer` unbinds the `onceWrapper` after it has been called.\n  var onceMap = function(map, name, callback, offer) {\n    if (callback) {\n      var once = map[name] = _.once(function() {\n        offer(name, once);\n        callback.apply(this, arguments);\n      });\n      once._callback = callback;\n    }\n    return map;\n  };\n\n  // Trigger one or many events, firing all bound callbacks. Callbacks are\n  // passed the same arguments as `trigger` is, apart from the event name\n  // (unless you're listening on `\"all\"`, which will cause your callback to\n  // receive the true name of the event as the first argument).\n  Events.trigger = function(name) {\n    if (!this._events) return this;\n\n    var length = Math.max(0, arguments.length - 1);\n    var args = Array(length);\n    for (var i = 0; i < length; i++) args[i] = arguments[i + 1];\n\n    eventsApi(triggerApi, this._events, name, void 0, args);\n    return this;\n  };\n\n  // Handles triggering the appropriate event callbacks.\n  var triggerApi = function(objEvents, name, callback, args) {\n    if (objEvents) {\n      var events = objEvents[name];\n      var allEvents = objEvents.all;\n      if (events && allEvents) allEvents = allEvents.slice();\n      if (events) triggerEvents(events, args);\n      if (allEvents) triggerEvents(allEvents, [name].concat(args));\n    }\n    return objEvents;\n  };\n\n  // A difficult-to-believe, but optimized internal dispatch function for\n  // triggering events. Tries to keep the usual cases speedy (most internal\n  // Backbone events have 3 arguments).\n  var triggerEvents = function(events, args) {\n    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];\n    switch (args.length) {\n      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;\n      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;\n      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;\n      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;\n      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;\n    }\n  };\n\n  // A listening class that tracks and cleans up memory bindings\n  // when all callbacks have been offed.\n  var Listening = function(listener, obj) {\n    this.id = listener._listenId;\n    this.listener = listener;\n    this.obj = obj;\n    this.interop = true;\n    this.count = 0;\n    this._events = void 0;\n  };\n\n  Listening.prototype.on = Events.on;\n\n  // Offs a callback (or several).\n  // Uses an optimized counter if the listenee uses Backbone.Events.\n  // Otherwise, falls back to manual tracking to support events\n  // library interop.\n  Listening.prototype.off = function(name, callback) {\n    var cleanup;\n    if (this.interop) {\n      this._events = eventsApi(offApi, this._events, name, callback, {\n        context: void 0,\n        listeners: void 0\n      });\n      cleanup = !this._events;\n    } else {\n      this.count--;\n      cleanup = this.count === 0;\n    }\n    if (cleanup) this.cleanup();\n  };\n\n  // Cleans up memory bindings between the listener and the listenee.\n  Listening.prototype.cleanup = function() {\n    delete this.listener._listeningTo[this.obj._listenId];\n    if (!this.interop) delete this.obj._listeners[this.id];\n  };\n\n  // Aliases for backwards compatibility.\n  Events.bind   = Events.on;\n  Events.unbind = Events.off;\n\n  // Allow the `Backbone` object to serve as a global event bus, for folks who\n  // want global \"pubsub\" in a convenient place.\n  _.extend(Backbone, Events);\n\n  // Backbone.Model\n  // --------------\n\n  // Backbone **Models** are the basic data object in the framework --\n  // frequently representing a row in a table in a database on your server.\n  // A discrete chunk of data and a bunch of useful, related methods for\n  // performing computations and transformations on that data.\n\n  // Create a new model with the specified attributes. A client id (`cid`)\n  // is automatically generated and assigned for you.\n  var Model = Backbone.Model = function(attributes, options) {\n    var attrs = attributes || {};\n    options || (options = {});\n    this.preinitialize.apply(this, arguments);\n    this.cid = _.uniqueId(this.cidPrefix);\n    this.attributes = {};\n    if (options.collection) this.collection = options.collection;\n    if (options.parse) attrs = this.parse(attrs, options) || {};\n    var defaults = _.result(this, 'defaults');\n\n    // Just _.defaults would work fine, but the additional _.extends\n    // is in there for historical reasons. See #3843.\n    attrs = _.defaults(_.extend({}, defaults, attrs), defaults);\n\n    this.set(attrs, options);\n    this.changed = {};\n    this.initialize.apply(this, arguments);\n  };\n\n  // Attach all inheritable methods to the Model prototype.\n  _.extend(Model.prototype, Events, {\n\n    // A hash of attributes whose current and previous value differ.\n    changed: null,\n\n    // The value returned during the last failed validation.\n    validationError: null,\n\n    // The default name for the JSON `id` attribute is `\"id\"`. MongoDB and\n    // CouchDB users may want to set this to `\"_id\"`.\n    idAttribute: 'id',\n\n    // The prefix is used to create the client id which is used to identify models locally.\n    // You may want to override this if you're experiencing name clashes with model ids.\n    cidPrefix: 'c',\n\n    // preinitialize is an empty function by default. You can override it with a function\n    // or object.  preinitialize will run before any instantiation logic is run in the Model.\n    preinitialize: function(){},\n\n    // Initialize is an empty function by default. Override it with your own\n    // initialization logic.\n    initialize: function(){},\n\n    // Return a copy of the model's `attributes` object.\n    toJSON: function(options) {\n      return _.clone(this.attributes);\n    },\n\n    // Proxy `Backbone.sync` by default -- but override this if you need\n    // custom syncing semantics for *this* particular model.\n    sync: function() {\n      return Backbone.sync.apply(this, arguments);\n    },\n\n    // Get the value of an attribute.\n    get: function(attr) {\n      return this.attributes[attr];\n    },\n\n    // Get the HTML-escaped value of an attribute.\n    escape: function(attr) {\n      return _.escape(this.get(attr));\n    },\n\n    // Returns `true` if the attribute contains a value that is not null\n    // or undefined.\n    has: function(attr) {\n      return this.get(attr) != null;\n    },\n\n    // Special-cased proxy to underscore's `_.matches` method.\n    matches: function(attrs) {\n      return !!_.iteratee(attrs, this)(this.attributes);\n    },\n\n    // Set a hash of model attributes on the object, firing `\"change\"`. This is\n    // the core primitive operation of a model, updating the data and notifying\n    // anyone who needs to know about the change in state. The heart of the beast.\n    set: function(key, val, options) {\n      if (key == null) return this;\n\n      // Handle both `\"key\", value` and `{key: value}` -style arguments.\n      var attrs;\n      if (typeof key === 'object') {\n        attrs = key;\n        options = val;\n      } else {\n        (attrs = {})[key] = val;\n      }\n\n      options || (options = {});\n\n      // Run validation.\n      if (!this._validate(attrs, options)) return false;\n\n      // Extract attributes and options.\n      var unset      = options.unset;\n      var silent     = options.silent;\n      var changes    = [];\n      var changing   = this._changing;\n      this._changing = true;\n\n      if (!changing) {\n        this._previousAttributes = _.clone(this.attributes);\n        this.changed = {};\n      }\n\n      var current = this.attributes;\n      var changed = this.changed;\n      var prev    = this._previousAttributes;\n\n      // For each `set` attribute, update or delete the current value.\n      for (var attr in attrs) {\n        val = attrs[attr];\n        if (!_.isEqual(current[attr], val)) changes.push(attr);\n        if (!_.isEqual(prev[attr], val)) {\n          changed[attr] = val;\n        } else {\n          delete changed[attr];\n        }\n        unset ? delete current[attr] : current[attr] = val;\n      }\n\n      // Update the `id`.\n      if (this.idAttribute in attrs) {\n        var prevId = this.id;\n        this.id = this.get(this.idAttribute);\n        if (this.id !== prevId) {\n          this.trigger('changeId', this, prevId, options);\n        }\n      }\n\n      // Trigger all relevant attribute changes.\n      if (!silent) {\n        if (changes.length) this._pending = options;\n        for (var i = 0; i < changes.length; i++) {\n          this.trigger('change:' + changes[i], this, current[changes[i]], options);\n        }\n      }\n\n      // You might be wondering why there's a `while` loop here. Changes can\n      // be recursively nested within `\"change\"` events.\n      if (changing) return this;\n      if (!silent) {\n        while (this._pending) {\n          options = this._pending;\n          this._pending = false;\n          this.trigger('change', this, options);\n        }\n      }\n      this._pending = false;\n      this._changing = false;\n      return this;\n    },\n\n    // Remove an attribute from the model, firing `\"change\"`. `unset` is a noop\n    // if the attribute doesn't exist.\n    unset: function(attr, options) {\n      return this.set(attr, void 0, _.extend({}, options, {unset: true}));\n    },\n\n    // Clear all attributes on the model, firing `\"change\"`.\n    clear: function(options) {\n      var attrs = {};\n      for (var key in this.attributes) attrs[key] = void 0;\n      return this.set(attrs, _.extend({}, options, {unset: true}));\n    },\n\n    // Determine if the model has changed since the last `\"change\"` event.\n    // If you specify an attribute name, determine if that attribute has changed.\n    hasChanged: function(attr) {\n      if (attr == null) return !_.isEmpty(this.changed);\n      return _.has(this.changed, attr);\n    },\n\n    // Return an object containing all the attributes that have changed, or\n    // false if there are no changed attributes. Useful for determining what\n    // parts of a view need to be updated and/or what attributes need to be\n    // persisted to the server. Unset attributes will be set to undefined.\n    // You can also pass an attributes object to diff against the model,\n    // determining if there *would be* a change.\n    changedAttributes: function(diff) {\n      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;\n      var old = this._changing ? this._previousAttributes : this.attributes;\n      var changed = {};\n      var hasChanged;\n      for (var attr in diff) {\n        var val = diff[attr];\n        if (_.isEqual(old[attr], val)) continue;\n        changed[attr] = val;\n        hasChanged = true;\n      }\n      return hasChanged ? changed : false;\n    },\n\n    // Get the previous value of an attribute, recorded at the time the last\n    // `\"change\"` event was fired.\n    previous: function(attr) {\n      if (attr == null || !this._previousAttributes) return null;\n      return this._previousAttributes[attr];\n    },\n\n    // Get all of the attributes of the model at the time of the previous\n    // `\"change\"` event.\n    previousAttributes: function() {\n      return _.clone(this._previousAttributes);\n    },\n\n    // Fetch the model from the server, merging the response with the model's\n    // local attributes. Any changed attributes will trigger a \"change\" event.\n    fetch: function(options) {\n      options = _.extend({parse: true}, options);\n      var model = this;\n      var success = options.success;\n      options.success = function(resp) {\n        var serverAttrs = options.parse ? model.parse(resp, options) : resp;\n        if (!model.set(serverAttrs, options)) return false;\n        if (success) success.call(options.context, model, resp, options);\n        model.trigger('sync', model, resp, options);\n      };\n      wrapError(this, options);\n      return this.sync('read', this, options);\n    },\n\n    // Set a hash of model attributes, and sync the model to the server.\n    // If the server returns an attributes hash that differs, the model's\n    // state will be `set` again.\n    save: function(key, val, options) {\n      // Handle both `\"key\", value` and `{key: value}` -style arguments.\n      var attrs;\n      if (key == null || typeof key === 'object') {\n        attrs = key;\n        options = val;\n      } else {\n        (attrs = {})[key] = val;\n      }\n\n      options = _.extend({validate: true, parse: true}, options);\n      var wait = options.wait;\n\n      // If we're not waiting and attributes exist, save acts as\n      // `set(attr).save(null, opts)` with validation. Otherwise, check if\n      // the model will be valid when the attributes, if any, are set.\n      if (attrs && !wait) {\n        if (!this.set(attrs, options)) return false;\n      } else if (!this._validate(attrs, options)) {\n        return false;\n      }\n\n      // After a successful server-side save, the client is (optionally)\n      // updated with the server-side state.\n      var model = this;\n      var success = options.success;\n      var attributes = this.attributes;\n      options.success = function(resp) {\n        // Ensure attributes are restored during synchronous saves.\n        model.attributes = attributes;\n        var serverAttrs = options.parse ? model.parse(resp, options) : resp;\n        if (wait) serverAttrs = _.extend({}, attrs, serverAttrs);\n        if (serverAttrs && !model.set(serverAttrs, options)) return false;\n        if (success) success.call(options.context, model, resp, options);\n        model.trigger('sync', model, resp, options);\n      };\n      wrapError(this, options);\n\n      // Set temporary attributes if `{wait: true}` to properly find new ids.\n      if (attrs && wait) this.attributes = _.extend({}, attributes, attrs);\n\n      var method = this.isNew() ? 'create' : options.patch ? 'patch' : 'update';\n      if (method === 'patch' && !options.attrs) options.attrs = attrs;\n      var xhr = this.sync(method, this, options);\n\n      // Restore attributes.\n      this.attributes = attributes;\n\n      return xhr;\n    },\n\n    // Destroy this model on the server if it was already persisted.\n    // Optimistically removes the model from its collection, if it has one.\n    // If `wait: true` is passed, waits for the server to respond before removal.\n    destroy: function(options) {\n      options = options ? _.clone(options) : {};\n      var model = this;\n      var success = options.success;\n      var wait = options.wait;\n\n      var destroy = function() {\n        model.stopListening();\n        model.trigger('destroy', model, model.collection, options);\n      };\n\n      options.success = function(resp) {\n        if (wait) destroy();\n        if (success) success.call(options.context, model, resp, options);\n        if (!model.isNew()) model.trigger('sync', model, resp, options);\n      };\n\n      var xhr = false;\n      if (this.isNew()) {\n        _.defer(options.success);\n      } else {\n        wrapError(this, options);\n        xhr = this.sync('delete', this, options);\n      }\n      if (!wait) destroy();\n      return xhr;\n    },\n\n    // Default URL for the model's representation on the server -- if you're\n    // using Backbone's restful methods, override this to change the endpoint\n    // that will be called.\n    url: function() {\n      var base =\n        _.result(this, 'urlRoot') ||\n        _.result(this.collection, 'url') ||\n        urlError();\n      if (this.isNew()) return base;\n      var id = this.get(this.idAttribute);\n      return base.replace(/[^\\/]$/, '$&/') + encodeURIComponent(id);\n    },\n\n    // **parse** converts a response into the hash of attributes to be `set` on\n    // the model. The default implementation is just to pass the response along.\n    parse: function(resp, options) {\n      return resp;\n    },\n\n    // Create a new model with identical attributes to this one.\n    clone: function() {\n      return new this.constructor(this.attributes);\n    },\n\n    // A model is new if it has never been saved to the server, and lacks an id.\n    isNew: function() {\n      return !this.has(this.idAttribute);\n    },\n\n    // Check if the model is currently in a valid state.\n    isValid: function(options) {\n      return this._validate({}, _.extend({}, options, {validate: true}));\n    },\n\n    // Run validation against the next complete set of model attributes,\n    // returning `true` if all is well. Otherwise, fire an `\"invalid\"` event.\n    _validate: function(attrs, options) {\n      if (!options.validate || !this.validate) return true;\n      attrs = _.extend({}, this.attributes, attrs);\n      var error = this.validationError = this.validate(attrs, options) || null;\n      if (!error) return true;\n      this.trigger('invalid', this, error, _.extend(options, {validationError: error}));\n      return false;\n    }\n\n  });\n\n  // Backbone.Collection\n  // -------------------\n\n  // If models tend to represent a single row of data, a Backbone Collection is\n  // more analogous to a table full of data ... or a small slice or page of that\n  // table, or a collection of rows that belong together for a particular reason\n  // -- all of the messages in this particular folder, all of the documents\n  // belonging to this particular author, and so on. Collections maintain\n  // indexes of their models, both in order, and for lookup by `id`.\n\n  // Create a new **Collection**, perhaps to contain a specific type of `model`.\n  // If a `comparator` is specified, the Collection will maintain\n  // its models in sort order, as they're added and removed.\n  var Collection = Backbone.Collection = function(models, options) {\n    options || (options = {});\n    this.preinitialize.apply(this, arguments);\n    if (options.model) this.model = options.model;\n    if (options.comparator !== void 0) this.comparator = options.comparator;\n    this._reset();\n    this.initialize.apply(this, arguments);\n    if (models) this.reset(models, _.extend({silent: true}, options));\n  };\n\n  // Default options for `Collection#set`.\n  var setOptions = {add: true, remove: true, merge: true};\n  var addOptions = {add: true, remove: false};\n\n  // Splices `insert` into `array` at index `at`.\n  var splice = function(array, insert, at) {\n    at = Math.min(Math.max(at, 0), array.length);\n    var tail = Array(array.length - at);\n    var length = insert.length;\n    var i;\n    for (i = 0; i < tail.length; i++) tail[i] = array[i + at];\n    for (i = 0; i < length; i++) array[i + at] = insert[i];\n    for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];\n  };\n\n  // Define the Collection's inheritable methods.\n  _.extend(Collection.prototype, Events, {\n\n    // The default model for a collection is just a **Backbone.Model**.\n    // This should be overridden in most cases.\n    model: Model,\n\n\n    // preinitialize is an empty function by default. You can override it with a function\n    // or object.  preinitialize will run before any instantiation logic is run in the Collection.\n    preinitialize: function(){},\n\n    // Initialize is an empty function by default. Override it with your own\n    // initialization logic.\n    initialize: function(){},\n\n    // The JSON representation of a Collection is an array of the\n    // models' attributes.\n    toJSON: function(options) {\n      return this.map(function(model) { return model.toJSON(options); });\n    },\n\n    // Proxy `Backbone.sync` by default.\n    sync: function() {\n      return Backbone.sync.apply(this, arguments);\n    },\n\n    // Add a model, or list of models to the set. `models` may be Backbone\n    // Models or raw JavaScript objects to be converted to Models, or any\n    // combination of the two.\n    add: function(models, options) {\n      return this.set(models, _.extend({merge: false}, options, addOptions));\n    },\n\n    // Remove a model, or a list of models from the set.\n    remove: function(models, options) {\n      options = _.extend({}, options);\n      var singular = !_.isArray(models);\n      models = singular ? [models] : models.slice();\n      var removed = this._removeModels(models, options);\n      if (!options.silent && removed.length) {\n        options.changes = {added: [], merged: [], removed: removed};\n        this.trigger('update', this, options);\n      }\n      return singular ? removed[0] : removed;\n    },\n\n    // Update a collection by `set`-ing a new list of models, adding new ones,\n    // removing models that are no longer present, and merging models that\n    // already exist in the collection, as necessary. Similar to **Model#set**,\n    // the core operation for updating the data contained by the collection.\n    set: function(models, options) {\n      if (models == null) return;\n\n      options = _.extend({}, setOptions, options);\n      if (options.parse && !this._isModel(models)) {\n        models = this.parse(models, options) || [];\n      }\n\n      var singular = !_.isArray(models);\n      models = singular ? [models] : models.slice();\n\n      var at = options.at;\n      if (at != null) at = +at;\n      if (at > this.length) at = this.length;\n      if (at < 0) at += this.length + 1;\n\n      var set = [];\n      var toAdd = [];\n      var toMerge = [];\n      var toRemove = [];\n      var modelMap = {};\n\n      var add = options.add;\n      var merge = options.merge;\n      var remove = options.remove;\n\n      var sort = false;\n      var sortable = this.comparator && at == null && options.sort !== false;\n      var sortAttr = _.isString(this.comparator) ? this.comparator : null;\n\n      // Turn bare objects into model references, and prevent invalid models\n      // from being added.\n      var model, i;\n      for (i = 0; i < models.length; i++) {\n        model = models[i];\n\n        // If a duplicate is found, prevent it from being added and\n        // optionally merge it into the existing model.\n        var existing = this.get(model);\n        if (existing) {\n          if (merge && model !== existing) {\n            var attrs = this._isModel(model) ? model.attributes : model;\n            if (options.parse) attrs = existing.parse(attrs, options);\n            existing.set(attrs, options);\n            toMerge.push(existing);\n            if (sortable && !sort) sort = existing.hasChanged(sortAttr);\n          }\n          if (!modelMap[existing.cid]) {\n            modelMap[existing.cid] = true;\n            set.push(existing);\n          }\n          models[i] = existing;\n\n        // If this is a new, valid model, push it to the `toAdd` list.\n        } else if (add) {\n          model = models[i] = this._prepareModel(model, options);\n          if (model) {\n            toAdd.push(model);\n            this._addReference(model, options);\n            modelMap[model.cid] = true;\n            set.push(model);\n          }\n        }\n      }\n\n      // Remove stale models.\n      if (remove) {\n        for (i = 0; i < this.length; i++) {\n          model = this.models[i];\n          if (!modelMap[model.cid]) toRemove.push(model);\n        }\n        if (toRemove.length) this._removeModels(toRemove, options);\n      }\n\n      // See if sorting is needed, update `length` and splice in new models.\n      var orderChanged = false;\n      var replace = !sortable && add && remove;\n      if (set.length && replace) {\n        orderChanged = this.length !== set.length || _.some(this.models, function(m, index) {\n          return m !== set[index];\n        });\n        this.models.length = 0;\n        splice(this.models, set, 0);\n        this.length = this.models.length;\n      } else if (toAdd.length) {\n        if (sortable) sort = true;\n        splice(this.models, toAdd, at == null ? this.length : at);\n        this.length = this.models.length;\n      }\n\n      // Silently sort the collection if appropriate.\n      if (sort) this.sort({silent: true});\n\n      // Unless silenced, it's time to fire all appropriate add/sort/update events.\n      if (!options.silent) {\n        for (i = 0; i < toAdd.length; i++) {\n          if (at != null) options.index = at + i;\n          model = toAdd[i];\n          model.trigger('add', model, this, options);\n        }\n        if (sort || orderChanged) this.trigger('sort', this, options);\n        if (toAdd.length || toRemove.length || toMerge.length) {\n          options.changes = {\n            added: toAdd,\n            removed: toRemove,\n            merged: toMerge\n          };\n          this.trigger('update', this, options);\n        }\n      }\n\n      // Return the added (or merged) model (or models).\n      return singular ? models[0] : models;\n    },\n\n    // When you have more items than you want to add or remove individually,\n    // you can reset the entire set with a new list of models, without firing\n    // any granular `add` or `remove` events. Fires `reset` when finished.\n    // Useful for bulk operations and optimizations.\n    reset: function(models, options) {\n      options = options ? _.clone(options) : {};\n      for (var i = 0; i < this.models.length; i++) {\n        this._removeReference(this.models[i], options);\n      }\n      options.previousModels = this.models;\n      this._reset();\n      models = this.add(models, _.extend({silent: true}, options));\n      if (!options.silent) this.trigger('reset', this, options);\n      return models;\n    },\n\n    // Add a model to the end of the collection.\n    push: function(model, options) {\n      return this.add(model, _.extend({at: this.length}, options));\n    },\n\n    // Remove a model from the end of the collection.\n    pop: function(options) {\n      var model = this.at(this.length - 1);\n      return this.remove(model, options);\n    },\n\n    // Add a model to the beginning of the collection.\n    unshift: function(model, options) {\n      return this.add(model, _.extend({at: 0}, options));\n    },\n\n    // Remove a model from the beginning of the collection.\n    shift: function(options) {\n      var model = this.at(0);\n      return this.remove(model, options);\n    },\n\n    // Slice out a sub-array of models from the collection.\n    slice: function() {\n      return slice.apply(this.models, arguments);\n    },\n\n    // Get a model from the set by id, cid, model object with id or cid\n    // properties, or an attributes object that is transformed through modelId.\n    get: function(obj) {\n      if (obj == null) return void 0;\n      return this._byId[obj] ||\n        this._byId[this.modelId(this._isModel(obj) ? obj.attributes : obj, obj.idAttribute)] ||\n        obj.cid && this._byId[obj.cid];\n    },\n\n    // Returns `true` if the model is in the collection.\n    has: function(obj) {\n      return this.get(obj) != null;\n    },\n\n    // Get the model at the given index.\n    at: function(index) {\n      if (index < 0) index += this.length;\n      return this.models[index];\n    },\n\n    // Return models with matching attributes. Useful for simple cases of\n    // `filter`.\n    where: function(attrs, first) {\n      return this[first ? 'find' : 'filter'](attrs);\n    },\n\n    // Return the first model with matching attributes. Useful for simple cases\n    // of `find`.\n    findWhere: function(attrs) {\n      return this.where(attrs, true);\n    },\n\n    // Force the collection to re-sort itself. You don't need to call this under\n    // normal circumstances, as the set will maintain sort order as each item\n    // is added.\n    sort: function(options) {\n      var comparator = this.comparator;\n      if (!comparator) throw new Error('Cannot sort a set without a comparator');\n      options || (options = {});\n\n      var length = comparator.length;\n      if (_.isFunction(comparator)) comparator = comparator.bind(this);\n\n      // Run sort based on type of `comparator`.\n      if (length === 1 || _.isString(comparator)) {\n        this.models = this.sortBy(comparator);\n      } else {\n        this.models.sort(comparator);\n      }\n      if (!options.silent) this.trigger('sort', this, options);\n      return this;\n    },\n\n    // Pluck an attribute from each model in the collection.\n    pluck: function(attr) {\n      return this.map(attr + '');\n    },\n\n    // Fetch the default set of models for this collection, resetting the\n    // collection when they arrive. If `reset: true` is passed, the response\n    // data will be passed through the `reset` method instead of `set`.\n    fetch: function(options) {\n      options = _.extend({parse: true}, options);\n      var success = options.success;\n      var collection = this;\n      options.success = function(resp) {\n        var method = options.reset ? 'reset' : 'set';\n        collection[method](resp, options);\n        if (success) success.call(options.context, collection, resp, options);\n        collection.trigger('sync', collection, resp, options);\n      };\n      wrapError(this, options);\n      return this.sync('read', this, options);\n    },\n\n    // Create a new instance of a model in this collection. Add the model to the\n    // collection immediately, unless `wait: true` is passed, in which case we\n    // wait for the server to agree.\n    create: function(model, options) {\n      options = options ? _.clone(options) : {};\n      var wait = options.wait;\n      model = this._prepareModel(model, options);\n      if (!model) return false;\n      if (!wait) this.add(model, options);\n      var collection = this;\n      var success = options.success;\n      options.success = function(m, resp, callbackOpts) {\n        if (wait) {\n          m.off('error', collection._forwardPristineError, collection);\n          collection.add(m, callbackOpts);\n        }\n        if (success) success.call(callbackOpts.context, m, resp, callbackOpts);\n      };\n      // In case of wait:true, our collection is not listening to any\n      // of the model's events yet, so it will not forward the error\n      // event. In this special case, we need to listen for it\n      // separately and handle the event just once.\n      // (The reason we don't need to do this for the sync event is\n      // in the success handler above: we add the model first, which\n      // causes the collection to listen, and then invoke the callback\n      // that triggers the event.)\n      if (wait) {\n        model.once('error', this._forwardPristineError, this);\n      }\n      model.save(null, options);\n      return model;\n    },\n\n    // **parse** converts a response into a list of models to be added to the\n    // collection. The default implementation is just to pass it through.\n    parse: function(resp, options) {\n      return resp;\n    },\n\n    // Create a new collection with an identical list of models as this one.\n    clone: function() {\n      return new this.constructor(this.models, {\n        model: this.model,\n        comparator: this.comparator\n      });\n    },\n\n    // Define how to uniquely identify models in the collection.\n    modelId: function(attrs, idAttribute) {\n      return attrs[idAttribute || this.model.prototype.idAttribute || 'id'];\n    },\n\n    // Get an iterator of all models in this collection.\n    values: function() {\n      return new CollectionIterator(this, ITERATOR_VALUES);\n    },\n\n    // Get an iterator of all model IDs in this collection.\n    keys: function() {\n      return new CollectionIterator(this, ITERATOR_KEYS);\n    },\n\n    // Get an iterator of all [ID, model] tuples in this collection.\n    entries: function() {\n      return new CollectionIterator(this, ITERATOR_KEYSVALUES);\n    },\n\n    // Private method to reset all internal state. Called when the collection\n    // is first initialized or reset.\n    _reset: function() {\n      this.length = 0;\n      this.models = [];\n      this._byId  = {};\n    },\n\n    // Prepare a hash of attributes (or other model) to be added to this\n    // collection.\n    _prepareModel: function(attrs, options) {\n      if (this._isModel(attrs)) {\n        if (!attrs.collection) attrs.collection = this;\n        return attrs;\n      }\n      options = options ? _.clone(options) : {};\n      options.collection = this;\n\n      var model;\n      if (this.model.prototype) {\n        model = new this.model(attrs, options);\n      } else {\n        // ES class methods didn't have prototype\n        model = this.model(attrs, options);\n      }\n\n      if (!model.validationError) return model;\n      this.trigger('invalid', this, model.validationError, options);\n      return false;\n    },\n\n    // Internal method called by both remove and set.\n    _removeModels: function(models, options) {\n      var removed = [];\n      for (var i = 0; i < models.length; i++) {\n        var model = this.get(models[i]);\n        if (!model) continue;\n\n        var index = this.indexOf(model);\n        this.models.splice(index, 1);\n        this.length--;\n\n        // Remove references before triggering 'remove' event to prevent an\n        // infinite loop. #3693\n        delete this._byId[model.cid];\n        var id = this.modelId(model.attributes, model.idAttribute);\n        if (id != null) delete this._byId[id];\n\n        if (!options.silent) {\n          options.index = index;\n          model.trigger('remove', model, this, options);\n        }\n\n        removed.push(model);\n        this._removeReference(model, options);\n      }\n      if (models.length > 0 && !options.silent) delete options.index;\n      return removed;\n    },\n\n    // Method for checking whether an object should be considered a model for\n    // the purposes of adding to the collection.\n    _isModel: function(model) {\n      return model instanceof Model;\n    },\n\n    // Internal method to create a model's ties to a collection.\n    _addReference: function(model, options) {\n      this._byId[model.cid] = model;\n      var id = this.modelId(model.attributes, model.idAttribute);\n      if (id != null) this._byId[id] = model;\n      model.on('all', this._onModelEvent, this);\n    },\n\n    // Internal method to sever a model's ties to a collection.\n    _removeReference: function(model, options) {\n      delete this._byId[model.cid];\n      var id = this.modelId(model.attributes, model.idAttribute);\n      if (id != null) delete this._byId[id];\n      if (this === model.collection) delete model.collection;\n      model.off('all', this._onModelEvent, this);\n    },\n\n    // Internal method called every time a model in the set fires an event.\n    // Sets need to update their indexes when models change ids. All other\n    // events simply proxy through. \"add\" and \"remove\" events that originate\n    // in other collections are ignored.\n    _onModelEvent: function(event, model, collection, options) {\n      if (model) {\n        if ((event === 'add' || event === 'remove') && collection !== this) return;\n        if (event === 'destroy') this.remove(model, options);\n        if (event === 'changeId') {\n          var prevId = this.modelId(model.previousAttributes(), model.idAttribute);\n          var id = this.modelId(model.attributes, model.idAttribute);\n          if (prevId != null) delete this._byId[prevId];\n          if (id != null) this._byId[id] = model;\n        }\n      }\n      this.trigger.apply(this, arguments);\n    },\n\n    // Internal callback method used in `create`. It serves as a\n    // stand-in for the `_onModelEvent` method, which is not yet bound\n    // during the `wait` period of the `create` call. We still want to\n    // forward any `'error'` event at the end of the `wait` period,\n    // hence a customized callback.\n    _forwardPristineError: function(model, collection, options) {\n      // Prevent double forward if the model was already in the\n      // collection before the call to `create`.\n      if (this.has(model)) return;\n      this._onModelEvent('error', model, collection, options);\n    }\n  });\n\n  // Defining an @@iterator method implements JavaScript's Iterable protocol.\n  // In modern ES2015 browsers, this value is found at Symbol.iterator.\n  /* global Symbol */\n  var $$iterator = typeof Symbol === 'function' && Symbol.iterator;\n  if ($$iterator) {\n    Collection.prototype[$$iterator] = Collection.prototype.values;\n  }\n\n  // CollectionIterator\n  // ------------------\n\n  // A CollectionIterator implements JavaScript's Iterator protocol, allowing the\n  // use of `for of` loops in modern browsers and interoperation between\n  // Backbone.Collection and other JavaScript functions and third-party libraries\n  // which can operate on Iterables.\n  var CollectionIterator = function(collection, kind) {\n    this._collection = collection;\n    this._kind = kind;\n    this._index = 0;\n  };\n\n  // This \"enum\" defines the three possible kinds of values which can be emitted\n  // by a CollectionIterator that correspond to the values(), keys() and entries()\n  // methods on Collection, respectively.\n  var ITERATOR_VALUES = 1;\n  var ITERATOR_KEYS = 2;\n  var ITERATOR_KEYSVALUES = 3;\n\n  // All Iterators should themselves be Iterable.\n  if ($$iterator) {\n    CollectionIterator.prototype[$$iterator] = function() {\n      return this;\n    };\n  }\n\n  CollectionIterator.prototype.next = function() {\n    if (this._collection) {\n\n      // Only continue iterating if the iterated collection is long enough.\n      if (this._index < this._collection.length) {\n        var model = this._collection.at(this._index);\n        this._index++;\n\n        // Construct a value depending on what kind of values should be iterated.\n        var value;\n        if (this._kind === ITERATOR_VALUES) {\n          value = model;\n        } else {\n          var id = this._collection.modelId(model.attributes, model.idAttribute);\n          if (this._kind === ITERATOR_KEYS) {\n            value = id;\n          } else { // ITERATOR_KEYSVALUES\n            value = [id, model];\n          }\n        }\n        return {value: value, done: false};\n      }\n\n      // Once exhausted, remove the reference to the collection so future\n      // calls to the next method always return done.\n      this._collection = void 0;\n    }\n\n    return {value: void 0, done: true};\n  };\n\n  // Backbone.View\n  // -------------\n\n  // Backbone Views are almost more convention than they are actual code. A View\n  // is simply a JavaScript object that represents a logical chunk of UI in the\n  // DOM. This might be a single item, an entire list, a sidebar or panel, or\n  // even the surrounding frame which wraps your whole app. Defining a chunk of\n  // UI as a **View** allows you to define your DOM events declaratively, without\n  // having to worry about render order ... and makes it easy for the view to\n  // react to specific changes in the state of your models.\n\n  // Creating a Backbone.View creates its initial element outside of the DOM,\n  // if an existing element is not provided...\n  var View = Backbone.View = function(options) {\n    this.cid = _.uniqueId('view');\n    this.preinitialize.apply(this, arguments);\n    _.extend(this, _.pick(options, viewOptions));\n    this._ensureElement();\n    this.initialize.apply(this, arguments);\n  };\n\n  // Cached regex to split keys for `delegate`.\n  var delegateEventSplitter = /^(\\S+)\\s*(.*)$/;\n\n  // List of view options to be set as properties.\n  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];\n\n  // Set up all inheritable **Backbone.View** properties and methods.\n  _.extend(View.prototype, Events, {\n\n    // The default `tagName` of a View's element is `\"div\"`.\n    tagName: 'div',\n\n    // jQuery delegate for element lookup, scoped to DOM elements within the\n    // current view. This should be preferred to global lookups where possible.\n    $: function(selector) {\n      return this.$el.find(selector);\n    },\n\n    // preinitialize is an empty function by default. You can override it with a function\n    // or object.  preinitialize will run before any instantiation logic is run in the View\n    preinitialize: function(){},\n\n    // Initialize is an empty function by default. Override it with your own\n    // initialization logic.\n    initialize: function(){},\n\n    // **render** is the core function that your view should override, in order\n    // to populate its element (`this.el`), with the appropriate HTML. The\n    // convention is for **render** to always return `this`.\n    render: function() {\n      return this;\n    },\n\n    // Remove this view by taking the element out of the DOM, and removing any\n    // applicable Backbone.Events listeners.\n    remove: function() {\n      this._removeElement();\n      this.stopListening();\n      return this;\n    },\n\n    // Remove this view's element from the document and all event listeners\n    // attached to it. Exposed for subclasses using an alternative DOM\n    // manipulation API.\n    _removeElement: function() {\n      this.$el.remove();\n    },\n\n    // Change the view's element (`this.el` property) and re-delegate the\n    // view's events on the new element.\n    setElement: function(element) {\n      this.undelegateEvents();\n      this._setElement(element);\n      this.delegateEvents();\n      return this;\n    },\n\n    // Creates the `this.el` and `this.$el` references for this view using the\n    // given `el`. `el` can be a CSS selector or an HTML string, a jQuery\n    // context or an element. Subclasses can override this to utilize an\n    // alternative DOM manipulation API and are only required to set the\n    // `this.el` property.\n    _setElement: function(el) {\n      this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);\n      this.el = this.$el[0];\n    },\n\n    // Set callbacks, where `this.events` is a hash of\n    //\n    // *{\"event selector\": \"callback\"}*\n    //\n    //     {\n    //       'mousedown .title':  'edit',\n    //       'click .button':     'save',\n    //       'click .open':       function(e) { ... }\n    //     }\n    //\n    // pairs. Callbacks will be bound to the view, with `this` set properly.\n    // Uses event delegation for efficiency.\n    // Omitting the selector binds the event to `this.el`.\n    delegateEvents: function(events) {\n      events || (events = _.result(this, 'events'));\n      if (!events) return this;\n      this.undelegateEvents();\n      for (var key in events) {\n        var method = events[key];\n        if (!_.isFunction(method)) method = this[method];\n        if (!method) continue;\n        var match = key.match(delegateEventSplitter);\n        this.delegate(match[1], match[2], method.bind(this));\n      }\n      return this;\n    },\n\n    // Add a single event listener to the view's element (or a child element\n    // using `selector`). This only works for delegate-able events: not `focus`,\n    // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.\n    delegate: function(eventName, selector, listener) {\n      this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);\n      return this;\n    },\n\n    // Clears all callbacks previously bound to the view by `delegateEvents`.\n    // You usually don't need to use this, but may wish to if you have multiple\n    // Backbone views attached to the same DOM element.\n    undelegateEvents: function() {\n      if (this.$el) this.$el.off('.delegateEvents' + this.cid);\n      return this;\n    },\n\n    // A finer-grained `undelegateEvents` for removing a single delegated event.\n    // `selector` and `listener` are both optional.\n    undelegate: function(eventName, selector, listener) {\n      this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);\n      return this;\n    },\n\n    // Produces a DOM element to be assigned to your view. Exposed for\n    // subclasses using an alternative DOM manipulation API.\n    _createElement: function(tagName) {\n      return document.createElement(tagName);\n    },\n\n    // Ensure that the View has a DOM element to render into.\n    // If `this.el` is a string, pass it through `$()`, take the first\n    // matching element, and re-assign it to `el`. Otherwise, create\n    // an element from the `id`, `className` and `tagName` properties.\n    _ensureElement: function() {\n      if (!this.el) {\n        var attrs = _.extend({}, _.result(this, 'attributes'));\n        if (this.id) attrs.id = _.result(this, 'id');\n        if (this.className) attrs['class'] = _.result(this, 'className');\n        this.setElement(this._createElement(_.result(this, 'tagName')));\n        this._setAttributes(attrs);\n      } else {\n        this.setElement(_.result(this, 'el'));\n      }\n    },\n\n    // Set attributes from a hash on this view's element.  Exposed for\n    // subclasses using an alternative DOM manipulation API.\n    _setAttributes: function(attributes) {\n      this.$el.attr(attributes);\n    }\n\n  });\n\n  // Proxy Backbone class methods to Underscore functions, wrapping the model's\n  // `attributes` object or collection's `models` array behind the scenes.\n  //\n  // collection.filter(function(model) { return model.get('age') > 10 });\n  // collection.each(this.addView);\n  //\n  // `Function#apply` can be slow so we use the method's arg count, if we know it.\n  var addMethod = function(base, length, method, attribute) {\n    switch (length) {\n      case 1: return function() {\n        return base[method](this[attribute]);\n      };\n      case 2: return function(value) {\n        return base[method](this[attribute], value);\n      };\n      case 3: return function(iteratee, context) {\n        return base[method](this[attribute], cb(iteratee, this), context);\n      };\n      case 4: return function(iteratee, defaultVal, context) {\n        return base[method](this[attribute], cb(iteratee, this), defaultVal, context);\n      };\n      default: return function() {\n        var args = slice.call(arguments);\n        args.unshift(this[attribute]);\n        return base[method].apply(base, args);\n      };\n    }\n  };\n\n  var addUnderscoreMethods = function(Class, base, methods, attribute) {\n    _.each(methods, function(length, method) {\n      if (base[method]) Class.prototype[method] = addMethod(base, length, method, attribute);\n    });\n  };\n\n  // Support `collection.sortBy('attr')` and `collection.findWhere({id: 1})`.\n  var cb = function(iteratee, instance) {\n    if (_.isFunction(iteratee)) return iteratee;\n    if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);\n    if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };\n    return iteratee;\n  };\n  var modelMatcher = function(attrs) {\n    var matcher = _.matches(attrs);\n    return function(model) {\n      return matcher(model.attributes);\n    };\n  };\n\n  // Underscore methods that we want to implement on the Collection.\n  // 90% of the core usefulness of Backbone Collections is actually implemented\n  // right here:\n  var collectionMethods = {forEach: 3, each: 3, map: 3, collect: 3, reduce: 0,\n    foldl: 0, inject: 0, reduceRight: 0, foldr: 0, find: 3, detect: 3, filter: 3,\n    select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,\n    contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,\n    head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,\n    without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,\n    isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,\n    sortBy: 3, indexBy: 3, findIndex: 3, findLastIndex: 3};\n\n\n  // Underscore methods that we want to implement on the Model, mapped to the\n  // number of arguments they take.\n  var modelMethods = {keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,\n    omit: 0, chain: 1, isEmpty: 1};\n\n  // Mix in each Underscore method as a proxy to `Collection#models`.\n\n  _.each([\n    [Collection, collectionMethods, 'models'],\n    [Model, modelMethods, 'attributes']\n  ], function(config) {\n    var Base = config[0],\n        methods = config[1],\n        attribute = config[2];\n\n    Base.mixin = function(obj) {\n      var mappings = _.reduce(_.functions(obj), function(memo, name) {\n        memo[name] = 0;\n        return memo;\n      }, {});\n      addUnderscoreMethods(Base, obj, mappings, attribute);\n    };\n\n    addUnderscoreMethods(Base, _, methods, attribute);\n  });\n\n  // Backbone.sync\n  // -------------\n\n  // Override this function to change the manner in which Backbone persists\n  // models to the server. You will be passed the type of request, and the\n  // model in question. By default, makes a RESTful Ajax request\n  // to the model's `url()`. Some possible customizations could be:\n  //\n  // * Use `setTimeout` to batch rapid-fire updates into a single request.\n  // * Send up the models as XML instead of JSON.\n  // * Persist models via WebSockets instead of Ajax.\n  //\n  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests\n  // as `POST`, with a `_method` parameter containing the true HTTP method,\n  // as well as all requests with the body as `application/x-www-form-urlencoded`\n  // instead of `application/json` with the model in a param named `model`.\n  // Useful when interfacing with server-side languages like **PHP** that make\n  // it difficult to read the body of `PUT` requests.\n  Backbone.sync = function(method, model, options) {\n    var type = methodMap[method];\n\n    // Default options, unless specified.\n    _.defaults(options || (options = {}), {\n      emulateHTTP: Backbone.emulateHTTP,\n      emulateJSON: Backbone.emulateJSON\n    });\n\n    // Default JSON-request options.\n    var params = {type: type, dataType: 'json'};\n\n    // Ensure that we have a URL.\n    if (!options.url) {\n      params.url = _.result(model, 'url') || urlError();\n    }\n\n    // Ensure that we have the appropriate request data.\n    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {\n      params.contentType = 'application/json';\n      params.data = JSON.stringify(options.attrs || model.toJSON(options));\n    }\n\n    // For older servers, emulate JSON by encoding the request into an HTML-form.\n    if (options.emulateJSON) {\n      params.contentType = 'application/x-www-form-urlencoded';\n      params.data = params.data ? {model: params.data} : {};\n    }\n\n    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`\n    // And an `X-HTTP-Method-Override` header.\n    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {\n      params.type = 'POST';\n      if (options.emulateJSON) params.data._method = type;\n      var beforeSend = options.beforeSend;\n      options.beforeSend = function(xhr) {\n        xhr.setRequestHeader('X-HTTP-Method-Override', type);\n        if (beforeSend) return beforeSend.apply(this, arguments);\n      };\n    }\n\n    // Don't process data on a non-GET request.\n    if (params.type !== 'GET' && !options.emulateJSON) {\n      params.processData = false;\n    }\n\n    // Pass along `textStatus` and `errorThrown` from jQuery.\n    var error = options.error;\n    options.error = function(xhr, textStatus, errorThrown) {\n      options.textStatus = textStatus;\n      options.errorThrown = errorThrown;\n      if (error) error.call(options.context, xhr, textStatus, errorThrown);\n    };\n\n    // Make the request, allowing the user to override any Ajax options.\n    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));\n    model.trigger('request', model, xhr, options);\n    return xhr;\n  };\n\n  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.\n  var methodMap = {\n    'create': 'POST',\n    'update': 'PUT',\n    'patch': 'PATCH',\n    'delete': 'DELETE',\n    'read': 'GET'\n  };\n\n  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.\n  // Override this if you'd like to use a different library.\n  Backbone.ajax = function() {\n    return Backbone.$.ajax.apply(Backbone.$, arguments);\n  };\n\n  // Backbone.Router\n  // ---------------\n\n  // Routers map faux-URLs to actions, and fire events when routes are\n  // matched. Creating a new one sets its `routes` hash, if not set statically.\n  var Router = Backbone.Router = function(options) {\n    options || (options = {});\n    this.preinitialize.apply(this, arguments);\n    if (options.routes) this.routes = options.routes;\n    this._bindRoutes();\n    this.initialize.apply(this, arguments);\n  };\n\n  // Cached regular expressions for matching named param parts and splatted\n  // parts of route strings.\n  var optionalParam = /\\((.*?)\\)/g;\n  var namedParam    = /(\\(\\?)?:\\w+/g;\n  var splatParam    = /\\*\\w+/g;\n  var escapeRegExp  = /[\\-{}\\[\\]+?.,\\\\\\^$|#\\s]/g;\n\n  // Set up all inheritable **Backbone.Router** properties and methods.\n  _.extend(Router.prototype, Events, {\n\n    // preinitialize is an empty function by default. You can override it with a function\n    // or object.  preinitialize will run before any instantiation logic is run in the Router.\n    preinitialize: function(){},\n\n    // Initialize is an empty function by default. Override it with your own\n    // initialization logic.\n    initialize: function(){},\n\n    // Manually bind a single named route to a callback. For example:\n    //\n    //     this.route('search/:query/p:num', 'search', function(query, num) {\n    //       ...\n    //     });\n    //\n    route: function(route, name, callback) {\n      if (!_.isRegExp(route)) route = this._routeToRegExp(route);\n      if (_.isFunction(name)) {\n        callback = name;\n        name = '';\n      }\n      if (!callback) callback = this[name];\n      var router = this;\n      Backbone.history.route(route, function(fragment) {\n        var args = router._extractParameters(route, fragment);\n        if (router.execute(callback, args, name) !== false) {\n          router.trigger.apply(router, ['route:' + name].concat(args));\n          router.trigger('route', name, args);\n          Backbone.history.trigger('route', router, name, args);\n        }\n      });\n      return this;\n    },\n\n    // Execute a route handler with the provided parameters.  This is an\n    // excellent place to do pre-route setup or post-route cleanup.\n    execute: function(callback, args, name) {\n      if (callback) callback.apply(this, args);\n    },\n\n    // Simple proxy to `Backbone.history` to save a fragment into the history.\n    navigate: function(fragment, options) {\n      Backbone.history.navigate(fragment, options);\n      return this;\n    },\n\n    // Bind all defined routes to `Backbone.history`. We have to reverse the\n    // order of the routes here to support behavior where the most general\n    // routes can be defined at the bottom of the route map.\n    _bindRoutes: function() {\n      if (!this.routes) return;\n      this.routes = _.result(this, 'routes');\n      var route, routes = _.keys(this.routes);\n      while ((route = routes.pop()) != null) {\n        this.route(route, this.routes[route]);\n      }\n    },\n\n    // Convert a route string into a regular expression, suitable for matching\n    // against the current location hash.\n    _routeToRegExp: function(route) {\n      route = route.replace(escapeRegExp, '\\\\$&')\n      .replace(optionalParam, '(?:$1)?')\n      .replace(namedParam, function(match, optional) {\n        return optional ? match : '([^/?]+)';\n      })\n      .replace(splatParam, '([^?]*?)');\n      return new RegExp('^' + route + '(?:\\\\?([\\\\s\\\\S]*))?$');\n    },\n\n    // Given a route, and a URL fragment that it matches, return the array of\n    // extracted decoded parameters. Empty or unmatched parameters will be\n    // treated as `null` to normalize cross-browser behavior.\n    _extractParameters: function(route, fragment) {\n      var params = route.exec(fragment).slice(1);\n      return _.map(params, function(param, i) {\n        // Don't decode the search params.\n        if (i === params.length - 1) return param || null;\n        return param ? decodeURIComponent(param) : null;\n      });\n    }\n\n  });\n\n  // Backbone.History\n  // ----------------\n\n  // Handles cross-browser history management, based on either\n  // [pushState](http://diveintohtml5.info/history.html) and real URLs, or\n  // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)\n  // and URL fragments. If the browser supports neither (old IE, natch),\n  // falls back to polling.\n  var History = Backbone.History = function() {\n    this.handlers = [];\n    this.checkUrl = this.checkUrl.bind(this);\n\n    // Ensure that `History` can be used outside of the browser.\n    if (typeof window !== 'undefined') {\n      this.location = window.location;\n      this.history = window.history;\n    }\n  };\n\n  // Cached regex for stripping a leading hash/slash and trailing space.\n  var routeStripper = /^[#\\/]|\\s+$/g;\n\n  // Cached regex for stripping leading and trailing slashes.\n  var rootStripper = /^\\/+|\\/+$/g;\n\n  // Cached regex for stripping urls of hash.\n  var pathStripper = /#.*$/;\n\n  // Has the history handling already been started?\n  History.started = false;\n\n  // Set up all inheritable **Backbone.History** properties and methods.\n  _.extend(History.prototype, Events, {\n\n    // The default interval to poll for hash changes, if necessary, is\n    // twenty times a second.\n    interval: 50,\n\n    // Are we at the app root?\n    atRoot: function() {\n      var path = this.location.pathname.replace(/[^\\/]$/, '$&/');\n      return path === this.root && !this.getSearch();\n    },\n\n    // Does the pathname match the root?\n    matchRoot: function() {\n      var path = this.decodeFragment(this.location.pathname);\n      var rootPath = path.slice(0, this.root.length - 1) + '/';\n      return rootPath === this.root;\n    },\n\n    // Unicode characters in `location.pathname` are percent encoded so they're\n    // decoded for comparison. `%25` should not be decoded since it may be part\n    // of an encoded parameter.\n    decodeFragment: function(fragment) {\n      return decodeURI(fragment.replace(/%25/g, '%2525'));\n    },\n\n    // In IE6, the hash fragment and search params are incorrect if the\n    // fragment contains `?`.\n    getSearch: function() {\n      var match = this.location.href.replace(/#.*/, '').match(/\\?.+/);\n      return match ? match[0] : '';\n    },\n\n    // Gets the true hash value. Cannot use location.hash directly due to bug\n    // in Firefox where location.hash will always be decoded.\n    getHash: function(window) {\n      var match = (window || this).location.href.match(/#(.*)$/);\n      return match ? match[1] : '';\n    },\n\n    // Get the pathname and search params, without the root.\n    getPath: function() {\n      var path = this.decodeFragment(\n        this.location.pathname + this.getSearch()\n      ).slice(this.root.length - 1);\n      return path.charAt(0) === '/' ? path.slice(1) : path;\n    },\n\n    // Get the cross-browser normalized URL fragment from the path or hash.\n    getFragment: function(fragment) {\n      if (fragment == null) {\n        if (this._usePushState || !this._wantsHashChange) {\n          fragment = this.getPath();\n        } else {\n          fragment = this.getHash();\n        }\n      }\n      return fragment.replace(routeStripper, '');\n    },\n\n    // Start the hash change handling, returning `true` if the current URL matches\n    // an existing route, and `false` otherwise.\n    start: function(options) {\n      if (History.started) throw new Error('Backbone.history has already been started');\n      History.started = true;\n\n      // Figure out the initial configuration. Do we need an iframe?\n      // Is pushState desired ... is it available?\n      this.options          = _.extend({root: '/'}, this.options, options);\n      this.root             = this.options.root;\n      this._trailingSlash   = this.options.trailingSlash;\n      this._wantsHashChange = this.options.hashChange !== false;\n      this._hasHashChange   = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);\n      this._useHashChange   = this._wantsHashChange && this._hasHashChange;\n      this._wantsPushState  = !!this.options.pushState;\n      this._hasPushState    = !!(this.history && this.history.pushState);\n      this._usePushState    = this._wantsPushState && this._hasPushState;\n      this.fragment         = this.getFragment();\n\n      // Normalize root to always include a leading and trailing slash.\n      this.root = ('/' + this.root + '/').replace(rootStripper, '/');\n\n      // Transition from hashChange to pushState or vice versa if both are\n      // requested.\n      if (this._wantsHashChange && this._wantsPushState) {\n\n        // If we've started off with a route from a `pushState`-enabled\n        // browser, but we're currently in a browser that doesn't support it...\n        if (!this._hasPushState && !this.atRoot()) {\n          var rootPath = this.root.slice(0, -1) || '/';\n          this.location.replace(rootPath + '#' + this.getPath());\n          // Return immediately as browser will do redirect to new url\n          return true;\n\n        // Or if we've started out with a hash-based route, but we're currently\n        // in a browser where it could be `pushState`-based instead...\n        } else if (this._hasPushState && this.atRoot()) {\n          this.navigate(this.getHash(), {replace: true});\n        }\n\n      }\n\n      // Proxy an iframe to handle location events if the browser doesn't\n      // support the `hashchange` event, HTML5 history, or the user wants\n      // `hashChange` but not `pushState`.\n      if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {\n        this.iframe = document.createElement('iframe');\n        this.iframe.src = 'javascript:0';\n        this.iframe.style.display = 'none';\n        this.iframe.tabIndex = -1;\n        var body = document.body;\n        // Using `appendChild` will throw on IE < 9 if the document is not ready.\n        var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow;\n        iWindow.document.open();\n        iWindow.document.close();\n        iWindow.location.hash = '#' + this.fragment;\n      }\n\n      // Add a cross-platform `addEventListener` shim for older browsers.\n      var addEventListener = window.addEventListener || function(eventName, listener) {\n        return attachEvent('on' + eventName, listener);\n      };\n\n      // Depending on whether we're using pushState or hashes, and whether\n      // 'onhashchange' is supported, determine how we check the URL state.\n      if (this._usePushState) {\n        addEventListener('popstate', this.checkUrl, false);\n      } else if (this._useHashChange && !this.iframe) {\n        addEventListener('hashchange', this.checkUrl, false);\n      } else if (this._wantsHashChange) {\n        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);\n      }\n\n      if (!this.options.silent) return this.loadUrl();\n    },\n\n    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,\n    // but possibly useful for unit testing Routers.\n    stop: function() {\n      // Add a cross-platform `removeEventListener` shim for older browsers.\n      var removeEventListener = window.removeEventListener || function(eventName, listener) {\n        return detachEvent('on' + eventName, listener);\n      };\n\n      // Remove window listeners.\n      if (this._usePushState) {\n        removeEventListener('popstate', this.checkUrl, false);\n      } else if (this._useHashChange && !this.iframe) {\n        removeEventListener('hashchange', this.checkUrl, false);\n      }\n\n      // Clean up the iframe if necessary.\n      if (this.iframe) {\n        document.body.removeChild(this.iframe);\n        this.iframe = null;\n      }\n\n      // Some environments will throw when clearing an undefined interval.\n      if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);\n      History.started = false;\n    },\n\n    // Add a route to be tested when the fragment changes. Routes added later\n    // may override previous routes.\n    route: function(route, callback) {\n      this.handlers.unshift({route: route, callback: callback});\n    },\n\n    // Checks the current URL to see if it has changed, and if it has,\n    // calls `loadUrl`, normalizing across the hidden iframe.\n    checkUrl: function(e) {\n      var current = this.getFragment();\n\n      // If the user pressed the back button, the iframe's hash will have\n      // changed and we should use that for comparison.\n      if (current === this.fragment && this.iframe) {\n        current = this.getHash(this.iframe.contentWindow);\n      }\n\n      if (current === this.fragment) {\n        if (!this.matchRoot()) return this.notfound();\n        return false;\n      }\n      if (this.iframe) this.navigate(current);\n      this.loadUrl();\n    },\n\n    // Attempt to load the current URL fragment. If a route succeeds with a\n    // match, returns `true`. If no defined routes matches the fragment,\n    // returns `false`.\n    loadUrl: function(fragment) {\n      // If the root doesn't match, no routes can match either.\n      if (!this.matchRoot()) return this.notfound();\n      fragment = this.fragment = this.getFragment(fragment);\n      return _.some(this.handlers, function(handler) {\n        if (handler.route.test(fragment)) {\n          handler.callback(fragment);\n          return true;\n        }\n      }) || this.notfound();\n    },\n\n    // When no route could be matched, this method is called internally to\n    // trigger the `'notfound'` event. It returns `false` so that it can be used\n    // in tail position.\n    notfound: function() {\n      this.trigger('notfound');\n      return false;\n    },\n\n    // Save a fragment into the hash history, or replace the URL state if the\n    // 'replace' option is passed. You are responsible for properly URL-encoding\n    // the fragment in advance.\n    //\n    // The options object can contain `trigger: true` if you wish to have the\n    // route callback be fired (not usually desirable), or `replace: true`, if\n    // you wish to modify the current URL without adding an entry to the history.\n    navigate: function(fragment, options) {\n      if (!History.started) return false;\n      if (!options || options === true) options = {trigger: !!options};\n\n      // Normalize the fragment.\n      fragment = this.getFragment(fragment || '');\n\n      // Strip trailing slash on the root unless _trailingSlash is true\n      var rootPath = this.root;\n      if (!this._trailingSlash && (fragment === '' || fragment.charAt(0) === '?')) {\n        rootPath = rootPath.slice(0, -1) || '/';\n      }\n      var url = rootPath + fragment;\n\n      // Strip the fragment of the query and hash for matching.\n      fragment = fragment.replace(pathStripper, '');\n\n      // Decode for matching.\n      var decodedFragment = this.decodeFragment(fragment);\n\n      if (this.fragment === decodedFragment) return;\n      this.fragment = decodedFragment;\n\n      // If pushState is available, we use it to set the fragment as a real URL.\n      if (this._usePushState) {\n        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);\n\n      // If hash changes haven't been explicitly disabled, update the hash\n      // fragment to store history.\n      } else if (this._wantsHashChange) {\n        this._updateHash(this.location, fragment, options.replace);\n        if (this.iframe && fragment !== this.getHash(this.iframe.contentWindow)) {\n          var iWindow = this.iframe.contentWindow;\n\n          // Opening and closing the iframe tricks IE7 and earlier to push a\n          // history entry on hash-tag change.  When replace is true, we don't\n          // want this.\n          if (!options.replace) {\n            iWindow.document.open();\n            iWindow.document.close();\n          }\n\n          this._updateHash(iWindow.location, fragment, options.replace);\n        }\n\n      // If you've told us that you explicitly don't want fallback hashchange-\n      // based history, then `navigate` becomes a page refresh.\n      } else {\n        return this.location.assign(url);\n      }\n      if (options.trigger) return this.loadUrl(fragment);\n    },\n\n    // Update the hash location, either replacing the current entry, or adding\n    // a new one to the browser history.\n    _updateHash: function(location, fragment, replace) {\n      if (replace) {\n        var href = location.href.replace(/(javascript:|#).*$/, '');\n        location.replace(href + '#' + fragment);\n      } else {\n        // Some browsers require that `hash` contains a leading #.\n        location.hash = '#' + fragment;\n      }\n    }\n\n  });\n\n  // Create the default Backbone.history.\n  Backbone.history = new History;\n\n  // Helpers\n  // -------\n\n  // Helper function to correctly set up the prototype chain for subclasses.\n  // Similar to `goog.inherits`, but uses a hash of prototype properties and\n  // class properties to be extended.\n  var extend = function(protoProps, staticProps) {\n    var parent = this;\n    var child;\n\n    // The constructor function for the new subclass is either defined by you\n    // (the \"constructor\" property in your `extend` definition), or defaulted\n    // by us to simply call the parent constructor.\n    if (protoProps && _.has(protoProps, 'constructor')) {\n      child = protoProps.constructor;\n    } else {\n      child = function(){ return parent.apply(this, arguments); };\n    }\n\n    // Add static properties to the constructor function, if supplied.\n    _.extend(child, parent, staticProps);\n\n    // Set the prototype chain to inherit from `parent`, without calling\n    // `parent`'s constructor function and add the prototype properties.\n    child.prototype = _.create(parent.prototype, protoProps);\n    child.prototype.constructor = child;\n\n    // Set a convenience property in case the parent's prototype is needed\n    // later.\n    child.__super__ = parent.prototype;\n\n    return child;\n  };\n\n  // Set up inheritance for the model, collection, router, view and history.\n  Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;\n\n  // Throw an error when a URL is needed, and none is supplied.\n  var urlError = function() {\n    throw new Error('A \"url\" property or function must be specified');\n  };\n\n  // Wrap an optional error callback with a fallback error event.\n  var wrapError = function(model, options) {\n    var error = options.error;\n    options.error = function(resp) {\n      if (error) error.call(options.context, model, resp, options);\n      model.trigger('error', model, resp, options);\n    };\n  };\n\n  // Provide useful information when things go wrong. This method is not meant\n  // to be used directly; it merely provides the necessary introspection for the\n  // external `debugInfo` function.\n  Backbone._debug = function() {\n    return {root: root, _: _};\n  };\n\n  return Backbone;\n});\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\"          : \"backbone\",\n  \"main\"          : \"backbone.js\",\n  \"dependencies\"  : {\n    \"underscore\"  : \">=1.8.3\"\n  },\n  \"ignore\"        : [\"docs\", \"examples\", \"test\", \"*.yml\", \"*.html\", \"*.ico\", \"*.md\", \"CNAME\", \".*\", \"karma.*\", \"package.json\"]\n}\n"
  },
  {
    "path": "debug-info.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('backbone')) :\n  typeof define === 'function' && define.amd ? define(['backbone'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.Backbone = global.Backbone || {}, global.Backbone.debugInfo = factory(global.Backbone)));\n})(this, (function (Backbone) {\n  // Provide useful information when things go wrong.\n  function debugInfo() {\n    // Introspect Backbone.\n    var $ = Backbone.$, _b = Backbone._debug(), _ = _b._, root = _b.root;\n    // Use the `partialRight` function as a Lodash indicator. It was never in\n    // Underscore, has been in Lodash at least since version 1.3.1, and is\n    // unlikely to be mixed into Underscore since nobody needs it.\n    var lodash = !!_.partialRight;\n    var info = {\n      backbone: Backbone.VERSION,\n      // Is this the exact released version, or a later development version?\n      /* This is automatically temporarily replaced when publishing a release,\n         so please don't edit this. */\n      distribution: 'MARK_DEVELOPMENT',\n      _: (lodash ? 'lodash ' : '') + _.VERSION,\n      $: !$ ? false : $.fn && $.fn.jquery ? $.fn.jquery :\n        $.zepto ? 'zepto' : $.ender ? 'ender' : true\n    };\n    if (typeof root.Deno !== 'undefined') {\n      info.deno = _.pick(root.Deno, 'version', 'build');\n    } else if (typeof root.process !== 'undefined') {\n      info.process = _.pick(root.process, 'version', 'platform', 'arch');\n    } else if (typeof root.navigator !== 'undefined') {\n      info.navigator = _.pick(root.navigator, 'userAgent', 'platform', 'webdriver');\n    }\n    /* eslint-disable-next-line no-console */\n    console.debug('Backbone debug info: ', JSON.stringify(info, null, 4));\n    return info;\n  }\n\n  return debugInfo;\n\n}));\n"
  },
  {
    "path": "docs/backbone.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head>\n  <title>backbone.js</title>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;\">\n  <link rel=\"stylesheet\" media=\"all\" href=\"docco.css\" />\n</head>\n<body>\n  <div id=\"container\">\n    <div id=\"background\"></div>\n    \n    <ul class=\"sections\">\n        \n          <li id=\"title\">\n              <div class=\"annotation\">\n                  <h1>backbone.js</h1>\n              </div>\n          </li>\n        \n        \n        \n        <li id=\"section-1\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-1\">&#x00a7;</a>\n              </div>\n              <pre><code><span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">js</span> <span class=\"hljs-number\">1.6</span><span class=\"hljs-number\">.1</span>\n</code></pre>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-2\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-2\">&#x00a7;</a>\n              </div>\n              <pre><code>(c) <span class=\"hljs-number\">2010</span>-<span class=\"hljs-number\">2024</span> <span class=\"hljs-title class_\">Jeremy</span> <span class=\"hljs-title class_\">Ashkenas</span> and <span class=\"hljs-title class_\">DocumentCloud</span>\n<span class=\"hljs-title class_\">Backbone</span> may be freely distributed under the <span class=\"hljs-variable constant_\">MIT</span> license.\n<span class=\"hljs-title class_\">For</span> all details and <span class=\"hljs-attr\">documentation</span>:\n<span class=\"hljs-attr\">http</span>:<span class=\"hljs-comment\">//backbonejs.org</span>\n</code></pre>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>\n(<span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">factory</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-3\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-3\">&#x00a7;</a>\n              </div>\n              <p>Establish the root object, <code>window</code> (<code>self</code>) in the browser, or <code>global</code> on the server.\nWe use <code>self</code> instead of <code>window</code> for <code>WebWorker</code> support.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> root = <span class=\"hljs-keyword\">typeof</span> self == <span class=\"hljs-string\">&#x27;object&#x27;</span> &amp;&amp; self.<span class=\"hljs-property\">self</span> === self &amp;&amp; self ||\n            <span class=\"hljs-keyword\">typeof</span> <span class=\"hljs-variable language_\">global</span> == <span class=\"hljs-string\">&#x27;object&#x27;</span> &amp;&amp; <span class=\"hljs-variable language_\">global</span>.<span class=\"hljs-property\">global</span> === <span class=\"hljs-variable language_\">global</span> &amp;&amp; <span class=\"hljs-variable language_\">global</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-4\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-4\">&#x00a7;</a>\n              </div>\n              <p>Set up Backbone appropriately for the environment. Start with AMD.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-keyword\">typeof</span> define === <span class=\"hljs-string\">&#x27;function&#x27;</span> &amp;&amp; define.<span class=\"hljs-property\">amd</span>) {\n    <span class=\"hljs-title function_\">define</span>([<span class=\"hljs-string\">&#x27;underscore&#x27;</span>, <span class=\"hljs-string\">&#x27;jquery&#x27;</span>, <span class=\"hljs-string\">&#x27;exports&#x27;</span>], <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">_, $, <span class=\"hljs-built_in\">exports</span></span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-5\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-5\">&#x00a7;</a>\n              </div>\n              <p>Export global even in AMD case in case this script is loaded with\nothers that may still expect a global Backbone.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      root.<span class=\"hljs-property\">Backbone</span> = <span class=\"hljs-title function_\">factory</span>(root, <span class=\"hljs-built_in\">exports</span>, _, $);\n    });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-6\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-6\">&#x00a7;</a>\n              </div>\n              <p>Next for Node.js or CommonJS. jQuery may not be needed as a module.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-keyword\">typeof</span> <span class=\"hljs-built_in\">exports</span> !== <span class=\"hljs-string\">&#x27;undefined&#x27;</span>) {\n    <span class=\"hljs-keyword\">var</span> _ = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">&#x27;underscore&#x27;</span>), $;\n    <span class=\"hljs-keyword\">try</span> { $ = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">&#x27;jquery&#x27;</span>); } <span class=\"hljs-keyword\">catch</span> (e) {}\n    <span class=\"hljs-title function_\">factory</span>(root, <span class=\"hljs-built_in\">exports</span>, _, $);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-7\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-7\">&#x00a7;</a>\n              </div>\n              <p>Finally, as a browser global.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  } <span class=\"hljs-keyword\">else</span> {\n    root.<span class=\"hljs-property\">Backbone</span> = <span class=\"hljs-title function_\">factory</span>(root, {}, root.<span class=\"hljs-property\">_</span>, root.<span class=\"hljs-property\">jQuery</span> || root.<span class=\"hljs-property\">Zepto</span> || root.<span class=\"hljs-property\">ender</span> || root.<span class=\"hljs-property\">$</span>);\n  }\n\n})(<span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">root, Backbone, _, $</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-8\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-8\">&#x00a7;</a>\n              </div>\n              <h2 id=\"initial-setup\">Initial Setup</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-9\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-9\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-10\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-10\">&#x00a7;</a>\n              </div>\n              <p>Save the previous value of the <code>Backbone</code> variable, so that it can be\nrestored later on, if <code>noConflict</code> is used.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> previousBackbone = root.<span class=\"hljs-property\">Backbone</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-11\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-11\">&#x00a7;</a>\n              </div>\n              <p>Create a local reference to a common array method we’ll want to use later.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> slice = <span class=\"hljs-title class_\">Array</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>.<span class=\"hljs-property\">slice</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-12\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-12\">&#x00a7;</a>\n              </div>\n              <p>Current version of the library. Keep in sync with <code>package.json</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">VERSION</span> = <span class=\"hljs-string\">&#x27;1.6.1&#x27;</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-13\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-13\">&#x00a7;</a>\n              </div>\n              <p>For Backbone’s purposes, jQuery, Zepto, Ender, or My Library (kidding) owns\nthe <code>$</code> variable.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">$</span> = $;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-14\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-14\">&#x00a7;</a>\n              </div>\n              <p>Runs Backbone.js in <em>noConflict</em> mode, returning the <code>Backbone</code> variable\nto its previous owner. Returns a reference to this Backbone object.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">noConflict</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    root.<span class=\"hljs-property\">Backbone</span> = previousBackbone;\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-15\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-15\">&#x00a7;</a>\n              </div>\n              <p>Turn on <code>emulateHTTP</code> to support legacy HTTP servers. Setting this option\nwill fake <code>&quot;PATCH&quot;</code>, <code>&quot;PUT&quot;</code> and <code>&quot;DELETE&quot;</code> requests via the <code>_method</code> parameter and\nset a <code>X-Http-Method-Override</code> header.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">emulateHTTP</span> = <span class=\"hljs-literal\">false</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-16\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-16\">&#x00a7;</a>\n              </div>\n              <p>Turn on <code>emulateJSON</code> to support legacy servers that can’t deal with direct\n<code>application/json</code> requests … this will encode the body as\n<code>application/x-www-form-urlencoded</code> instead and will send the model in a\nform param named <code>model</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">emulateJSON</span> = <span class=\"hljs-literal\">false</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-17\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-17\">&#x00a7;</a>\n              </div>\n              <h2 id=\"backboneevents\">Backbone.Events</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-18\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-18\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-19\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-19\">&#x00a7;</a>\n              </div>\n              <p>A module that can be mixed in to <em>any object</em> in order to provide it with\na custom event channel. You may bind a callback to an event with <code>on</code> or\nremove with <code>off</code>; <code>trigger</code>-ing an event fires all callbacks in\nsuccession.</p>\n<pre><code><span class=\"hljs-keyword\">var</span> object = {};\n_.<span class=\"hljs-title function_\">extend</span>(object, <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">Events</span>);\nobject.<span class=\"hljs-title function_\">on</span>(<span class=\"hljs-string\">&#x27;expand&#x27;</span>, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){ <span class=\"hljs-title function_\">alert</span>(<span class=\"hljs-string\">&#x27;expanded&#x27;</span>); });\nobject.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;expand&#x27;</span>);\n</code></pre>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">Events</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">Events</span> = {};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-20\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-20\">&#x00a7;</a>\n              </div>\n              <p>Regular expression used to split event strings.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> eventSplitter = <span class=\"hljs-regexp\">/\\s+/</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-21\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-21\">&#x00a7;</a>\n              </div>\n              <p>A private global variable to share between listeners and listenees.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> _listening;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-22\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-22\">&#x00a7;</a>\n              </div>\n              <p>Iterates over the standard <code>event, callback</code> (as well as the fancy multiple\nspace-separated events <code>&quot;change blur&quot;, callback</code> and jQuery-style event\nmaps <code>{event: callback}</code>).</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> eventsApi = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">iteratee, events, name, callback, opts</span>) {\n    <span class=\"hljs-keyword\">var</span> i = <span class=\"hljs-number\">0</span>, names;\n    <span class=\"hljs-keyword\">if</span> (name &amp;&amp; <span class=\"hljs-keyword\">typeof</span> name === <span class=\"hljs-string\">&#x27;object&#x27;</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-23\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-23\">&#x00a7;</a>\n              </div>\n              <p>Handle event maps.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (callback !== <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span> &amp;&amp; <span class=\"hljs-string\">&#x27;context&#x27;</span> <span class=\"hljs-keyword\">in</span> opts &amp;&amp; opts.<span class=\"hljs-property\">context</span> === <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>) opts.<span class=\"hljs-property\">context</span> = callback;\n      <span class=\"hljs-keyword\">for</span> (names = _.<span class=\"hljs-title function_\">keys</span>(name); i &lt; names.<span class=\"hljs-property\">length</span> ; i++) {\n        events = <span class=\"hljs-title function_\">eventsApi</span>(iteratee, events, names[i], name[names[i]], opts);\n      }\n    } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (name &amp;&amp; eventSplitter.<span class=\"hljs-title function_\">test</span>(name)) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-24\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-24\">&#x00a7;</a>\n              </div>\n              <p>Handle space-separated event names by delegating them individually.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">for</span> (names = name.<span class=\"hljs-title function_\">split</span>(eventSplitter); i &lt; names.<span class=\"hljs-property\">length</span>; i++) {\n        events = <span class=\"hljs-title function_\">iteratee</span>(events, names[i], callback, opts);\n      }\n    } <span class=\"hljs-keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-25\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-25\">&#x00a7;</a>\n              </div>\n              <p>Finally, standard events.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      events = <span class=\"hljs-title function_\">iteratee</span>(events, name, callback, opts);\n    }\n    <span class=\"hljs-keyword\">return</span> events;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-26\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-26\">&#x00a7;</a>\n              </div>\n              <p>Bind an event to a <code>callback</code> function. Passing <code>&quot;all&quot;</code> will bind\nthe callback to all events fired.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">on</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">name, callback, context</span>) {\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span> = <span class=\"hljs-title function_\">eventsApi</span>(onApi, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span> || {}, name, callback, {\n      <span class=\"hljs-attr\">context</span>: context,\n      <span class=\"hljs-attr\">ctx</span>: <span class=\"hljs-variable language_\">this</span>,\n      <span class=\"hljs-attr\">listening</span>: _listening\n    });\n\n    <span class=\"hljs-keyword\">if</span> (_listening) {\n      <span class=\"hljs-keyword\">var</span> listeners = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_listeners</span> || (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_listeners</span> = {});\n      listeners[_listening.<span class=\"hljs-property\">id</span>] = _listening;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-27\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-27\">&#x00a7;</a>\n              </div>\n              <p>Allow the listening to use a counter, instead of tracking\ncallbacks for library interop</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      _listening.<span class=\"hljs-property\">interop</span> = <span class=\"hljs-literal\">false</span>;\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-28\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-28\">&#x00a7;</a>\n              </div>\n              <p>Inversion-of-control versions of <code>on</code>. Tell <em>this</em> object to listen to\nan event in another object… keeping track of what it’s listening to\nfor easier unbinding later.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">listenTo</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">obj, name, callback</span>) {\n    <span class=\"hljs-keyword\">if</span> (!obj) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    <span class=\"hljs-keyword\">var</span> id = obj.<span class=\"hljs-property\">_listenId</span> || (obj.<span class=\"hljs-property\">_listenId</span> = _.<span class=\"hljs-title function_\">uniqueId</span>(<span class=\"hljs-string\">&#x27;l&#x27;</span>));\n    <span class=\"hljs-keyword\">var</span> listeningTo = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_listeningTo</span> || (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_listeningTo</span> = {});\n    <span class=\"hljs-keyword\">var</span> listening = _listening = listeningTo[id];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-29\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-29\">&#x00a7;</a>\n              </div>\n              <p>This object is not listening to any other events on <code>obj</code> yet.\nSetup the necessary references to track the listening callbacks.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (!listening) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_listenId</span> || (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_listenId</span> = _.<span class=\"hljs-title function_\">uniqueId</span>(<span class=\"hljs-string\">&#x27;l&#x27;</span>));\n      listening = _listening = listeningTo[id] = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">Listening</span>(<span class=\"hljs-variable language_\">this</span>, obj);\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-30\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-30\">&#x00a7;</a>\n              </div>\n              <p>Bind callbacks on obj.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">var</span> error = <span class=\"hljs-title function_\">tryCatchOn</span>(obj, name, callback, <span class=\"hljs-variable language_\">this</span>);\n    _listening = <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>;\n\n    <span class=\"hljs-keyword\">if</span> (error) <span class=\"hljs-keyword\">throw</span> error;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-31\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-31\">&#x00a7;</a>\n              </div>\n              <p>If the target obj is not Backbone.Events, track events manually.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (listening.<span class=\"hljs-property\">interop</span>) listening.<span class=\"hljs-title function_\">on</span>(name, callback);\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-32\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-32\">&#x00a7;</a>\n              </div>\n              <p>The reducing API that adds a callback to the <code>events</code> object.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> onApi = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">events, name, callback, options</span>) {\n    <span class=\"hljs-keyword\">if</span> (callback) {\n      <span class=\"hljs-keyword\">var</span> handlers = events[name] || (events[name] = []);\n      <span class=\"hljs-keyword\">var</span> context = options.<span class=\"hljs-property\">context</span>, ctx = options.<span class=\"hljs-property\">ctx</span>, listening = options.<span class=\"hljs-property\">listening</span>;\n      <span class=\"hljs-keyword\">if</span> (listening) listening.<span class=\"hljs-property\">count</span>++;\n\n      handlers.<span class=\"hljs-title function_\">push</span>({<span class=\"hljs-attr\">callback</span>: callback, <span class=\"hljs-attr\">context</span>: context, <span class=\"hljs-attr\">ctx</span>: context || ctx, <span class=\"hljs-attr\">listening</span>: listening});\n    }\n    <span class=\"hljs-keyword\">return</span> events;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-33\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-33\">&#x00a7;</a>\n              </div>\n              <p>An try-catch guarded #on function, to prevent poisoning the global\n<code>_listening</code> variable.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> tryCatchOn = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">obj, name, callback, context</span>) {\n    <span class=\"hljs-keyword\">try</span> {\n      obj.<span class=\"hljs-title function_\">on</span>(name, callback, context);\n    } <span class=\"hljs-keyword\">catch</span> (e) {\n      <span class=\"hljs-keyword\">return</span> e;\n    }\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-34\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-34\">&#x00a7;</a>\n              </div>\n              <p>Remove one or many callbacks. If <code>context</code> is null, removes all\ncallbacks with that function. If <code>callback</code> is null, removes all\ncallbacks for the event. If <code>name</code> is null, removes all bound\ncallbacks for all events.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">off</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">name, callback, context</span>) {\n    <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span> = <span class=\"hljs-title function_\">eventsApi</span>(offApi, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span>, name, callback, {\n      <span class=\"hljs-attr\">context</span>: context,\n      <span class=\"hljs-attr\">listeners</span>: <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_listeners</span>\n    });\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-35\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-35\">&#x00a7;</a>\n              </div>\n              <p>Tell this object to stop listening to either specific events … or\nto every object it’s currently listening to.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">stopListening</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">obj, name, callback</span>) {\n    <span class=\"hljs-keyword\">var</span> listeningTo = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_listeningTo</span>;\n    <span class=\"hljs-keyword\">if</span> (!listeningTo) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n\n    <span class=\"hljs-keyword\">var</span> ids = obj ? [obj.<span class=\"hljs-property\">_listenId</span>] : _.<span class=\"hljs-title function_\">keys</span>(listeningTo);\n    <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> i = <span class=\"hljs-number\">0</span>; i &lt; ids.<span class=\"hljs-property\">length</span>; i++) {\n      <span class=\"hljs-keyword\">var</span> listening = listeningTo[ids[i]];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-36\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-36\">&#x00a7;</a>\n              </div>\n              <p>If listening doesn’t exist, this object is not currently\nlistening to obj. Break out early.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (!listening) <span class=\"hljs-keyword\">break</span>;\n\n      listening.<span class=\"hljs-property\">obj</span>.<span class=\"hljs-title function_\">off</span>(name, callback, <span class=\"hljs-variable language_\">this</span>);\n      <span class=\"hljs-keyword\">if</span> (listening.<span class=\"hljs-property\">interop</span>) listening.<span class=\"hljs-title function_\">off</span>(name, callback);\n    }\n    <span class=\"hljs-keyword\">if</span> (_.<span class=\"hljs-title function_\">isEmpty</span>(listeningTo)) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_listeningTo</span> = <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>;\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-37\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-37\">&#x00a7;</a>\n              </div>\n              <p>The reducing API that removes a callback from the <code>events</code> object.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> offApi = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">events, name, callback, options</span>) {\n    <span class=\"hljs-keyword\">if</span> (!events) <span class=\"hljs-keyword\">return</span>;\n\n    <span class=\"hljs-keyword\">var</span> context = options.<span class=\"hljs-property\">context</span>, listeners = options.<span class=\"hljs-property\">listeners</span>;\n    <span class=\"hljs-keyword\">var</span> i = <span class=\"hljs-number\">0</span>, names;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-38\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-38\">&#x00a7;</a>\n              </div>\n              <p>Delete all event listeners and “drop” events.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (!name &amp;&amp; !context &amp;&amp; !callback) {\n      <span class=\"hljs-keyword\">for</span> (names = _.<span class=\"hljs-title function_\">keys</span>(listeners); i &lt; names.<span class=\"hljs-property\">length</span>; i++) {\n        listeners[names[i]].<span class=\"hljs-title function_\">cleanup</span>();\n      }\n      <span class=\"hljs-keyword\">return</span>;\n    }\n\n    names = name ? [name] : _.<span class=\"hljs-title function_\">keys</span>(events);\n    <span class=\"hljs-keyword\">for</span> (; i &lt; names.<span class=\"hljs-property\">length</span>; i++) {\n      name = names[i];\n      <span class=\"hljs-keyword\">var</span> handlers = events[name];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-39\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-39\">&#x00a7;</a>\n              </div>\n              <p>Bail out if there are no events stored.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (!handlers) <span class=\"hljs-keyword\">break</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-40\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-40\">&#x00a7;</a>\n              </div>\n              <p>Find any remaining events.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> remaining = [];\n      <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> j = <span class=\"hljs-number\">0</span>; j &lt; handlers.<span class=\"hljs-property\">length</span>; j++) {\n        <span class=\"hljs-keyword\">var</span> handler = handlers[j];\n        <span class=\"hljs-keyword\">if</span> (\n          callback &amp;&amp; callback !== handler.<span class=\"hljs-property\">callback</span> &amp;&amp;\n            callback !== handler.<span class=\"hljs-property\">callback</span>.<span class=\"hljs-property\">_callback</span> ||\n              context &amp;&amp; context !== handler.<span class=\"hljs-property\">context</span>\n        ) {\n          remaining.<span class=\"hljs-title function_\">push</span>(handler);\n        } <span class=\"hljs-keyword\">else</span> {\n          <span class=\"hljs-keyword\">var</span> listening = handler.<span class=\"hljs-property\">listening</span>;\n          <span class=\"hljs-keyword\">if</span> (listening) listening.<span class=\"hljs-title function_\">off</span>(name, callback);\n        }\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-41\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-41\">&#x00a7;</a>\n              </div>\n              <p>Replace events if there are any remaining.  Otherwise, clean up.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (remaining.<span class=\"hljs-property\">length</span>) {\n        events[name] = remaining;\n      } <span class=\"hljs-keyword\">else</span> {\n        <span class=\"hljs-keyword\">delete</span> events[name];\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> events;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-42\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-42\">&#x00a7;</a>\n              </div>\n              <p>Bind an event to only be triggered a single time. After the first time\nthe callback is invoked, its listener will be removed. If multiple events\nare passed in using the space-separated syntax, the handler will fire\nonce for each event, not once for a combination of all events.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">once</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">name, callback, context</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-43\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-43\">&#x00a7;</a>\n              </div>\n              <p>Map the event into a <code>{event: once}</code> object.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">var</span> events = <span class=\"hljs-title function_\">eventsApi</span>(onceMap, {}, name, callback, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">off</span>.<span class=\"hljs-title function_\">bind</span>(<span class=\"hljs-variable language_\">this</span>));\n    <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-keyword\">typeof</span> name === <span class=\"hljs-string\">&#x27;string&#x27;</span> &amp;&amp; context == <span class=\"hljs-literal\">null</span>) callback = <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>;\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">on</span>(events, callback, context);\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-44\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-44\">&#x00a7;</a>\n              </div>\n              <p>Inversion-of-control versions of <code>once</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">listenToOnce</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">obj, name, callback</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-45\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-45\">&#x00a7;</a>\n              </div>\n              <p>Map the event into a <code>{event: once}</code> object.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">var</span> events = <span class=\"hljs-title function_\">eventsApi</span>(onceMap, {}, name, callback, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">stopListening</span>.<span class=\"hljs-title function_\">bind</span>(<span class=\"hljs-variable language_\">this</span>, obj));\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">listenTo</span>(obj, events);\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-46\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-46\">&#x00a7;</a>\n              </div>\n              <p>Reduces the event callbacks into a map of <code>{event: onceWrapper}</code>.\n<code>offer</code> unbinds the <code>onceWrapper</code> after it has been called.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> onceMap = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">map, name, callback, offer</span>) {\n    <span class=\"hljs-keyword\">if</span> (callback) {\n      <span class=\"hljs-keyword\">var</span> once = map[name] = _.<span class=\"hljs-title function_\">once</span>(<span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n        <span class=\"hljs-title function_\">offer</span>(name, once);\n        callback.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n      });\n      once.<span class=\"hljs-property\">_callback</span> = callback;\n    }\n    <span class=\"hljs-keyword\">return</span> map;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-47\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-47\">&#x00a7;</a>\n              </div>\n              <p>Trigger one or many events, firing all bound callbacks. Callbacks are\npassed the same arguments as <code>trigger</code> is, apart from the event name\n(unless you’re listening on <code>&quot;all&quot;</code>, which will cause your callback to\nreceive the true name of the event as the first argument).</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">trigger</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">name</span>) {\n    <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n\n    <span class=\"hljs-keyword\">var</span> length = <span class=\"hljs-title class_\">Math</span>.<span class=\"hljs-title function_\">max</span>(<span class=\"hljs-number\">0</span>, <span class=\"hljs-variable language_\">arguments</span>.<span class=\"hljs-property\">length</span> - <span class=\"hljs-number\">1</span>);\n    <span class=\"hljs-keyword\">var</span> args = <span class=\"hljs-title class_\">Array</span>(length);\n    <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> i = <span class=\"hljs-number\">0</span>; i &lt; length; i++) args[i] = <span class=\"hljs-variable language_\">arguments</span>[i + <span class=\"hljs-number\">1</span>];\n\n    <span class=\"hljs-title function_\">eventsApi</span>(triggerApi, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span>, name, <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>, args);\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-48\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-48\">&#x00a7;</a>\n              </div>\n              <p>Handles triggering the appropriate event callbacks.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> triggerApi = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">objEvents, name, callback, args</span>) {\n    <span class=\"hljs-keyword\">if</span> (objEvents) {\n      <span class=\"hljs-keyword\">var</span> events = objEvents[name];\n      <span class=\"hljs-keyword\">var</span> allEvents = objEvents.<span class=\"hljs-property\">all</span>;\n      <span class=\"hljs-keyword\">if</span> (events &amp;&amp; allEvents) allEvents = allEvents.<span class=\"hljs-title function_\">slice</span>();\n      <span class=\"hljs-keyword\">if</span> (events) <span class=\"hljs-title function_\">triggerEvents</span>(events, args);\n      <span class=\"hljs-keyword\">if</span> (allEvents) <span class=\"hljs-title function_\">triggerEvents</span>(allEvents, [name].<span class=\"hljs-title function_\">concat</span>(args));\n    }\n    <span class=\"hljs-keyword\">return</span> objEvents;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-49\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-49\">&#x00a7;</a>\n              </div>\n              <p>A difficult-to-believe, but optimized internal dispatch function for\ntriggering events. Tries to keep the usual cases speedy (most internal\nBackbone events have 3 arguments).</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> triggerEvents = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">events, args</span>) {\n    <span class=\"hljs-keyword\">var</span> ev, i = -<span class=\"hljs-number\">1</span>, l = events.<span class=\"hljs-property\">length</span>, a1 = args[<span class=\"hljs-number\">0</span>], a2 = args[<span class=\"hljs-number\">1</span>], a3 = args[<span class=\"hljs-number\">2</span>];\n    <span class=\"hljs-keyword\">switch</span> (args.<span class=\"hljs-property\">length</span>) {\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-number\">0</span>: <span class=\"hljs-keyword\">while</span> (++i &lt; l) (ev = events[i]).<span class=\"hljs-property\">callback</span>.<span class=\"hljs-title function_\">call</span>(ev.<span class=\"hljs-property\">ctx</span>); <span class=\"hljs-keyword\">return</span>;\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-number\">1</span>: <span class=\"hljs-keyword\">while</span> (++i &lt; l) (ev = events[i]).<span class=\"hljs-property\">callback</span>.<span class=\"hljs-title function_\">call</span>(ev.<span class=\"hljs-property\">ctx</span>, a1); <span class=\"hljs-keyword\">return</span>;\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-number\">2</span>: <span class=\"hljs-keyword\">while</span> (++i &lt; l) (ev = events[i]).<span class=\"hljs-property\">callback</span>.<span class=\"hljs-title function_\">call</span>(ev.<span class=\"hljs-property\">ctx</span>, a1, a2); <span class=\"hljs-keyword\">return</span>;\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-number\">3</span>: <span class=\"hljs-keyword\">while</span> (++i &lt; l) (ev = events[i]).<span class=\"hljs-property\">callback</span>.<span class=\"hljs-title function_\">call</span>(ev.<span class=\"hljs-property\">ctx</span>, a1, a2, a3); <span class=\"hljs-keyword\">return</span>;\n      <span class=\"hljs-attr\">default</span>: <span class=\"hljs-keyword\">while</span> (++i &lt; l) (ev = events[i]).<span class=\"hljs-property\">callback</span>.<span class=\"hljs-title function_\">apply</span>(ev.<span class=\"hljs-property\">ctx</span>, args); <span class=\"hljs-keyword\">return</span>;\n    }\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-50\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-50\">&#x00a7;</a>\n              </div>\n              <p>A listening class that tracks and cleans up memory bindings\nwhen all callbacks have been offed.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">Listening</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">listener, obj</span>) {\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">id</span> = listener.<span class=\"hljs-property\">_listenId</span>;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">listener</span> = listener;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">obj</span> = obj;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">interop</span> = <span class=\"hljs-literal\">true</span>;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">count</span> = <span class=\"hljs-number\">0</span>;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span> = <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>;\n  };\n\n  <span class=\"hljs-title class_\">Listening</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>.<span class=\"hljs-property\">on</span> = <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">on</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-51\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-51\">&#x00a7;</a>\n              </div>\n              <p>Offs a callback (or several).\nUses an optimized counter if the listenee uses Backbone.Events.\nOtherwise, falls back to manual tracking to support events\nlibrary interop.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Listening</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>.<span class=\"hljs-property\">off</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">name, callback</span>) {\n    <span class=\"hljs-keyword\">var</span> cleanup;\n    <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">interop</span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span> = <span class=\"hljs-title function_\">eventsApi</span>(offApi, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span>, name, callback, {\n        <span class=\"hljs-attr\">context</span>: <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>,\n        <span class=\"hljs-attr\">listeners</span>: <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>\n      });\n      cleanup = !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_events</span>;\n    } <span class=\"hljs-keyword\">else</span> {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">count</span>--;\n      cleanup = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">count</span> === <span class=\"hljs-number\">0</span>;\n    }\n    <span class=\"hljs-keyword\">if</span> (cleanup) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">cleanup</span>();\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-52\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-52\">&#x00a7;</a>\n              </div>\n              <p>Cleans up memory bindings between the listener and the listenee.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Listening</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>.<span class=\"hljs-property\">cleanup</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    <span class=\"hljs-keyword\">delete</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">listener</span>.<span class=\"hljs-property\">_listeningTo</span>[<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">obj</span>.<span class=\"hljs-property\">_listenId</span>];\n    <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">interop</span>) <span class=\"hljs-keyword\">delete</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">obj</span>.<span class=\"hljs-property\">_listeners</span>[<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">id</span>];\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-53\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-53\">&#x00a7;</a>\n              </div>\n              <p>Aliases for backwards compatibility.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">bind</span>   = <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">on</span>;\n  <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">unbind</span> = <span class=\"hljs-title class_\">Events</span>.<span class=\"hljs-property\">off</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-54\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-54\">&#x00a7;</a>\n              </div>\n              <p>Allow the <code>Backbone</code> object to serve as a global event bus, for folks who\nwant global “pubsub” in a convenient place.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  _.<span class=\"hljs-title function_\">extend</span>(<span class=\"hljs-title class_\">Backbone</span>, <span class=\"hljs-title class_\">Events</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-55\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-55\">&#x00a7;</a>\n              </div>\n              <h2 id=\"backbonemodel\">Backbone.Model</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-56\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-56\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-57\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-57\">&#x00a7;</a>\n              </div>\n              <p>Backbone <strong>Models</strong> are the basic data object in the framework –\nfrequently representing a row in a table in a database on your server.\nA discrete chunk of data and a bunch of useful, related methods for\nperforming computations and transformations on that data.</p>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-58\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-58\">&#x00a7;</a>\n              </div>\n              <p>Create a new model with the specified attributes. A client id (<code>cid</code>)\nis automatically generated and assigned for you.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">Model</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">Model</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attributes, options</span>) {\n    <span class=\"hljs-keyword\">var</span> attrs = attributes || {};\n    options || (options = {});\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">preinitialize</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">cid</span> = _.<span class=\"hljs-title function_\">uniqueId</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">cidPrefix</span>);\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span> = {};\n    <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">collection</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">collection</span> = options.<span class=\"hljs-property\">collection</span>;\n    <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">parse</span>) attrs = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">parse</span>(attrs, options) || {};\n    <span class=\"hljs-keyword\">var</span> defaults = _.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-string\">&#x27;defaults&#x27;</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-59\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-59\">&#x00a7;</a>\n              </div>\n              <p>Just _.defaults would work fine, but the additional _.extends\nis in there for historical reasons. See #3843.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    attrs = _.<span class=\"hljs-title function_\">defaults</span>(_.<span class=\"hljs-title function_\">extend</span>({}, defaults, attrs), defaults);\n\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">set</span>(attrs, options);\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">changed</span> = {};\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">initialize</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-60\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-60\">&#x00a7;</a>\n              </div>\n              <p>Attach all inheritable methods to the Model prototype.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  _.<span class=\"hljs-title function_\">extend</span>(<span class=\"hljs-title class_\">Model</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>, <span class=\"hljs-title class_\">Events</span>, {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-61\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-61\">&#x00a7;</a>\n              </div>\n              <p>A hash of attributes whose current and previous value differ.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">changed</span>: <span class=\"hljs-literal\">null</span>,</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-62\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-62\">&#x00a7;</a>\n              </div>\n              <p>The value returned during the last failed validation.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">validationError</span>: <span class=\"hljs-literal\">null</span>,</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-63\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-63\">&#x00a7;</a>\n              </div>\n              <p>The default name for the JSON <code>id</code> attribute is <code>&quot;id&quot;</code>. MongoDB and\nCouchDB users may want to set this to <code>&quot;_id&quot;</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">idAttribute</span>: <span class=\"hljs-string\">&#x27;id&#x27;</span>,</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-64\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-64\">&#x00a7;</a>\n              </div>\n              <p>The prefix is used to create the client id which is used to identify models locally.\nYou may want to override this if you’re experiencing name clashes with model ids.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">cidPrefix</span>: <span class=\"hljs-string\">&#x27;c&#x27;</span>,</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-65\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-65\">&#x00a7;</a>\n              </div>\n              <p>preinitialize is an empty function by default. You can override it with a function\nor object.  preinitialize will run before any instantiation logic is run in the Model.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">preinitialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){},</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-66\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-66\">&#x00a7;</a>\n              </div>\n              <p>Initialize is an empty function by default. Override it with your own\ninitialization logic.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">initialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){},</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-67\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-67\">&#x00a7;</a>\n              </div>\n              <p>Return a copy of the model’s <code>attributes</code> object.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">toJSON</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      <span class=\"hljs-keyword\">return</span> _.<span class=\"hljs-title function_\">clone</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-68\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-68\">&#x00a7;</a>\n              </div>\n              <p>Proxy <code>Backbone.sync</code> by default – but override this if you need\ncustom syncing semantics for <em>this</em> particular model.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">sync</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">sync</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-69\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-69\">&#x00a7;</a>\n              </div>\n              <p>Get the value of an attribute.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">get</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attr</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span>[attr];\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-70\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-70\">&#x00a7;</a>\n              </div>\n              <p>Get the HTML-escaped value of an attribute.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">escape</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attr</span>) {\n      <span class=\"hljs-keyword\">return</span> _.<span class=\"hljs-built_in\">escape</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">get</span>(attr));\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-71\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-71\">&#x00a7;</a>\n              </div>\n              <p>Returns <code>true</code> if the attribute contains a value that is not null\nor undefined.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">has</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attr</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">get</span>(attr) != <span class=\"hljs-literal\">null</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-72\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-72\">&#x00a7;</a>\n              </div>\n              <p>Special-cased proxy to underscore’s <code>_.matches</code> method.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">matches</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attrs</span>) {\n      <span class=\"hljs-keyword\">return</span> !!_.<span class=\"hljs-title function_\">iteratee</span>(attrs, <span class=\"hljs-variable language_\">this</span>)(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-73\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-73\">&#x00a7;</a>\n              </div>\n              <p>Set a hash of model attributes on the object, firing <code>&quot;change&quot;</code>. This is\nthe core primitive operation of a model, updating the data and notifying\nanyone who needs to know about the change in state. The heart of the beast.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">set</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">key, val, options</span>) {\n      <span class=\"hljs-keyword\">if</span> (key == <span class=\"hljs-literal\">null</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-74\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-74\">&#x00a7;</a>\n              </div>\n              <p>Handle both <code>&quot;key&quot;, value</code> and <code>{key: value}</code> -style arguments.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> attrs;\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-keyword\">typeof</span> key === <span class=\"hljs-string\">&#x27;object&#x27;</span>) {\n        attrs = key;\n        options = val;\n      } <span class=\"hljs-keyword\">else</span> {\n        (attrs = {})[key] = val;\n      }\n\n      options || (options = {});</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-75\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-75\">&#x00a7;</a>\n              </div>\n              <p>Run validation.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_validate</span>(attrs, options)) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-76\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-76\">&#x00a7;</a>\n              </div>\n              <p>Extract attributes and options.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> unset      = options.<span class=\"hljs-property\">unset</span>;\n      <span class=\"hljs-keyword\">var</span> silent     = options.<span class=\"hljs-property\">silent</span>;\n      <span class=\"hljs-keyword\">var</span> changes    = [];\n      <span class=\"hljs-keyword\">var</span> changing   = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_changing</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_changing</span> = <span class=\"hljs-literal\">true</span>;\n\n      <span class=\"hljs-keyword\">if</span> (!changing) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_previousAttributes</span> = _.<span class=\"hljs-title function_\">clone</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span>);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">changed</span> = {};\n      }\n\n      <span class=\"hljs-keyword\">var</span> current = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span>;\n      <span class=\"hljs-keyword\">var</span> changed = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">changed</span>;\n      <span class=\"hljs-keyword\">var</span> prev    = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_previousAttributes</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-77\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-77\">&#x00a7;</a>\n              </div>\n              <p>For each <code>set</code> attribute, update or delete the current value.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> attr <span class=\"hljs-keyword\">in</span> attrs) {\n        val = attrs[attr];\n        <span class=\"hljs-keyword\">if</span> (!_.<span class=\"hljs-title function_\">isEqual</span>(current[attr], val)) changes.<span class=\"hljs-title function_\">push</span>(attr);\n        <span class=\"hljs-keyword\">if</span> (!_.<span class=\"hljs-title function_\">isEqual</span>(prev[attr], val)) {\n          changed[attr] = val;\n        } <span class=\"hljs-keyword\">else</span> {\n          <span class=\"hljs-keyword\">delete</span> changed[attr];\n        }\n        unset ? <span class=\"hljs-keyword\">delete</span> current[attr] : current[attr] = val;\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-78\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-78\">&#x00a7;</a>\n              </div>\n              <p>Update the <code>id</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">idAttribute</span> <span class=\"hljs-keyword\">in</span> attrs) {\n        <span class=\"hljs-keyword\">var</span> prevId = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">id</span>;\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">id</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">get</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">idAttribute</span>);\n        <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">id</span> !== prevId) {\n          <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;changeId&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, prevId, options);\n        }\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-79\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-79\">&#x00a7;</a>\n              </div>\n              <p>Trigger all relevant attribute changes.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (!silent) {\n        <span class=\"hljs-keyword\">if</span> (changes.<span class=\"hljs-property\">length</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_pending</span> = options;\n        <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> i = <span class=\"hljs-number\">0</span>; i &lt; changes.<span class=\"hljs-property\">length</span>; i++) {\n          <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;change:&#x27;</span> + changes[i], <span class=\"hljs-variable language_\">this</span>, current[changes[i]], options);\n        }\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-80\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-80\">&#x00a7;</a>\n              </div>\n              <p>You might be wondering why there’s a <code>while</code> loop here. Changes can\nbe recursively nested within <code>&quot;change&quot;</code> events.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (changing) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n      <span class=\"hljs-keyword\">if</span> (!silent) {\n        <span class=\"hljs-keyword\">while</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_pending</span>) {\n          options = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_pending</span>;\n          <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_pending</span> = <span class=\"hljs-literal\">false</span>;\n          <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;change&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, options);\n        }\n      }\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_pending</span> = <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_changing</span> = <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-81\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-81\">&#x00a7;</a>\n              </div>\n              <p>Remove an attribute from the model, firing <code>&quot;change&quot;</code>. <code>unset</code> is a noop\nif the attribute doesn’t exist.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">unset</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attr, options</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">set</span>(attr, <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>, _.<span class=\"hljs-title function_\">extend</span>({}, options, {<span class=\"hljs-attr\">unset</span>: <span class=\"hljs-literal\">true</span>}));\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-82\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-82\">&#x00a7;</a>\n              </div>\n              <p>Clear all attributes on the model, firing <code>&quot;change&quot;</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">clear</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      <span class=\"hljs-keyword\">var</span> attrs = {};\n      <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> key <span class=\"hljs-keyword\">in</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span>) attrs[key] = <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>;\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">set</span>(attrs, _.<span class=\"hljs-title function_\">extend</span>({}, options, {<span class=\"hljs-attr\">unset</span>: <span class=\"hljs-literal\">true</span>}));\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-83\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-83\">&#x00a7;</a>\n              </div>\n              <p>Determine if the model has changed since the last <code>&quot;change&quot;</code> event.\nIf you specify an attribute name, determine if that attribute has changed.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">hasChanged</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attr</span>) {\n      <span class=\"hljs-keyword\">if</span> (attr == <span class=\"hljs-literal\">null</span>) <span class=\"hljs-keyword\">return</span> !_.<span class=\"hljs-title function_\">isEmpty</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">changed</span>);\n      <span class=\"hljs-keyword\">return</span> _.<span class=\"hljs-title function_\">has</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">changed</span>, attr);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-84\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-84\">&#x00a7;</a>\n              </div>\n              <p>Return an object containing all the attributes that have changed, or\nfalse if there are no changed attributes. Useful for determining what\nparts of a view need to be updated and/or what attributes need to be\npersisted to the server. Unset attributes will be set to undefined.\nYou can also pass an attributes object to diff against the model,\ndetermining if there <em>would be</em> a change.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">changedAttributes</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">diff</span>) {\n      <span class=\"hljs-keyword\">if</span> (!diff) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">hasChanged</span>() ? _.<span class=\"hljs-title function_\">clone</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">changed</span>) : <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-keyword\">var</span> old = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_changing</span> ? <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_previousAttributes</span> : <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span>;\n      <span class=\"hljs-keyword\">var</span> changed = {};\n      <span class=\"hljs-keyword\">var</span> hasChanged;\n      <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> attr <span class=\"hljs-keyword\">in</span> diff) {\n        <span class=\"hljs-keyword\">var</span> val = diff[attr];\n        <span class=\"hljs-keyword\">if</span> (_.<span class=\"hljs-title function_\">isEqual</span>(old[attr], val)) <span class=\"hljs-keyword\">continue</span>;\n        changed[attr] = val;\n        hasChanged = <span class=\"hljs-literal\">true</span>;\n      }\n      <span class=\"hljs-keyword\">return</span> hasChanged ? changed : <span class=\"hljs-literal\">false</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-85\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-85\">&#x00a7;</a>\n              </div>\n              <p>Get the previous value of an attribute, recorded at the time the last\n<code>&quot;change&quot;</code> event was fired.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">previous</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attr</span>) {\n      <span class=\"hljs-keyword\">if</span> (attr == <span class=\"hljs-literal\">null</span> || !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_previousAttributes</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">null</span>;\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_previousAttributes</span>[attr];\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-86\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-86\">&#x00a7;</a>\n              </div>\n              <p>Get all of the attributes of the model at the time of the previous\n<code>&quot;change&quot;</code> event.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">previousAttributes</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> _.<span class=\"hljs-title function_\">clone</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_previousAttributes</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-87\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-87\">&#x00a7;</a>\n              </div>\n              <p>Fetch the model from the server, merging the response with the model’s\nlocal attributes. Any changed attributes will trigger a “change” event.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">fetch</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      options = _.<span class=\"hljs-title function_\">extend</span>({<span class=\"hljs-attr\">parse</span>: <span class=\"hljs-literal\">true</span>}, options);\n      <span class=\"hljs-keyword\">var</span> model = <span class=\"hljs-variable language_\">this</span>;\n      <span class=\"hljs-keyword\">var</span> success = options.<span class=\"hljs-property\">success</span>;\n      options.<span class=\"hljs-property\">success</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">resp</span>) {\n        <span class=\"hljs-keyword\">var</span> serverAttrs = options.<span class=\"hljs-property\">parse</span> ? model.<span class=\"hljs-title function_\">parse</span>(resp, options) : resp;\n        <span class=\"hljs-keyword\">if</span> (!model.<span class=\"hljs-title function_\">set</span>(serverAttrs, options)) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n        <span class=\"hljs-keyword\">if</span> (success) success.<span class=\"hljs-title function_\">call</span>(options.<span class=\"hljs-property\">context</span>, model, resp, options);\n        model.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;sync&#x27;</span>, model, resp, options);\n      };\n      <span class=\"hljs-title function_\">wrapError</span>(<span class=\"hljs-variable language_\">this</span>, options);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">sync</span>(<span class=\"hljs-string\">&#x27;read&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, options);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-88\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-88\">&#x00a7;</a>\n              </div>\n              <p>Set a hash of model attributes, and sync the model to the server.\nIf the server returns an attributes hash that differs, the model’s\nstate will be <code>set</code> again.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">save</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">key, val, options</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-89\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-89\">&#x00a7;</a>\n              </div>\n              <p>Handle both <code>&quot;key&quot;, value</code> and <code>{key: value}</code> -style arguments.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> attrs;\n      <span class=\"hljs-keyword\">if</span> (key == <span class=\"hljs-literal\">null</span> || <span class=\"hljs-keyword\">typeof</span> key === <span class=\"hljs-string\">&#x27;object&#x27;</span>) {\n        attrs = key;\n        options = val;\n      } <span class=\"hljs-keyword\">else</span> {\n        (attrs = {})[key] = val;\n      }\n\n      options = _.<span class=\"hljs-title function_\">extend</span>({<span class=\"hljs-attr\">validate</span>: <span class=\"hljs-literal\">true</span>, <span class=\"hljs-attr\">parse</span>: <span class=\"hljs-literal\">true</span>}, options);\n      <span class=\"hljs-keyword\">var</span> wait = options.<span class=\"hljs-property\">wait</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-90\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-90\">&#x00a7;</a>\n              </div>\n              <p>If we’re not waiting and attributes exist, save acts as\n<code>set(attr).save(null, opts)</code> with validation. Otherwise, check if\nthe model will be valid when the attributes, if any, are set.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (attrs &amp;&amp; !wait) {\n        <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">set</span>(attrs, options)) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_validate</span>(attrs, options)) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-91\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-91\">&#x00a7;</a>\n              </div>\n              <p>After a successful server-side save, the client is (optionally)\nupdated with the server-side state.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> model = <span class=\"hljs-variable language_\">this</span>;\n      <span class=\"hljs-keyword\">var</span> success = options.<span class=\"hljs-property\">success</span>;\n      <span class=\"hljs-keyword\">var</span> attributes = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span>;\n      options.<span class=\"hljs-property\">success</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">resp</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-92\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-92\">&#x00a7;</a>\n              </div>\n              <p>Ensure attributes are restored during synchronous saves.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        model.<span class=\"hljs-property\">attributes</span> = attributes;\n        <span class=\"hljs-keyword\">var</span> serverAttrs = options.<span class=\"hljs-property\">parse</span> ? model.<span class=\"hljs-title function_\">parse</span>(resp, options) : resp;\n        <span class=\"hljs-keyword\">if</span> (wait) serverAttrs = _.<span class=\"hljs-title function_\">extend</span>({}, attrs, serverAttrs);\n        <span class=\"hljs-keyword\">if</span> (serverAttrs &amp;&amp; !model.<span class=\"hljs-title function_\">set</span>(serverAttrs, options)) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n        <span class=\"hljs-keyword\">if</span> (success) success.<span class=\"hljs-title function_\">call</span>(options.<span class=\"hljs-property\">context</span>, model, resp, options);\n        model.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;sync&#x27;</span>, model, resp, options);\n      };\n      <span class=\"hljs-title function_\">wrapError</span>(<span class=\"hljs-variable language_\">this</span>, options);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-93\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-93\">&#x00a7;</a>\n              </div>\n              <p>Set temporary attributes if <code>{wait: true}</code> to properly find new ids.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (attrs &amp;&amp; wait) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span> = _.<span class=\"hljs-title function_\">extend</span>({}, attributes, attrs);\n\n      <span class=\"hljs-keyword\">var</span> method = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">isNew</span>() ? <span class=\"hljs-string\">&#x27;create&#x27;</span> : options.<span class=\"hljs-property\">patch</span> ? <span class=\"hljs-string\">&#x27;patch&#x27;</span> : <span class=\"hljs-string\">&#x27;update&#x27;</span>;\n      <span class=\"hljs-keyword\">if</span> (method === <span class=\"hljs-string\">&#x27;patch&#x27;</span> &amp;&amp; !options.<span class=\"hljs-property\">attrs</span>) options.<span class=\"hljs-property\">attrs</span> = attrs;\n      <span class=\"hljs-keyword\">var</span> xhr = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">sync</span>(method, <span class=\"hljs-variable language_\">this</span>, options);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-94\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-94\">&#x00a7;</a>\n              </div>\n              <p>Restore attributes.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span> = attributes;\n\n      <span class=\"hljs-keyword\">return</span> xhr;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-95\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-95\">&#x00a7;</a>\n              </div>\n              <p>Destroy this model on the server if it was already persisted.\nOptimistically removes the model from its collection, if it has one.\nIf <code>wait: true</code> is passed, waits for the server to respond before removal.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">destroy</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      options = options ? _.<span class=\"hljs-title function_\">clone</span>(options) : {};\n      <span class=\"hljs-keyword\">var</span> model = <span class=\"hljs-variable language_\">this</span>;\n      <span class=\"hljs-keyword\">var</span> success = options.<span class=\"hljs-property\">success</span>;\n      <span class=\"hljs-keyword\">var</span> wait = options.<span class=\"hljs-property\">wait</span>;\n\n      <span class=\"hljs-keyword\">var</span> destroy = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n        model.<span class=\"hljs-title function_\">stopListening</span>();\n        model.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;destroy&#x27;</span>, model, model.<span class=\"hljs-property\">collection</span>, options);\n      };\n\n      options.<span class=\"hljs-property\">success</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">resp</span>) {\n        <span class=\"hljs-keyword\">if</span> (wait) <span class=\"hljs-title function_\">destroy</span>();\n        <span class=\"hljs-keyword\">if</span> (success) success.<span class=\"hljs-title function_\">call</span>(options.<span class=\"hljs-property\">context</span>, model, resp, options);\n        <span class=\"hljs-keyword\">if</span> (!model.<span class=\"hljs-title function_\">isNew</span>()) model.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;sync&#x27;</span>, model, resp, options);\n      };\n\n      <span class=\"hljs-keyword\">var</span> xhr = <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">isNew</span>()) {\n        _.<span class=\"hljs-title function_\">defer</span>(options.<span class=\"hljs-property\">success</span>);\n      } <span class=\"hljs-keyword\">else</span> {\n        <span class=\"hljs-title function_\">wrapError</span>(<span class=\"hljs-variable language_\">this</span>, options);\n        xhr = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">sync</span>(<span class=\"hljs-string\">&#x27;delete&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, options);\n      }\n      <span class=\"hljs-keyword\">if</span> (!wait) <span class=\"hljs-title function_\">destroy</span>();\n      <span class=\"hljs-keyword\">return</span> xhr;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-96\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-96\">&#x00a7;</a>\n              </div>\n              <p>Default URL for the model’s representation on the server – if you’re\nusing Backbone’s restful methods, override this to change the endpoint\nthat will be called.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">url</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">var</span> base =\n        _.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-string\">&#x27;urlRoot&#x27;</span>) ||\n        _.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">collection</span>, <span class=\"hljs-string\">&#x27;url&#x27;</span>) ||\n        <span class=\"hljs-title function_\">urlError</span>();\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">isNew</span>()) <span class=\"hljs-keyword\">return</span> base;\n      <span class=\"hljs-keyword\">var</span> id = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">get</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">idAttribute</span>);\n      <span class=\"hljs-keyword\">return</span> base.<span class=\"hljs-title function_\">replace</span>(<span class=\"hljs-regexp\">/[^\\/]$/</span>, <span class=\"hljs-string\">&#x27;$&amp;/&#x27;</span>) + <span class=\"hljs-built_in\">encodeURIComponent</span>(id);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-97\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-97\">&#x00a7;</a>\n              </div>\n              <p><strong>parse</strong> converts a response into the hash of attributes to be <code>set</code> on\nthe model. The default implementation is just to pass the response along.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">parse</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">resp, options</span>) {\n      <span class=\"hljs-keyword\">return</span> resp;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-98\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-98\">&#x00a7;</a>\n              </div>\n              <p>Create a new model with identical attributes to this one.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">clone</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">new</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">constructor</span>(<span class=\"hljs-params\"><span class=\"hljs-variable language_\">this</span>.attributes</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-99\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-99\">&#x00a7;</a>\n              </div>\n              <p>A model is new if it has never been saved to the server, and lacks an id.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">isNew</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">has</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">idAttribute</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-100\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-100\">&#x00a7;</a>\n              </div>\n              <p>Check if the model is currently in a valid state.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">isValid</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_validate</span>({}, _.<span class=\"hljs-title function_\">extend</span>({}, options, {<span class=\"hljs-attr\">validate</span>: <span class=\"hljs-literal\">true</span>}));\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-101\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-101\">&#x00a7;</a>\n              </div>\n              <p>Run validation against the next complete set of model attributes,\nreturning <code>true</code> if all is well. Otherwise, fire an <code>&quot;invalid&quot;</code> event.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_validate</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attrs, options</span>) {\n      <span class=\"hljs-keyword\">if</span> (!options.<span class=\"hljs-property\">validate</span> || !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">validate</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n      attrs = _.<span class=\"hljs-title function_\">extend</span>({}, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">attributes</span>, attrs);\n      <span class=\"hljs-keyword\">var</span> error = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">validationError</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">validate</span>(attrs, options) || <span class=\"hljs-literal\">null</span>;\n      <span class=\"hljs-keyword\">if</span> (!error) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;invalid&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, error, _.<span class=\"hljs-title function_\">extend</span>(options, {<span class=\"hljs-attr\">validationError</span>: error}));\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n    }\n\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-102\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-102\">&#x00a7;</a>\n              </div>\n              <h2 id=\"backbonecollection\">Backbone.Collection</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-103\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-103\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-104\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-104\">&#x00a7;</a>\n              </div>\n              <p>If models tend to represent a single row of data, a Backbone Collection is\nmore analogous to a table full of data … or a small slice or page of that\ntable, or a collection of rows that belong together for a particular reason\n– all of the messages in this particular folder, all of the documents\nbelonging to this particular author, and so on. Collections maintain\nindexes of their models, both in order, and for lookup by <code>id</code>.</p>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-105\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-105\">&#x00a7;</a>\n              </div>\n              <p>Create a new <strong>Collection</strong>, perhaps to contain a specific type of <code>model</code>.\nIf a <code>comparator</code> is specified, the Collection will maintain\nits models in sort order, as they’re added and removed.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">Collection</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">Collection</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">models, options</span>) {\n    options || (options = {});\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">preinitialize</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n    <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">model</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span> = options.<span class=\"hljs-property\">model</span>;\n    <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">comparator</span> !== <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">comparator</span> = options.<span class=\"hljs-property\">comparator</span>;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_reset</span>();\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">initialize</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n    <span class=\"hljs-keyword\">if</span> (models) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">reset</span>(models, _.<span class=\"hljs-title function_\">extend</span>({<span class=\"hljs-attr\">silent</span>: <span class=\"hljs-literal\">true</span>}, options));\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-106\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-106\">&#x00a7;</a>\n              </div>\n              <p>Default options for <code>Collection#set</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> setOptions = {<span class=\"hljs-attr\">add</span>: <span class=\"hljs-literal\">true</span>, <span class=\"hljs-attr\">remove</span>: <span class=\"hljs-literal\">true</span>, <span class=\"hljs-attr\">merge</span>: <span class=\"hljs-literal\">true</span>};\n  <span class=\"hljs-keyword\">var</span> addOptions = {<span class=\"hljs-attr\">add</span>: <span class=\"hljs-literal\">true</span>, <span class=\"hljs-attr\">remove</span>: <span class=\"hljs-literal\">false</span>};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-107\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-107\">&#x00a7;</a>\n              </div>\n              <p>Splices <code>insert</code> into <code>array</code> at index <code>at</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> splice = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">array, insert, at</span>) {\n    at = <span class=\"hljs-title class_\">Math</span>.<span class=\"hljs-title function_\">min</span>(<span class=\"hljs-title class_\">Math</span>.<span class=\"hljs-title function_\">max</span>(at, <span class=\"hljs-number\">0</span>), array.<span class=\"hljs-property\">length</span>);\n    <span class=\"hljs-keyword\">var</span> tail = <span class=\"hljs-title class_\">Array</span>(array.<span class=\"hljs-property\">length</span> - at);\n    <span class=\"hljs-keyword\">var</span> length = insert.<span class=\"hljs-property\">length</span>;\n    <span class=\"hljs-keyword\">var</span> i;\n    <span class=\"hljs-keyword\">for</span> (i = <span class=\"hljs-number\">0</span>; i &lt; tail.<span class=\"hljs-property\">length</span>; i++) tail[i] = array[i + at];\n    <span class=\"hljs-keyword\">for</span> (i = <span class=\"hljs-number\">0</span>; i &lt; length; i++) array[i + at] = insert[i];\n    <span class=\"hljs-keyword\">for</span> (i = <span class=\"hljs-number\">0</span>; i &lt; tail.<span class=\"hljs-property\">length</span>; i++) array[i + length + at] = tail[i];\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-108\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-108\">&#x00a7;</a>\n              </div>\n              <p>Define the Collection’s inheritable methods.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  _.<span class=\"hljs-title function_\">extend</span>(<span class=\"hljs-title class_\">Collection</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>, <span class=\"hljs-title class_\">Events</span>, {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-109\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-109\">&#x00a7;</a>\n              </div>\n              <p>The default model for a collection is just a <strong>Backbone.Model</strong>.\nThis should be overridden in most cases.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">model</span>: <span class=\"hljs-title class_\">Model</span>,</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-110\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-110\">&#x00a7;</a>\n              </div>\n              <p>preinitialize is an empty function by default. You can override it with a function\nor object.  preinitialize will run before any instantiation logic is run in the Collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">preinitialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){},</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-111\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-111\">&#x00a7;</a>\n              </div>\n              <p>Initialize is an empty function by default. Override it with your own\ninitialization logic.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">initialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){},</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-112\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-112\">&#x00a7;</a>\n              </div>\n              <p>The JSON representation of a Collection is an array of the\nmodels’ attributes.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">toJSON</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">map</span>(<span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model</span>) { <span class=\"hljs-keyword\">return</span> model.<span class=\"hljs-title function_\">toJSON</span>(options); });\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-113\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-113\">&#x00a7;</a>\n              </div>\n              <p>Proxy <code>Backbone.sync</code> by default.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">sync</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">sync</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-114\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-114\">&#x00a7;</a>\n              </div>\n              <p>Add a model, or list of models to the set. <code>models</code> may be Backbone\nModels or raw JavaScript objects to be converted to Models, or any\ncombination of the two.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">add</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">models, options</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">set</span>(models, _.<span class=\"hljs-title function_\">extend</span>({<span class=\"hljs-attr\">merge</span>: <span class=\"hljs-literal\">false</span>}, options, addOptions));\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-115\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-115\">&#x00a7;</a>\n              </div>\n              <p>Remove a model, or a list of models from the set.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">remove</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">models, options</span>) {\n      options = _.<span class=\"hljs-title function_\">extend</span>({}, options);\n      <span class=\"hljs-keyword\">var</span> singular = !_.<span class=\"hljs-title function_\">isArray</span>(models);\n      models = singular ? [models] : models.<span class=\"hljs-title function_\">slice</span>();\n      <span class=\"hljs-keyword\">var</span> removed = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_removeModels</span>(models, options);\n      <span class=\"hljs-keyword\">if</span> (!options.<span class=\"hljs-property\">silent</span> &amp;&amp; removed.<span class=\"hljs-property\">length</span>) {\n        options.<span class=\"hljs-property\">changes</span> = {<span class=\"hljs-attr\">added</span>: [], <span class=\"hljs-attr\">merged</span>: [], <span class=\"hljs-attr\">removed</span>: removed};\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;update&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, options);\n      }\n      <span class=\"hljs-keyword\">return</span> singular ? removed[<span class=\"hljs-number\">0</span>] : removed;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-116\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-116\">&#x00a7;</a>\n              </div>\n              <p>Update a collection by <code>set</code>-ing a new list of models, adding new ones,\nremoving models that are no longer present, and merging models that\nalready exist in the collection, as necessary. Similar to <strong>Model#set</strong>,\nthe core operation for updating the data contained by the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">set</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">models, options</span>) {\n      <span class=\"hljs-keyword\">if</span> (models == <span class=\"hljs-literal\">null</span>) <span class=\"hljs-keyword\">return</span>;\n\n      options = _.<span class=\"hljs-title function_\">extend</span>({}, setOptions, options);\n      <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">parse</span> &amp;&amp; !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_isModel</span>(models)) {\n        models = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">parse</span>(models, options) || [];\n      }\n\n      <span class=\"hljs-keyword\">var</span> singular = !_.<span class=\"hljs-title function_\">isArray</span>(models);\n      models = singular ? [models] : models.<span class=\"hljs-title function_\">slice</span>();\n\n      <span class=\"hljs-keyword\">var</span> at = options.<span class=\"hljs-property\">at</span>;\n      <span class=\"hljs-keyword\">if</span> (at != <span class=\"hljs-literal\">null</span>) at = +at;\n      <span class=\"hljs-keyword\">if</span> (at &gt; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span>) at = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span>;\n      <span class=\"hljs-keyword\">if</span> (at &lt; <span class=\"hljs-number\">0</span>) at += <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span> + <span class=\"hljs-number\">1</span>;\n\n      <span class=\"hljs-keyword\">var</span> set = [];\n      <span class=\"hljs-keyword\">var</span> toAdd = [];\n      <span class=\"hljs-keyword\">var</span> toMerge = [];\n      <span class=\"hljs-keyword\">var</span> toRemove = [];\n      <span class=\"hljs-keyword\">var</span> modelMap = {};\n\n      <span class=\"hljs-keyword\">var</span> add = options.<span class=\"hljs-property\">add</span>;\n      <span class=\"hljs-keyword\">var</span> merge = options.<span class=\"hljs-property\">merge</span>;\n      <span class=\"hljs-keyword\">var</span> remove = options.<span class=\"hljs-property\">remove</span>;\n\n      <span class=\"hljs-keyword\">var</span> sort = <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-keyword\">var</span> sortable = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">comparator</span> &amp;&amp; at == <span class=\"hljs-literal\">null</span> &amp;&amp; options.<span class=\"hljs-property\">sort</span> !== <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-keyword\">var</span> sortAttr = _.<span class=\"hljs-title function_\">isString</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">comparator</span>) ? <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">comparator</span> : <span class=\"hljs-literal\">null</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-117\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-117\">&#x00a7;</a>\n              </div>\n              <p>Turn bare objects into model references, and prevent invalid models\nfrom being added.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> model, i;\n      <span class=\"hljs-keyword\">for</span> (i = <span class=\"hljs-number\">0</span>; i &lt; models.<span class=\"hljs-property\">length</span>; i++) {\n        model = models[i];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-118\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-118\">&#x00a7;</a>\n              </div>\n              <p>If a duplicate is found, prevent it from being added and\noptionally merge it into the existing model.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"hljs-keyword\">var</span> existing = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">get</span>(model);\n        <span class=\"hljs-keyword\">if</span> (existing) {\n          <span class=\"hljs-keyword\">if</span> (merge &amp;&amp; model !== existing) {\n            <span class=\"hljs-keyword\">var</span> attrs = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_isModel</span>(model) ? model.<span class=\"hljs-property\">attributes</span> : model;\n            <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">parse</span>) attrs = existing.<span class=\"hljs-title function_\">parse</span>(attrs, options);\n            existing.<span class=\"hljs-title function_\">set</span>(attrs, options);\n            toMerge.<span class=\"hljs-title function_\">push</span>(existing);\n            <span class=\"hljs-keyword\">if</span> (sortable &amp;&amp; !sort) sort = existing.<span class=\"hljs-title function_\">hasChanged</span>(sortAttr);\n          }\n          <span class=\"hljs-keyword\">if</span> (!modelMap[existing.<span class=\"hljs-property\">cid</span>]) {\n            modelMap[existing.<span class=\"hljs-property\">cid</span>] = <span class=\"hljs-literal\">true</span>;\n            set.<span class=\"hljs-title function_\">push</span>(existing);\n          }\n          models[i] = existing;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-119\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-119\">&#x00a7;</a>\n              </div>\n              <p>If this is a new, valid model, push it to the <code>toAdd</code> list.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (add) {\n          model = models[i] = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_prepareModel</span>(model, options);\n          <span class=\"hljs-keyword\">if</span> (model) {\n            toAdd.<span class=\"hljs-title function_\">push</span>(model);\n            <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_addReference</span>(model, options);\n            modelMap[model.<span class=\"hljs-property\">cid</span>] = <span class=\"hljs-literal\">true</span>;\n            set.<span class=\"hljs-title function_\">push</span>(model);\n          }\n        }\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-120\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-120\">&#x00a7;</a>\n              </div>\n              <p>Remove stale models.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (remove) {\n        <span class=\"hljs-keyword\">for</span> (i = <span class=\"hljs-number\">0</span>; i &lt; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span>; i++) {\n          model = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>[i];\n          <span class=\"hljs-keyword\">if</span> (!modelMap[model.<span class=\"hljs-property\">cid</span>]) toRemove.<span class=\"hljs-title function_\">push</span>(model);\n        }\n        <span class=\"hljs-keyword\">if</span> (toRemove.<span class=\"hljs-property\">length</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_removeModels</span>(toRemove, options);\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-121\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-121\">&#x00a7;</a>\n              </div>\n              <p>See if sorting is needed, update <code>length</code> and splice in new models.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> orderChanged = <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-keyword\">var</span> replace = !sortable &amp;&amp; add &amp;&amp; remove;\n      <span class=\"hljs-keyword\">if</span> (set.<span class=\"hljs-property\">length</span> &amp;&amp; replace) {\n        orderChanged = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span> !== set.<span class=\"hljs-property\">length</span> || _.<span class=\"hljs-title function_\">some</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">m, index</span>) {\n          <span class=\"hljs-keyword\">return</span> m !== set[index];\n        });\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>.<span class=\"hljs-property\">length</span> = <span class=\"hljs-number\">0</span>;\n        <span class=\"hljs-title function_\">splice</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>, set, <span class=\"hljs-number\">0</span>);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>.<span class=\"hljs-property\">length</span>;\n      } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (toAdd.<span class=\"hljs-property\">length</span>) {\n        <span class=\"hljs-keyword\">if</span> (sortable) sort = <span class=\"hljs-literal\">true</span>;\n        <span class=\"hljs-title function_\">splice</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>, toAdd, at == <span class=\"hljs-literal\">null</span> ? <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span> : at);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>.<span class=\"hljs-property\">length</span>;\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-122\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-122\">&#x00a7;</a>\n              </div>\n              <p>Silently sort the collection if appropriate.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (sort) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">sort</span>({<span class=\"hljs-attr\">silent</span>: <span class=\"hljs-literal\">true</span>});</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-123\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-123\">&#x00a7;</a>\n              </div>\n              <p>Unless silenced, it’s time to fire all appropriate add/sort/update events.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (!options.<span class=\"hljs-property\">silent</span>) {\n        <span class=\"hljs-keyword\">for</span> (i = <span class=\"hljs-number\">0</span>; i &lt; toAdd.<span class=\"hljs-property\">length</span>; i++) {\n          <span class=\"hljs-keyword\">if</span> (at != <span class=\"hljs-literal\">null</span>) options.<span class=\"hljs-property\">index</span> = at + i;\n          model = toAdd[i];\n          model.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;add&#x27;</span>, model, <span class=\"hljs-variable language_\">this</span>, options);\n        }\n        <span class=\"hljs-keyword\">if</span> (sort || orderChanged) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;sort&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, options);\n        <span class=\"hljs-keyword\">if</span> (toAdd.<span class=\"hljs-property\">length</span> || toRemove.<span class=\"hljs-property\">length</span> || toMerge.<span class=\"hljs-property\">length</span>) {\n          options.<span class=\"hljs-property\">changes</span> = {\n            <span class=\"hljs-attr\">added</span>: toAdd,\n            <span class=\"hljs-attr\">removed</span>: toRemove,\n            <span class=\"hljs-attr\">merged</span>: toMerge\n          };\n          <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;update&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, options);\n        }\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-124\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-124\">&#x00a7;</a>\n              </div>\n              <p>Return the added (or merged) model (or models).</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">return</span> singular ? models[<span class=\"hljs-number\">0</span>] : models;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-125\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-125\">&#x00a7;</a>\n              </div>\n              <p>When you have more items than you want to add or remove individually,\nyou can reset the entire set with a new list of models, without firing\nany granular <code>add</code> or <code>remove</code> events. Fires <code>reset</code> when finished.\nUseful for bulk operations and optimizations.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">reset</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">models, options</span>) {\n      options = options ? _.<span class=\"hljs-title function_\">clone</span>(options) : {};\n      <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> i = <span class=\"hljs-number\">0</span>; i &lt; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>.<span class=\"hljs-property\">length</span>; i++) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_removeReference</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>[i], options);\n      }\n      options.<span class=\"hljs-property\">previousModels</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_reset</span>();\n      models = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">add</span>(models, _.<span class=\"hljs-title function_\">extend</span>({<span class=\"hljs-attr\">silent</span>: <span class=\"hljs-literal\">true</span>}, options));\n      <span class=\"hljs-keyword\">if</span> (!options.<span class=\"hljs-property\">silent</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;reset&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, options);\n      <span class=\"hljs-keyword\">return</span> models;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-126\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-126\">&#x00a7;</a>\n              </div>\n              <p>Add a model to the end of the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">push</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model, options</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">add</span>(model, _.<span class=\"hljs-title function_\">extend</span>({<span class=\"hljs-attr\">at</span>: <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span>}, options));\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-127\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-127\">&#x00a7;</a>\n              </div>\n              <p>Remove a model from the end of the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">pop</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      <span class=\"hljs-keyword\">var</span> model = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">at</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span> - <span class=\"hljs-number\">1</span>);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">remove</span>(model, options);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-128\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-128\">&#x00a7;</a>\n              </div>\n              <p>Add a model to the beginning of the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">unshift</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model, options</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">add</span>(model, _.<span class=\"hljs-title function_\">extend</span>({<span class=\"hljs-attr\">at</span>: <span class=\"hljs-number\">0</span>}, options));\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-129\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-129\">&#x00a7;</a>\n              </div>\n              <p>Remove a model from the beginning of the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">shift</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      <span class=\"hljs-keyword\">var</span> model = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">at</span>(<span class=\"hljs-number\">0</span>);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">remove</span>(model, options);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-130\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-130\">&#x00a7;</a>\n              </div>\n              <p>Slice out a sub-array of models from the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">slice</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> slice.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>, <span class=\"hljs-variable language_\">arguments</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-131\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-131\">&#x00a7;</a>\n              </div>\n              <p>Get a model from the set by id, cid, model object with id or cid\nproperties, or an attributes object that is transformed through modelId.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">get</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">obj</span>) {\n      <span class=\"hljs-keyword\">if</span> (obj == <span class=\"hljs-literal\">null</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>;\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[obj] ||\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">modelId</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_isModel</span>(obj) ? obj.<span class=\"hljs-property\">attributes</span> : obj, obj.<span class=\"hljs-property\">idAttribute</span>)] ||\n        obj.<span class=\"hljs-property\">cid</span> &amp;&amp; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[obj.<span class=\"hljs-property\">cid</span>];\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-132\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-132\">&#x00a7;</a>\n              </div>\n              <p>Returns <code>true</code> if the model is in the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">has</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">obj</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">get</span>(obj) != <span class=\"hljs-literal\">null</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-133\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-133\">&#x00a7;</a>\n              </div>\n              <p>Get the model at the given index.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">at</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">index</span>) {\n      <span class=\"hljs-keyword\">if</span> (index &lt; <span class=\"hljs-number\">0</span>) index += <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span>;\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>[index];\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-134\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-134\">&#x00a7;</a>\n              </div>\n              <p>Return models with matching attributes. Useful for simple cases of\n<code>filter</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">where</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attrs, first</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>[first ? <span class=\"hljs-string\">&#x27;find&#x27;</span> : <span class=\"hljs-string\">&#x27;filter&#x27;</span>](attrs);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-135\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-135\">&#x00a7;</a>\n              </div>\n              <p>Return the first model with matching attributes. Useful for simple cases\nof <code>find</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">findWhere</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attrs</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">where</span>(attrs, <span class=\"hljs-literal\">true</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-136\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-136\">&#x00a7;</a>\n              </div>\n              <p>Force the collection to re-sort itself. You don’t need to call this under\nnormal circumstances, as the set will maintain sort order as each item\nis added.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">sort</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      <span class=\"hljs-keyword\">var</span> comparator = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">comparator</span>;\n      <span class=\"hljs-keyword\">if</span> (!comparator) <span class=\"hljs-keyword\">throw</span> <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">Error</span>(<span class=\"hljs-string\">&#x27;Cannot sort a set without a comparator&#x27;</span>);\n      options || (options = {});\n\n      <span class=\"hljs-keyword\">var</span> length = comparator.<span class=\"hljs-property\">length</span>;\n      <span class=\"hljs-keyword\">if</span> (_.<span class=\"hljs-title function_\">isFunction</span>(comparator)) comparator = comparator.<span class=\"hljs-title function_\">bind</span>(<span class=\"hljs-variable language_\">this</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-137\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-137\">&#x00a7;</a>\n              </div>\n              <p>Run sort based on type of <code>comparator</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (length === <span class=\"hljs-number\">1</span> || _.<span class=\"hljs-title function_\">isString</span>(comparator)) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">sortBy</span>(comparator);\n      } <span class=\"hljs-keyword\">else</span> {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>.<span class=\"hljs-title function_\">sort</span>(comparator);\n      }\n      <span class=\"hljs-keyword\">if</span> (!options.<span class=\"hljs-property\">silent</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;sort&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, options);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-138\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-138\">&#x00a7;</a>\n              </div>\n              <p>Pluck an attribute from each model in the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">pluck</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attr</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">map</span>(attr + <span class=\"hljs-string\">&#x27;&#x27;</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-139\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-139\">&#x00a7;</a>\n              </div>\n              <p>Fetch the default set of models for this collection, resetting the\ncollection when they arrive. If <code>reset: true</code> is passed, the response\ndata will be passed through the <code>reset</code> method instead of <code>set</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">fetch</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      options = _.<span class=\"hljs-title function_\">extend</span>({<span class=\"hljs-attr\">parse</span>: <span class=\"hljs-literal\">true</span>}, options);\n      <span class=\"hljs-keyword\">var</span> success = options.<span class=\"hljs-property\">success</span>;\n      <span class=\"hljs-keyword\">var</span> collection = <span class=\"hljs-variable language_\">this</span>;\n      options.<span class=\"hljs-property\">success</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">resp</span>) {\n        <span class=\"hljs-keyword\">var</span> method = options.<span class=\"hljs-property\">reset</span> ? <span class=\"hljs-string\">&#x27;reset&#x27;</span> : <span class=\"hljs-string\">&#x27;set&#x27;</span>;\n        collection[method](resp, options);\n        <span class=\"hljs-keyword\">if</span> (success) success.<span class=\"hljs-title function_\">call</span>(options.<span class=\"hljs-property\">context</span>, collection, resp, options);\n        collection.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;sync&#x27;</span>, collection, resp, options);\n      };\n      <span class=\"hljs-title function_\">wrapError</span>(<span class=\"hljs-variable language_\">this</span>, options);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">sync</span>(<span class=\"hljs-string\">&#x27;read&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, options);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-140\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-140\">&#x00a7;</a>\n              </div>\n              <p>Create a new instance of a model in this collection. Add the model to the\ncollection immediately, unless <code>wait: true</code> is passed, in which case we\nwait for the server to agree.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">create</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model, options</span>) {\n      options = options ? _.<span class=\"hljs-title function_\">clone</span>(options) : {};\n      <span class=\"hljs-keyword\">var</span> wait = options.<span class=\"hljs-property\">wait</span>;\n      model = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_prepareModel</span>(model, options);\n      <span class=\"hljs-keyword\">if</span> (!model) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-keyword\">if</span> (!wait) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">add</span>(model, options);\n      <span class=\"hljs-keyword\">var</span> collection = <span class=\"hljs-variable language_\">this</span>;\n      <span class=\"hljs-keyword\">var</span> success = options.<span class=\"hljs-property\">success</span>;\n      options.<span class=\"hljs-property\">success</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">m, resp, callbackOpts</span>) {\n        <span class=\"hljs-keyword\">if</span> (wait) {\n          m.<span class=\"hljs-title function_\">off</span>(<span class=\"hljs-string\">&#x27;error&#x27;</span>, collection.<span class=\"hljs-property\">_forwardPristineError</span>, collection);\n          collection.<span class=\"hljs-title function_\">add</span>(m, callbackOpts);\n        }\n        <span class=\"hljs-keyword\">if</span> (success) success.<span class=\"hljs-title function_\">call</span>(callbackOpts.<span class=\"hljs-property\">context</span>, m, resp, callbackOpts);\n      };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-141\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-141\">&#x00a7;</a>\n              </div>\n              <p>In case of wait:true, our collection is not listening to any\nof the model’s events yet, so it will not forward the error\nevent. In this special case, we need to listen for it\nseparately and handle the event just once.\n(The reason we don’t need to do this for the sync event is\nin the success handler above: we add the model first, which\ncauses the collection to listen, and then invoke the callback\nthat triggers the event.)</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (wait) {\n        model.<span class=\"hljs-title function_\">once</span>(<span class=\"hljs-string\">&#x27;error&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_forwardPristineError</span>, <span class=\"hljs-variable language_\">this</span>);\n      }\n      model.<span class=\"hljs-title function_\">save</span>(<span class=\"hljs-literal\">null</span>, options);\n      <span class=\"hljs-keyword\">return</span> model;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-142\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-142\">&#x00a7;</a>\n              </div>\n              <p><strong>parse</strong> converts a response into a list of models to be added to the\ncollection. The default implementation is just to pass it through.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">parse</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">resp, options</span>) {\n      <span class=\"hljs-keyword\">return</span> resp;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-143\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-143\">&#x00a7;</a>\n              </div>\n              <p>Create a new collection with an identical list of models as this one.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">clone</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">new</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">constructor</span>(<span class=\"hljs-params\"><span class=\"hljs-variable language_\">this</span>.models, {\n        model: <span class=\"hljs-variable language_\">this</span>.model,\n        comparator: <span class=\"hljs-variable language_\">this</span>.comparator\n      }</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-144\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-144\">&#x00a7;</a>\n              </div>\n              <p>Define how to uniquely identify models in the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">modelId</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attrs, idAttribute</span>) {\n      <span class=\"hljs-keyword\">return</span> attrs[idAttribute || <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>.<span class=\"hljs-property\">idAttribute</span> || <span class=\"hljs-string\">&#x27;id&#x27;</span>];\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-145\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-145\">&#x00a7;</a>\n              </div>\n              <p>Get an iterator of all models in this collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">values</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">CollectionIterator</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable constant_\">ITERATOR_VALUES</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-146\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-146\">&#x00a7;</a>\n              </div>\n              <p>Get an iterator of all model IDs in this collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">keys</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">CollectionIterator</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable constant_\">ITERATOR_KEYS</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-147\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-147\">&#x00a7;</a>\n              </div>\n              <p>Get an iterator of all [ID, model] tuples in this collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">entries</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">CollectionIterator</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable constant_\">ITERATOR_KEYSVALUES</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-148\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-148\">&#x00a7;</a>\n              </div>\n              <p>Private method to reset all internal state. Called when the collection\nis first initialized or reset.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_reset</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span> = <span class=\"hljs-number\">0</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span> = [];\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>  = {};\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-149\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-149\">&#x00a7;</a>\n              </div>\n              <p>Prepare a hash of attributes (or other model) to be added to this\ncollection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_prepareModel</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attrs, options</span>) {\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_isModel</span>(attrs)) {\n        <span class=\"hljs-keyword\">if</span> (!attrs.<span class=\"hljs-property\">collection</span>) attrs.<span class=\"hljs-property\">collection</span> = <span class=\"hljs-variable language_\">this</span>;\n        <span class=\"hljs-keyword\">return</span> attrs;\n      }\n      options = options ? _.<span class=\"hljs-title function_\">clone</span>(options) : {};\n      options.<span class=\"hljs-property\">collection</span> = <span class=\"hljs-variable language_\">this</span>;\n\n      <span class=\"hljs-keyword\">var</span> model;\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>) {\n        model = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">model</span>(attrs, options);\n      } <span class=\"hljs-keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-150\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-150\">&#x00a7;</a>\n              </div>\n              <p>ES class methods didn’t have prototype</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        model = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">model</span>(attrs, options);\n      }\n\n      <span class=\"hljs-keyword\">if</span> (!model.<span class=\"hljs-property\">validationError</span>) <span class=\"hljs-keyword\">return</span> model;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;invalid&#x27;</span>, <span class=\"hljs-variable language_\">this</span>, model.<span class=\"hljs-property\">validationError</span>, options);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-151\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-151\">&#x00a7;</a>\n              </div>\n              <p>Internal method called by both remove and set.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_removeModels</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">models, options</span>) {\n      <span class=\"hljs-keyword\">var</span> removed = [];\n      <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> i = <span class=\"hljs-number\">0</span>; i &lt; models.<span class=\"hljs-property\">length</span>; i++) {\n        <span class=\"hljs-keyword\">var</span> model = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">get</span>(models[i]);\n        <span class=\"hljs-keyword\">if</span> (!model) <span class=\"hljs-keyword\">continue</span>;\n\n        <span class=\"hljs-keyword\">var</span> index = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">indexOf</span>(model);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">models</span>.<span class=\"hljs-title function_\">splice</span>(index, <span class=\"hljs-number\">1</span>);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span>--;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-152\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-152\">&#x00a7;</a>\n              </div>\n              <p>Remove references before triggering ‘remove’ event to prevent an\ninfinite loop. #3693</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"hljs-keyword\">delete</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[model.<span class=\"hljs-property\">cid</span>];\n        <span class=\"hljs-keyword\">var</span> id = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">modelId</span>(model.<span class=\"hljs-property\">attributes</span>, model.<span class=\"hljs-property\">idAttribute</span>);\n        <span class=\"hljs-keyword\">if</span> (id != <span class=\"hljs-literal\">null</span>) <span class=\"hljs-keyword\">delete</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[id];\n\n        <span class=\"hljs-keyword\">if</span> (!options.<span class=\"hljs-property\">silent</span>) {\n          options.<span class=\"hljs-property\">index</span> = index;\n          model.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;remove&#x27;</span>, model, <span class=\"hljs-variable language_\">this</span>, options);\n        }\n\n        removed.<span class=\"hljs-title function_\">push</span>(model);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_removeReference</span>(model, options);\n      }\n      <span class=\"hljs-keyword\">if</span> (models.<span class=\"hljs-property\">length</span> &gt; <span class=\"hljs-number\">0</span> &amp;&amp; !options.<span class=\"hljs-property\">silent</span>) <span class=\"hljs-keyword\">delete</span> options.<span class=\"hljs-property\">index</span>;\n      <span class=\"hljs-keyword\">return</span> removed;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-153\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-153\">&#x00a7;</a>\n              </div>\n              <p>Method for checking whether an object should be considered a model for\nthe purposes of adding to the collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_isModel</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model</span>) {\n      <span class=\"hljs-keyword\">return</span> model <span class=\"hljs-keyword\">instanceof</span> <span class=\"hljs-title class_\">Model</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-154\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-154\">&#x00a7;</a>\n              </div>\n              <p>Internal method to create a model’s ties to a collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_addReference</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model, options</span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[model.<span class=\"hljs-property\">cid</span>] = model;\n      <span class=\"hljs-keyword\">var</span> id = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">modelId</span>(model.<span class=\"hljs-property\">attributes</span>, model.<span class=\"hljs-property\">idAttribute</span>);\n      <span class=\"hljs-keyword\">if</span> (id != <span class=\"hljs-literal\">null</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[id] = model;\n      model.<span class=\"hljs-title function_\">on</span>(<span class=\"hljs-string\">&#x27;all&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_onModelEvent</span>, <span class=\"hljs-variable language_\">this</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-155\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-155\">&#x00a7;</a>\n              </div>\n              <p>Internal method to sever a model’s ties to a collection.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_removeReference</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model, options</span>) {\n      <span class=\"hljs-keyword\">delete</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[model.<span class=\"hljs-property\">cid</span>];\n      <span class=\"hljs-keyword\">var</span> id = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">modelId</span>(model.<span class=\"hljs-property\">attributes</span>, model.<span class=\"hljs-property\">idAttribute</span>);\n      <span class=\"hljs-keyword\">if</span> (id != <span class=\"hljs-literal\">null</span>) <span class=\"hljs-keyword\">delete</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[id];\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span> === model.<span class=\"hljs-property\">collection</span>) <span class=\"hljs-keyword\">delete</span> model.<span class=\"hljs-property\">collection</span>;\n      model.<span class=\"hljs-title function_\">off</span>(<span class=\"hljs-string\">&#x27;all&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_onModelEvent</span>, <span class=\"hljs-variable language_\">this</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-156\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-156\">&#x00a7;</a>\n              </div>\n              <p>Internal method called every time a model in the set fires an event.\nSets need to update their indexes when models change ids. All other\nevents simply proxy through. “add” and “remove” events that originate\nin other collections are ignored.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_onModelEvent</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">event, model, collection, options</span>) {\n      <span class=\"hljs-keyword\">if</span> (model) {\n        <span class=\"hljs-keyword\">if</span> ((event === <span class=\"hljs-string\">&#x27;add&#x27;</span> || event === <span class=\"hljs-string\">&#x27;remove&#x27;</span>) &amp;&amp; collection !== <span class=\"hljs-variable language_\">this</span>) <span class=\"hljs-keyword\">return</span>;\n        <span class=\"hljs-keyword\">if</span> (event === <span class=\"hljs-string\">&#x27;destroy&#x27;</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">remove</span>(model, options);\n        <span class=\"hljs-keyword\">if</span> (event === <span class=\"hljs-string\">&#x27;changeId&#x27;</span>) {\n          <span class=\"hljs-keyword\">var</span> prevId = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">modelId</span>(model.<span class=\"hljs-title function_\">previousAttributes</span>(), model.<span class=\"hljs-property\">idAttribute</span>);\n          <span class=\"hljs-keyword\">var</span> id = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">modelId</span>(model.<span class=\"hljs-property\">attributes</span>, model.<span class=\"hljs-property\">idAttribute</span>);\n          <span class=\"hljs-keyword\">if</span> (prevId != <span class=\"hljs-literal\">null</span>) <span class=\"hljs-keyword\">delete</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[prevId];\n          <span class=\"hljs-keyword\">if</span> (id != <span class=\"hljs-literal\">null</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_byId</span>[id] = model;\n        }\n      }\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">trigger</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-157\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-157\">&#x00a7;</a>\n              </div>\n              <p>Internal callback method used in <code>create</code>. It serves as a\nstand-in for the <code>_onModelEvent</code> method, which is not yet bound\nduring the <code>wait</code> period of the <code>create</code> call. We still want to\nforward any <code>&#39;error&#39;</code> event at the end of the <code>wait</code> period,\nhence a customized callback.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_forwardPristineError</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model, collection, options</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-158\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-158\">&#x00a7;</a>\n              </div>\n              <p>Prevent double forward if the model was already in the\ncollection before the call to <code>create</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">has</span>(model)) <span class=\"hljs-keyword\">return</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_onModelEvent</span>(<span class=\"hljs-string\">&#x27;error&#x27;</span>, model, collection, options);\n    }\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-159\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-159\">&#x00a7;</a>\n              </div>\n              <p>Defining an @@iterator method implements JavaScript’s Iterable protocol.\nIn modern ES2015 browsers, this value is found at Symbol.iterator.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-comment\">/* global Symbol */</span>\n  <span class=\"hljs-keyword\">var</span> $$iterator = <span class=\"hljs-keyword\">typeof</span> <span class=\"hljs-title class_\">Symbol</span> === <span class=\"hljs-string\">&#x27;function&#x27;</span> &amp;&amp; <span class=\"hljs-title class_\">Symbol</span>.<span class=\"hljs-property\">iterator</span>;\n  <span class=\"hljs-keyword\">if</span> ($$iterator) {\n    <span class=\"hljs-title class_\">Collection</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>[$$iterator] = <span class=\"hljs-title class_\">Collection</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>.<span class=\"hljs-property\">values</span>;\n  }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-160\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-160\">&#x00a7;</a>\n              </div>\n              <h2 id=\"collectioniterator\">CollectionIterator</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-161\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-161\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-162\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-162\">&#x00a7;</a>\n              </div>\n              <p>A CollectionIterator implements JavaScript’s Iterator protocol, allowing the\nuse of <code>for of</code> loops in modern browsers and interoperation between\nBackbone.Collection and other JavaScript functions and third-party libraries\nwhich can operate on Iterables.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">CollectionIterator</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">collection, kind</span>) {\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_collection</span> = collection;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_kind</span> = kind;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_index</span> = <span class=\"hljs-number\">0</span>;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-163\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-163\">&#x00a7;</a>\n              </div>\n              <p>This “enum” defines the three possible kinds of values which can be emitted\nby a CollectionIterator that correspond to the values(), keys() and entries()\nmethods on Collection, respectively.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-variable constant_\">ITERATOR_VALUES</span> = <span class=\"hljs-number\">1</span>;\n  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-variable constant_\">ITERATOR_KEYS</span> = <span class=\"hljs-number\">2</span>;\n  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-variable constant_\">ITERATOR_KEYSVALUES</span> = <span class=\"hljs-number\">3</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-164\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-164\">&#x00a7;</a>\n              </div>\n              <p>All Iterators should themselves be Iterable.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">if</span> ($$iterator) {\n    <span class=\"hljs-title class_\">CollectionIterator</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>[$$iterator] = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    };\n  }\n\n  <span class=\"hljs-title class_\">CollectionIterator</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>.<span class=\"hljs-property\">next</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_collection</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-165\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-165\">&#x00a7;</a>\n              </div>\n              <p>Only continue iterating if the iterated collection is long enough.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_index</span> &lt; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_collection</span>.<span class=\"hljs-property\">length</span>) {\n        <span class=\"hljs-keyword\">var</span> model = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_collection</span>.<span class=\"hljs-title function_\">at</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_index</span>);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_index</span>++;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-166\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-166\">&#x00a7;</a>\n              </div>\n              <p>Construct a value depending on what kind of values should be iterated.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"hljs-keyword\">var</span> value;\n        <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_kind</span> === <span class=\"hljs-variable constant_\">ITERATOR_VALUES</span>) {\n          value = model;\n        } <span class=\"hljs-keyword\">else</span> {\n          <span class=\"hljs-keyword\">var</span> id = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_collection</span>.<span class=\"hljs-title function_\">modelId</span>(model.<span class=\"hljs-property\">attributes</span>, model.<span class=\"hljs-property\">idAttribute</span>);\n          <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_kind</span> === <span class=\"hljs-variable constant_\">ITERATOR_KEYS</span>) {\n            value = id;\n          } <span class=\"hljs-keyword\">else</span> { <span class=\"hljs-comment\">// ITERATOR_KEYSVALUES</span>\n            value = [id, model];\n          }\n        }\n        <span class=\"hljs-keyword\">return</span> {<span class=\"hljs-attr\">value</span>: value, <span class=\"hljs-attr\">done</span>: <span class=\"hljs-literal\">false</span>};\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-167\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-167\">&#x00a7;</a>\n              </div>\n              <p>Once exhausted, remove the reference to the collection so future\ncalls to the next method always return done.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_collection</span> = <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>;\n    }\n\n    <span class=\"hljs-keyword\">return</span> {<span class=\"hljs-attr\">value</span>: <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span>, <span class=\"hljs-attr\">done</span>: <span class=\"hljs-literal\">true</span>};\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-168\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-168\">&#x00a7;</a>\n              </div>\n              <h2 id=\"backboneview\">Backbone.View</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-169\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-169\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-170\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-170\">&#x00a7;</a>\n              </div>\n              <p>Backbone Views are almost more convention than they are actual code. A View\nis simply a JavaScript object that represents a logical chunk of UI in the\nDOM. This might be a single item, an entire list, a sidebar or panel, or\neven the surrounding frame which wraps your whole app. Defining a chunk of\nUI as a <strong>View</strong> allows you to define your DOM events declaratively, without\nhaving to worry about render order … and makes it easy for the view to\nreact to specific changes in the state of your models.</p>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-171\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-171\">&#x00a7;</a>\n              </div>\n              <p>Creating a Backbone.View creates its initial element outside of the DOM,\nif an existing element is not provided…</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">View</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">View</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">cid</span> = _.<span class=\"hljs-title function_\">uniqueId</span>(<span class=\"hljs-string\">&#x27;view&#x27;</span>);\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">preinitialize</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n    _.<span class=\"hljs-title function_\">extend</span>(<span class=\"hljs-variable language_\">this</span>, _.<span class=\"hljs-title function_\">pick</span>(options, viewOptions));\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_ensureElement</span>();\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">initialize</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-172\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-172\">&#x00a7;</a>\n              </div>\n              <p>Cached regex to split keys for <code>delegate</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> delegateEventSplitter = <span class=\"hljs-regexp\">/^(\\S+)\\s*(.*)$/</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-173\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-173\">&#x00a7;</a>\n              </div>\n              <p>List of view options to be set as properties.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> viewOptions = [<span class=\"hljs-string\">&#x27;model&#x27;</span>, <span class=\"hljs-string\">&#x27;collection&#x27;</span>, <span class=\"hljs-string\">&#x27;el&#x27;</span>, <span class=\"hljs-string\">&#x27;id&#x27;</span>, <span class=\"hljs-string\">&#x27;attributes&#x27;</span>, <span class=\"hljs-string\">&#x27;className&#x27;</span>, <span class=\"hljs-string\">&#x27;tagName&#x27;</span>, <span class=\"hljs-string\">&#x27;events&#x27;</span>];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-174\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-174\">&#x00a7;</a>\n              </div>\n              <p>Set up all inheritable <strong>Backbone.View</strong> properties and methods.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  _.<span class=\"hljs-title function_\">extend</span>(<span class=\"hljs-title class_\">View</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>, <span class=\"hljs-title class_\">Events</span>, {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-175\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-175\">&#x00a7;</a>\n              </div>\n              <p>The default <code>tagName</code> of a View’s element is <code>&quot;div&quot;</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">tagName</span>: <span class=\"hljs-string\">&#x27;div&#x27;</span>,</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-176\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-176\">&#x00a7;</a>\n              </div>\n              <p>jQuery delegate for element lookup, scoped to DOM elements within the\ncurrent view. This should be preferred to global lookups where possible.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">$</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">selector</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">find</span>(selector);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-177\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-177\">&#x00a7;</a>\n              </div>\n              <p>preinitialize is an empty function by default. You can override it with a function\nor object.  preinitialize will run before any instantiation logic is run in the View</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">preinitialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){},</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-178\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-178\">&#x00a7;</a>\n              </div>\n              <p>Initialize is an empty function by default. Override it with your own\ninitialization logic.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">initialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){},</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-179\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-179\">&#x00a7;</a>\n              </div>\n              <p><strong>render</strong> is the core function that your view should override, in order\nto populate its element (<code>this.el</code>), with the appropriate HTML. The\nconvention is for <strong>render</strong> to always return <code>this</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">render</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-180\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-180\">&#x00a7;</a>\n              </div>\n              <p>Remove this view by taking the element out of the DOM, and removing any\napplicable Backbone.Events listeners.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">remove</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_removeElement</span>();\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">stopListening</span>();\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-181\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-181\">&#x00a7;</a>\n              </div>\n              <p>Remove this view’s element from the document and all event listeners\nattached to it. Exposed for subclasses using an alternative DOM\nmanipulation API.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_removeElement</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">remove</span>();\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-182\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-182\">&#x00a7;</a>\n              </div>\n              <p>Change the view’s element (<code>this.el</code> property) and re-delegate the\nview’s events on the new element.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">setElement</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">element</span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">undelegateEvents</span>();\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_setElement</span>(element);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">delegateEvents</span>();\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-183\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-183\">&#x00a7;</a>\n              </div>\n              <p>Creates the <code>this.el</code> and <code>this.$el</code> references for this view using the\ngiven <code>el</code>. <code>el</code> can be a CSS selector or an HTML string, a jQuery\ncontext or an element. Subclasses can override this to utilize an\nalternative DOM manipulation API and are only required to set the\n<code>this.el</code> property.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_setElement</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">el</span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span> = el <span class=\"hljs-keyword\">instanceof</span> <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">$</span> ? el : <span class=\"hljs-title class_\">Backbone</span>.$(el);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">el</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>[<span class=\"hljs-number\">0</span>];\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-184\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-184\">&#x00a7;</a>\n              </div>\n              <p>Set callbacks, where <code>this.events</code> is a hash of</p>\n<p><em>{“event selector”: “callback”}</em></p>\n<pre><code>{\n  <span class=\"hljs-string\">&#x27;mousedown .title&#x27;</span>:  <span class=\"hljs-string\">&#x27;edit&#x27;</span>,\n  <span class=\"hljs-string\">&#x27;click .button&#x27;</span>:     <span class=\"hljs-string\">&#x27;save&#x27;</span>,\n  <span class=\"hljs-string\">&#x27;click .open&#x27;</span>:       <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">e</span>) { ... }\n}\n</code></pre>\n<p>pairs. Callbacks will be bound to the view, with <code>this</code> set properly.\nUses event delegation for efficiency.\nOmitting the selector binds the event to <code>this.el</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">delegateEvents</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">events</span>) {\n      events || (events = _.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-string\">&#x27;events&#x27;</span>));\n      <span class=\"hljs-keyword\">if</span> (!events) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">undelegateEvents</span>();\n      <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">var</span> key <span class=\"hljs-keyword\">in</span> events) {\n        <span class=\"hljs-keyword\">var</span> method = events[key];\n        <span class=\"hljs-keyword\">if</span> (!_.<span class=\"hljs-title function_\">isFunction</span>(method)) method = <span class=\"hljs-variable language_\">this</span>[method];\n        <span class=\"hljs-keyword\">if</span> (!method) <span class=\"hljs-keyword\">continue</span>;\n        <span class=\"hljs-keyword\">var</span> match = key.<span class=\"hljs-title function_\">match</span>(delegateEventSplitter);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">delegate</span>(match[<span class=\"hljs-number\">1</span>], match[<span class=\"hljs-number\">2</span>], method.<span class=\"hljs-title function_\">bind</span>(<span class=\"hljs-variable language_\">this</span>));\n      }\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-185\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-185\">&#x00a7;</a>\n              </div>\n              <p>Add a single event listener to the view’s element (or a child element\nusing <code>selector</code>). This only works for delegate-able events: not <code>focus</code>,\n<code>blur</code>, and not <code>change</code>, <code>submit</code>, and <code>reset</code> in Internet Explorer.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">delegate</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">eventName, selector, listener</span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">on</span>(eventName + <span class=\"hljs-string\">&#x27;.delegateEvents&#x27;</span> + <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">cid</span>, selector, listener);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-186\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-186\">&#x00a7;</a>\n              </div>\n              <p>Clears all callbacks previously bound to the view by <code>delegateEvents</code>.\nYou usually don’t need to use this, but may wish to if you have multiple\nBackbone views attached to the same DOM element.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">undelegateEvents</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">off</span>(<span class=\"hljs-string\">&#x27;.delegateEvents&#x27;</span> + <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">cid</span>);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-187\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-187\">&#x00a7;</a>\n              </div>\n              <p>A finer-grained <code>undelegateEvents</code> for removing a single delegated event.\n<code>selector</code> and <code>listener</code> are both optional.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">undelegate</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">eventName, selector, listener</span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">off</span>(eventName + <span class=\"hljs-string\">&#x27;.delegateEvents&#x27;</span> + <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">cid</span>, selector, listener);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-188\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-188\">&#x00a7;</a>\n              </div>\n              <p>Produces a DOM element to be assigned to your view. Exposed for\nsubclasses using an alternative DOM manipulation API.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_createElement</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">tagName</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">document</span>.<span class=\"hljs-title function_\">createElement</span>(tagName);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-189\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-189\">&#x00a7;</a>\n              </div>\n              <p>Ensure that the View has a DOM element to render into.\nIf <code>this.el</code> is a string, pass it through <code>$()</code>, take the first\nmatching element, and re-assign it to <code>el</code>. Otherwise, create\nan element from the <code>id</code>, <code>className</code> and <code>tagName</code> properties.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_ensureElement</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">el</span>) {\n        <span class=\"hljs-keyword\">var</span> attrs = _.<span class=\"hljs-title function_\">extend</span>({}, _.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-string\">&#x27;attributes&#x27;</span>));\n        <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">id</span>) attrs.<span class=\"hljs-property\">id</span> = _.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-string\">&#x27;id&#x27;</span>);\n        <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">className</span>) attrs[<span class=\"hljs-string\">&#x27;class&#x27;</span>] = _.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-string\">&#x27;className&#x27;</span>);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">setElement</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_createElement</span>(_.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-string\">&#x27;tagName&#x27;</span>)));\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_setAttributes</span>(attrs);\n      } <span class=\"hljs-keyword\">else</span> {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">setElement</span>(_.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-string\">&#x27;el&#x27;</span>));\n      }\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-190\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-190\">&#x00a7;</a>\n              </div>\n              <p>Set attributes from a hash on this view’s element.  Exposed for\nsubclasses using an alternative DOM manipulation API.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_setAttributes</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attributes</span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">attr</span>(attributes);\n    }\n\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-191\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-191\">&#x00a7;</a>\n              </div>\n              <p>Proxy Backbone class methods to Underscore functions, wrapping the model’s\n<code>attributes</code> object or collection’s <code>models</code> array behind the scenes.</p>\n<p>collection.filter(function(model) { return model.get(‘age’) &gt; 10 });\ncollection.each(this.addView);</p>\n<p><code>Function#apply</code> can be slow so we use the method’s arg count, if we know it.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> addMethod = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">base, length, method, attribute</span>) {\n    <span class=\"hljs-keyword\">switch</span> (length) {\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-number\">1</span>: <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n        <span class=\"hljs-keyword\">return</span> base[method](<span class=\"hljs-variable language_\">this</span>[attribute]);\n      };\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-number\">2</span>: <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">value</span>) {\n        <span class=\"hljs-keyword\">return</span> base[method](<span class=\"hljs-variable language_\">this</span>[attribute], value);\n      };\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-number\">3</span>: <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">iteratee, context</span>) {\n        <span class=\"hljs-keyword\">return</span> base[method](<span class=\"hljs-variable language_\">this</span>[attribute], <span class=\"hljs-title function_\">cb</span>(iteratee, <span class=\"hljs-variable language_\">this</span>), context);\n      };\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-number\">4</span>: <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">iteratee, defaultVal, context</span>) {\n        <span class=\"hljs-keyword\">return</span> base[method](<span class=\"hljs-variable language_\">this</span>[attribute], <span class=\"hljs-title function_\">cb</span>(iteratee, <span class=\"hljs-variable language_\">this</span>), defaultVal, context);\n      };\n      <span class=\"hljs-attr\">default</span>: <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n        <span class=\"hljs-keyword\">var</span> args = slice.<span class=\"hljs-title function_\">call</span>(<span class=\"hljs-variable language_\">arguments</span>);\n        args.<span class=\"hljs-title function_\">unshift</span>(<span class=\"hljs-variable language_\">this</span>[attribute]);\n        <span class=\"hljs-keyword\">return</span> base[method].<span class=\"hljs-title function_\">apply</span>(base, args);\n      };\n    }\n  };\n\n  <span class=\"hljs-keyword\">var</span> addUnderscoreMethods = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">Class, base, methods, attribute</span>) {\n    _.<span class=\"hljs-title function_\">each</span>(methods, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">length, method</span>) {\n      <span class=\"hljs-keyword\">if</span> (base[method]) <span class=\"hljs-title class_\">Class</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>[method] = <span class=\"hljs-title function_\">addMethod</span>(base, length, method, attribute);\n    });\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-192\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-192\">&#x00a7;</a>\n              </div>\n              <p>Support <code>collection.sortBy(&#39;attr&#39;)</code> and <code>collection.findWhere({id: 1})</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> cb = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">iteratee, instance</span>) {\n    <span class=\"hljs-keyword\">if</span> (_.<span class=\"hljs-title function_\">isFunction</span>(iteratee)) <span class=\"hljs-keyword\">return</span> iteratee;\n    <span class=\"hljs-keyword\">if</span> (_.<span class=\"hljs-title function_\">isObject</span>(iteratee) &amp;&amp; !instance.<span class=\"hljs-title function_\">_isModel</span>(iteratee)) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title function_\">modelMatcher</span>(iteratee);\n    <span class=\"hljs-keyword\">if</span> (_.<span class=\"hljs-title function_\">isString</span>(iteratee)) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model</span>) { <span class=\"hljs-keyword\">return</span> model.<span class=\"hljs-title function_\">get</span>(iteratee); };\n    <span class=\"hljs-keyword\">return</span> iteratee;\n  };\n  <span class=\"hljs-keyword\">var</span> modelMatcher = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">attrs</span>) {\n    <span class=\"hljs-keyword\">var</span> matcher = _.<span class=\"hljs-title function_\">matches</span>(attrs);\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title function_\">matcher</span>(model.<span class=\"hljs-property\">attributes</span>);\n    };\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-193\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-193\">&#x00a7;</a>\n              </div>\n              <p>Underscore methods that we want to implement on the Collection.\n90% of the core usefulness of Backbone Collections is actually implemented\nright here:</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> collectionMethods = {<span class=\"hljs-attr\">forEach</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">each</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">map</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">collect</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">reduce</span>: <span class=\"hljs-number\">0</span>,\n    <span class=\"hljs-attr\">foldl</span>: <span class=\"hljs-number\">0</span>, <span class=\"hljs-attr\">inject</span>: <span class=\"hljs-number\">0</span>, <span class=\"hljs-attr\">reduceRight</span>: <span class=\"hljs-number\">0</span>, <span class=\"hljs-attr\">foldr</span>: <span class=\"hljs-number\">0</span>, <span class=\"hljs-attr\">find</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">detect</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">filter</span>: <span class=\"hljs-number\">3</span>,\n    <span class=\"hljs-attr\">select</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">reject</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">every</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">all</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">some</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">any</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">include</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">includes</span>: <span class=\"hljs-number\">3</span>,\n    <span class=\"hljs-attr\">contains</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">invoke</span>: <span class=\"hljs-number\">0</span>, <span class=\"hljs-attr\">max</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">min</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">toArray</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">size</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">first</span>: <span class=\"hljs-number\">3</span>,\n    <span class=\"hljs-attr\">head</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">take</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">initial</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">rest</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">tail</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">drop</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">last</span>: <span class=\"hljs-number\">3</span>,\n    <span class=\"hljs-attr\">without</span>: <span class=\"hljs-number\">0</span>, <span class=\"hljs-attr\">difference</span>: <span class=\"hljs-number\">0</span>, <span class=\"hljs-attr\">indexOf</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">shuffle</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">lastIndexOf</span>: <span class=\"hljs-number\">3</span>,\n    <span class=\"hljs-attr\">isEmpty</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">chain</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">sample</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">partition</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">groupBy</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">countBy</span>: <span class=\"hljs-number\">3</span>,\n    <span class=\"hljs-attr\">sortBy</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">indexBy</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">findIndex</span>: <span class=\"hljs-number\">3</span>, <span class=\"hljs-attr\">findLastIndex</span>: <span class=\"hljs-number\">3</span>};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-194\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-194\">&#x00a7;</a>\n              </div>\n              <p>Underscore methods that we want to implement on the Model, mapped to the\nnumber of arguments they take.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> modelMethods = {<span class=\"hljs-attr\">keys</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">values</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">pairs</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">invert</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">pick</span>: <span class=\"hljs-number\">0</span>,\n    <span class=\"hljs-attr\">omit</span>: <span class=\"hljs-number\">0</span>, <span class=\"hljs-attr\">chain</span>: <span class=\"hljs-number\">1</span>, <span class=\"hljs-attr\">isEmpty</span>: <span class=\"hljs-number\">1</span>};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-195\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-195\">&#x00a7;</a>\n              </div>\n              <p>Mix in each Underscore method as a proxy to <code>Collection#models</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>\n  _.<span class=\"hljs-title function_\">each</span>([\n    [<span class=\"hljs-title class_\">Collection</span>, collectionMethods, <span class=\"hljs-string\">&#x27;models&#x27;</span>],\n    [<span class=\"hljs-title class_\">Model</span>, modelMethods, <span class=\"hljs-string\">&#x27;attributes&#x27;</span>]\n  ], <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">config</span>) {\n    <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">Base</span> = config[<span class=\"hljs-number\">0</span>],\n        methods = config[<span class=\"hljs-number\">1</span>],\n        attribute = config[<span class=\"hljs-number\">2</span>];\n\n    <span class=\"hljs-title class_\">Base</span>.<span class=\"hljs-property\">mixin</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">obj</span>) {\n      <span class=\"hljs-keyword\">var</span> mappings = _.<span class=\"hljs-title function_\">reduce</span>(_.<span class=\"hljs-title function_\">functions</span>(obj), <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">memo, name</span>) {\n        memo[name] = <span class=\"hljs-number\">0</span>;\n        <span class=\"hljs-keyword\">return</span> memo;\n      }, {});\n      <span class=\"hljs-title function_\">addUnderscoreMethods</span>(<span class=\"hljs-title class_\">Base</span>, obj, mappings, attribute);\n    };\n\n    <span class=\"hljs-title function_\">addUnderscoreMethods</span>(<span class=\"hljs-title class_\">Base</span>, _, methods, attribute);\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-196\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-196\">&#x00a7;</a>\n              </div>\n              <h2 id=\"backbonesync\">Backbone.sync</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-197\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-197\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-198\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-198\">&#x00a7;</a>\n              </div>\n              <p>Override this function to change the manner in which Backbone persists\nmodels to the server. You will be passed the type of request, and the\nmodel in question. By default, makes a RESTful Ajax request\nto the model’s <code>url()</code>. Some possible customizations could be:</p>\n<ul>\n<li>Use <code>setTimeout</code> to batch rapid-fire updates into a single request.</li>\n<li>Send up the models as XML instead of JSON.</li>\n<li>Persist models via WebSockets instead of Ajax.</li>\n</ul>\n<p>Turn on <code>Backbone.emulateHTTP</code> in order to send <code>PUT</code> and <code>DELETE</code> requests\nas <code>POST</code>, with a <code>_method</code> parameter containing the true HTTP method,\nas well as all requests with the body as <code>application/x-www-form-urlencoded</code>\ninstead of <code>application/json</code> with the model in a param named <code>model</code>.\nUseful when interfacing with server-side languages like <strong>PHP</strong> that make\nit difficult to read the body of <code>PUT</code> requests.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">sync</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">method, model, options</span>) {\n    <span class=\"hljs-keyword\">var</span> type = methodMap[method];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-199\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-199\">&#x00a7;</a>\n              </div>\n              <p>Default options, unless specified.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    _.<span class=\"hljs-title function_\">defaults</span>(options || (options = {}), {\n      <span class=\"hljs-attr\">emulateHTTP</span>: <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">emulateHTTP</span>,\n      <span class=\"hljs-attr\">emulateJSON</span>: <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">emulateJSON</span>\n    });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-200\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-200\">&#x00a7;</a>\n              </div>\n              <p>Default JSON-request options.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">var</span> params = {<span class=\"hljs-attr\">type</span>: type, <span class=\"hljs-attr\">dataType</span>: <span class=\"hljs-string\">&#x27;json&#x27;</span>};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-201\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-201\">&#x00a7;</a>\n              </div>\n              <p>Ensure that we have a URL.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (!options.<span class=\"hljs-property\">url</span>) {\n      params.<span class=\"hljs-property\">url</span> = _.<span class=\"hljs-title function_\">result</span>(model, <span class=\"hljs-string\">&#x27;url&#x27;</span>) || <span class=\"hljs-title function_\">urlError</span>();\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-202\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-202\">&#x00a7;</a>\n              </div>\n              <p>Ensure that we have the appropriate request data.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">data</span> == <span class=\"hljs-literal\">null</span> &amp;&amp; model &amp;&amp; (method === <span class=\"hljs-string\">&#x27;create&#x27;</span> || method === <span class=\"hljs-string\">&#x27;update&#x27;</span> || method === <span class=\"hljs-string\">&#x27;patch&#x27;</span>)) {\n      params.<span class=\"hljs-property\">contentType</span> = <span class=\"hljs-string\">&#x27;application/json&#x27;</span>;\n      params.<span class=\"hljs-property\">data</span> = <span class=\"hljs-title class_\">JSON</span>.<span class=\"hljs-title function_\">stringify</span>(options.<span class=\"hljs-property\">attrs</span> || model.<span class=\"hljs-title function_\">toJSON</span>(options));\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-203\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-203\">&#x00a7;</a>\n              </div>\n              <p>For older servers, emulate JSON by encoding the request into an HTML-form.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">emulateJSON</span>) {\n      params.<span class=\"hljs-property\">contentType</span> = <span class=\"hljs-string\">&#x27;application/x-www-form-urlencoded&#x27;</span>;\n      params.<span class=\"hljs-property\">data</span> = params.<span class=\"hljs-property\">data</span> ? {<span class=\"hljs-attr\">model</span>: params.<span class=\"hljs-property\">data</span>} : {};\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-204\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-204\">&#x00a7;</a>\n              </div>\n              <p>For older servers, emulate HTTP by mimicking the HTTP method with <code>_method</code>\nAnd an <code>X-HTTP-Method-Override</code> header.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">emulateHTTP</span> &amp;&amp; (type === <span class=\"hljs-string\">&#x27;PUT&#x27;</span> || type === <span class=\"hljs-string\">&#x27;DELETE&#x27;</span> || type === <span class=\"hljs-string\">&#x27;PATCH&#x27;</span>)) {\n      params.<span class=\"hljs-property\">type</span> = <span class=\"hljs-string\">&#x27;POST&#x27;</span>;\n      <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">emulateJSON</span>) params.<span class=\"hljs-property\">data</span>.<span class=\"hljs-property\">_method</span> = type;\n      <span class=\"hljs-keyword\">var</span> beforeSend = options.<span class=\"hljs-property\">beforeSend</span>;\n      options.<span class=\"hljs-property\">beforeSend</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">xhr</span>) {\n        xhr.<span class=\"hljs-title function_\">setRequestHeader</span>(<span class=\"hljs-string\">&#x27;X-HTTP-Method-Override&#x27;</span>, type);\n        <span class=\"hljs-keyword\">if</span> (beforeSend) <span class=\"hljs-keyword\">return</span> beforeSend.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n      };\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-205\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-205\">&#x00a7;</a>\n              </div>\n              <p>Don’t process data on a non-GET request.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (params.<span class=\"hljs-property\">type</span> !== <span class=\"hljs-string\">&#x27;GET&#x27;</span> &amp;&amp; !options.<span class=\"hljs-property\">emulateJSON</span>) {\n      params.<span class=\"hljs-property\">processData</span> = <span class=\"hljs-literal\">false</span>;\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-206\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-206\">&#x00a7;</a>\n              </div>\n              <p>Pass along <code>textStatus</code> and <code>errorThrown</code> from jQuery.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">var</span> error = options.<span class=\"hljs-property\">error</span>;\n    options.<span class=\"hljs-property\">error</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">xhr, textStatus, errorThrown</span>) {\n      options.<span class=\"hljs-property\">textStatus</span> = textStatus;\n      options.<span class=\"hljs-property\">errorThrown</span> = errorThrown;\n      <span class=\"hljs-keyword\">if</span> (error) error.<span class=\"hljs-title function_\">call</span>(options.<span class=\"hljs-property\">context</span>, xhr, textStatus, errorThrown);\n    };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-207\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-207\">&#x00a7;</a>\n              </div>\n              <p>Make the request, allowing the user to override any Ajax options.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">var</span> xhr = options.<span class=\"hljs-property\">xhr</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-title function_\">ajax</span>(_.<span class=\"hljs-title function_\">extend</span>(params, options));\n    model.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;request&#x27;</span>, model, xhr, options);\n    <span class=\"hljs-keyword\">return</span> xhr;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-208\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-208\">&#x00a7;</a>\n              </div>\n              <p>Map from CRUD to HTTP for our default <code>Backbone.sync</code> implementation.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> methodMap = {\n    <span class=\"hljs-string\">&#x27;create&#x27;</span>: <span class=\"hljs-string\">&#x27;POST&#x27;</span>,\n    <span class=\"hljs-string\">&#x27;update&#x27;</span>: <span class=\"hljs-string\">&#x27;PUT&#x27;</span>,\n    <span class=\"hljs-string\">&#x27;patch&#x27;</span>: <span class=\"hljs-string\">&#x27;PATCH&#x27;</span>,\n    <span class=\"hljs-string\">&#x27;delete&#x27;</span>: <span class=\"hljs-string\">&#x27;DELETE&#x27;</span>,\n    <span class=\"hljs-string\">&#x27;read&#x27;</span>: <span class=\"hljs-string\">&#x27;GET&#x27;</span>\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-209\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-209\">&#x00a7;</a>\n              </div>\n              <p>Set the default implementation of <code>Backbone.ajax</code> to proxy through to <code>$</code>.\nOverride this if you’d like to use a different library.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">ajax</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">$</span>.<span class=\"hljs-property\">ajax</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">$</span>, <span class=\"hljs-variable language_\">arguments</span>);\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-210\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-210\">&#x00a7;</a>\n              </div>\n              <h2 id=\"backbonerouter\">Backbone.Router</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-211\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-211\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-212\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-212\">&#x00a7;</a>\n              </div>\n              <p>Routers map faux-URLs to actions, and fire events when routes are\nmatched. Creating a new one sets its <code>routes</code> hash, if not set statically.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">Router</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">Router</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n    options || (options = {});\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">preinitialize</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n    <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">routes</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">routes</span> = options.<span class=\"hljs-property\">routes</span>;\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_bindRoutes</span>();\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">initialize</span>.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>);\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-213\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-213\">&#x00a7;</a>\n              </div>\n              <p>Cached regular expressions for matching named param parts and splatted\nparts of route strings.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> optionalParam = <span class=\"hljs-regexp\">/\\((.*?)\\)/g</span>;\n  <span class=\"hljs-keyword\">var</span> namedParam    = <span class=\"hljs-regexp\">/(\\(\\?)?:\\w+/g</span>;\n  <span class=\"hljs-keyword\">var</span> splatParam    = <span class=\"hljs-regexp\">/\\*\\w+/g</span>;\n  <span class=\"hljs-keyword\">var</span> escapeRegExp  = <span class=\"hljs-regexp\">/[\\-{}\\[\\]+?.,\\\\\\^$|#\\s]/g</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-214\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-214\">&#x00a7;</a>\n              </div>\n              <p>Set up all inheritable <strong>Backbone.Router</strong> properties and methods.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  _.<span class=\"hljs-title function_\">extend</span>(<span class=\"hljs-title class_\">Router</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>, <span class=\"hljs-title class_\">Events</span>, {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-215\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-215\">&#x00a7;</a>\n              </div>\n              <p>preinitialize is an empty function by default. You can override it with a function\nor object.  preinitialize will run before any instantiation logic is run in the Router.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">preinitialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){},</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-216\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-216\">&#x00a7;</a>\n              </div>\n              <p>Initialize is an empty function by default. Override it with your own\ninitialization logic.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">initialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){},</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-217\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-217\">&#x00a7;</a>\n              </div>\n              <p>Manually bind a single named route to a callback. For example:</p>\n<pre><code><span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">route</span>(<span class=\"hljs-string\">&#x27;search/:query/p:num&#x27;</span>, <span class=\"hljs-string\">&#x27;search&#x27;</span>, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">query, num</span>) {\n  ...\n});\n</code></pre>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">route</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">route, name, callback</span>) {\n      <span class=\"hljs-keyword\">if</span> (!_.<span class=\"hljs-title function_\">isRegExp</span>(route)) route = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_routeToRegExp</span>(route);\n      <span class=\"hljs-keyword\">if</span> (_.<span class=\"hljs-title function_\">isFunction</span>(name)) {\n        callback = name;\n        name = <span class=\"hljs-string\">&#x27;&#x27;</span>;\n      }\n      <span class=\"hljs-keyword\">if</span> (!callback) callback = <span class=\"hljs-variable language_\">this</span>[name];\n      <span class=\"hljs-keyword\">var</span> router = <span class=\"hljs-variable language_\">this</span>;\n      <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">history</span>.<span class=\"hljs-title function_\">route</span>(route, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">fragment</span>) {\n        <span class=\"hljs-keyword\">var</span> args = router.<span class=\"hljs-title function_\">_extractParameters</span>(route, fragment);\n        <span class=\"hljs-keyword\">if</span> (router.<span class=\"hljs-title function_\">execute</span>(callback, args, name) !== <span class=\"hljs-literal\">false</span>) {\n          router.<span class=\"hljs-property\">trigger</span>.<span class=\"hljs-title function_\">apply</span>(router, [<span class=\"hljs-string\">&#x27;route:&#x27;</span> + name].<span class=\"hljs-title function_\">concat</span>(args));\n          router.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;route&#x27;</span>, name, args);\n          <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">history</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;route&#x27;</span>, router, name, args);\n        }\n      });\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-218\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-218\">&#x00a7;</a>\n              </div>\n              <p>Execute a route handler with the provided parameters.  This is an\nexcellent place to do pre-route setup or post-route cleanup.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">execute</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">callback, args, name</span>) {\n      <span class=\"hljs-keyword\">if</span> (callback) callback.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, args);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-219\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-219\">&#x00a7;</a>\n              </div>\n              <p>Simple proxy to <code>Backbone.history</code> to save a fragment into the history.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">navigate</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">fragment, options</span>) {\n      <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">history</span>.<span class=\"hljs-title function_\">navigate</span>(fragment, options);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-220\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-220\">&#x00a7;</a>\n              </div>\n              <p>Bind all defined routes to <code>Backbone.history</code>. We have to reverse the\norder of the routes here to support behavior where the most general\nroutes can be defined at the bottom of the route map.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_bindRoutes</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">routes</span>) <span class=\"hljs-keyword\">return</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">routes</span> = _.<span class=\"hljs-title function_\">result</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-string\">&#x27;routes&#x27;</span>);\n      <span class=\"hljs-keyword\">var</span> route, routes = _.<span class=\"hljs-title function_\">keys</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">routes</span>);\n      <span class=\"hljs-keyword\">while</span> ((route = routes.<span class=\"hljs-title function_\">pop</span>()) != <span class=\"hljs-literal\">null</span>) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">route</span>(route, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">routes</span>[route]);\n      }\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-221\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-221\">&#x00a7;</a>\n              </div>\n              <p>Convert a route string into a regular expression, suitable for matching\nagainst the current location hash.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_routeToRegExp</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">route</span>) {\n      route = route.<span class=\"hljs-title function_\">replace</span>(escapeRegExp, <span class=\"hljs-string\">&#x27;\\\\$&amp;&#x27;</span>)\n      .<span class=\"hljs-title function_\">replace</span>(optionalParam, <span class=\"hljs-string\">&#x27;(?:$1)?&#x27;</span>)\n      .<span class=\"hljs-title function_\">replace</span>(namedParam, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">match, optional</span>) {\n        <span class=\"hljs-keyword\">return</span> optional ? match : <span class=\"hljs-string\">&#x27;([^/?]+)&#x27;</span>;\n      })\n      .<span class=\"hljs-title function_\">replace</span>(splatParam, <span class=\"hljs-string\">&#x27;([^?]*?)&#x27;</span>);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">RegExp</span>(<span class=\"hljs-string\">&#x27;^&#x27;</span> + route + <span class=\"hljs-string\">&#x27;(?:\\\\?([\\\\s\\\\S]*))?$&#x27;</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-222\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-222\">&#x00a7;</a>\n              </div>\n              <p>Given a route, and a URL fragment that it matches, return the array of\nextracted decoded parameters. Empty or unmatched parameters will be\ntreated as <code>null</code> to normalize cross-browser behavior.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_extractParameters</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">route, fragment</span>) {\n      <span class=\"hljs-keyword\">var</span> params = route.<span class=\"hljs-title function_\">exec</span>(fragment).<span class=\"hljs-title function_\">slice</span>(<span class=\"hljs-number\">1</span>);\n      <span class=\"hljs-keyword\">return</span> _.<span class=\"hljs-title function_\">map</span>(params, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">param, i</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-223\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-223\">&#x00a7;</a>\n              </div>\n              <p>Don’t decode the search params.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"hljs-keyword\">if</span> (i === params.<span class=\"hljs-property\">length</span> - <span class=\"hljs-number\">1</span>) <span class=\"hljs-keyword\">return</span> param || <span class=\"hljs-literal\">null</span>;\n        <span class=\"hljs-keyword\">return</span> param ? <span class=\"hljs-built_in\">decodeURIComponent</span>(param) : <span class=\"hljs-literal\">null</span>;\n      });\n    }\n\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-224\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-224\">&#x00a7;</a>\n              </div>\n              <h2 id=\"backbonehistory\">Backbone.History</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-225\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-225\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-226\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-226\">&#x00a7;</a>\n              </div>\n              <p>Handles cross-browser history management, based on either\n<a href=\"http://diveintohtml5.info/history.html\">pushState</a> and real URLs, or\n<a href=\"https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange\">onhashchange</a>\nand URL fragments. If the browser supports neither (old IE, natch),\nfalls back to polling.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">History</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">History</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">handlers</span> = [];\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">checkUrl</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">checkUrl</span>.<span class=\"hljs-title function_\">bind</span>(<span class=\"hljs-variable language_\">this</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-227\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-227\">&#x00a7;</a>\n              </div>\n              <p>Ensure that <code>History</code> can be used outside of the browser.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-keyword\">typeof</span> <span class=\"hljs-variable language_\">window</span> !== <span class=\"hljs-string\">&#x27;undefined&#x27;</span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">location</span> = <span class=\"hljs-variable language_\">window</span>.<span class=\"hljs-property\">location</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">history</span> = <span class=\"hljs-variable language_\">window</span>.<span class=\"hljs-property\">history</span>;\n    }\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-228\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-228\">&#x00a7;</a>\n              </div>\n              <p>Cached regex for stripping a leading hash/slash and trailing space.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> routeStripper = <span class=\"hljs-regexp\">/^[#\\/]|\\s+$/g</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-229\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-229\">&#x00a7;</a>\n              </div>\n              <p>Cached regex for stripping leading and trailing slashes.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> rootStripper = <span class=\"hljs-regexp\">/^\\/+|\\/+$/g</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-230\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-230\">&#x00a7;</a>\n              </div>\n              <p>Cached regex for stripping urls of hash.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> pathStripper = <span class=\"hljs-regexp\">/#.*$/</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-231\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-231\">&#x00a7;</a>\n              </div>\n              <p>Has the history handling already been started?</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">History</span>.<span class=\"hljs-property\">started</span> = <span class=\"hljs-literal\">false</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-232\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-232\">&#x00a7;</a>\n              </div>\n              <p>Set up all inheritable <strong>Backbone.History</strong> properties and methods.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  _.<span class=\"hljs-title function_\">extend</span>(<span class=\"hljs-title class_\">History</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>, <span class=\"hljs-title class_\">Events</span>, {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-233\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-233\">&#x00a7;</a>\n              </div>\n              <p>The default interval to poll for hash changes, if necessary, is\ntwenty times a second.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">interval</span>: <span class=\"hljs-number\">50</span>,</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-234\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-234\">&#x00a7;</a>\n              </div>\n              <p>Are we at the app root?</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">atRoot</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">var</span> path = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">location</span>.<span class=\"hljs-property\">pathname</span>.<span class=\"hljs-title function_\">replace</span>(<span class=\"hljs-regexp\">/[^\\/]$/</span>, <span class=\"hljs-string\">&#x27;$&amp;/&#x27;</span>);\n      <span class=\"hljs-keyword\">return</span> path === <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">root</span> &amp;&amp; !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getSearch</span>();\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-235\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-235\">&#x00a7;</a>\n              </div>\n              <p>Does the pathname match the root?</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">matchRoot</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">var</span> path = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">decodeFragment</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">location</span>.<span class=\"hljs-property\">pathname</span>);\n      <span class=\"hljs-keyword\">var</span> rootPath = path.<span class=\"hljs-title function_\">slice</span>(<span class=\"hljs-number\">0</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">root</span>.<span class=\"hljs-property\">length</span> - <span class=\"hljs-number\">1</span>) + <span class=\"hljs-string\">&#x27;/&#x27;</span>;\n      <span class=\"hljs-keyword\">return</span> rootPath === <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">root</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-236\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-236\">&#x00a7;</a>\n              </div>\n              <p>Unicode characters in <code>location.pathname</code> are percent encoded so they’re\ndecoded for comparison. <code>%25</code> should not be decoded since it may be part\nof an encoded parameter.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">decodeFragment</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">fragment</span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">decodeURI</span>(fragment.<span class=\"hljs-title function_\">replace</span>(<span class=\"hljs-regexp\">/%25/g</span>, <span class=\"hljs-string\">&#x27;%2525&#x27;</span>));\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-237\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-237\">&#x00a7;</a>\n              </div>\n              <p>In IE6, the hash fragment and search params are incorrect if the\nfragment contains <code>?</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">getSearch</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">var</span> match = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">location</span>.<span class=\"hljs-property\">href</span>.<span class=\"hljs-title function_\">replace</span>(<span class=\"hljs-regexp\">/#.*/</span>, <span class=\"hljs-string\">&#x27;&#x27;</span>).<span class=\"hljs-title function_\">match</span>(<span class=\"hljs-regexp\">/\\?.+/</span>);\n      <span class=\"hljs-keyword\">return</span> match ? match[<span class=\"hljs-number\">0</span>] : <span class=\"hljs-string\">&#x27;&#x27;</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-238\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-238\">&#x00a7;</a>\n              </div>\n              <p>Gets the true hash value. Cannot use location.hash directly due to bug\nin Firefox where location.hash will always be decoded.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">getHash</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"><span class=\"hljs-variable language_\">window</span></span>) {\n      <span class=\"hljs-keyword\">var</span> match = (<span class=\"hljs-variable language_\">window</span> || <span class=\"hljs-variable language_\">this</span>).<span class=\"hljs-property\">location</span>.<span class=\"hljs-property\">href</span>.<span class=\"hljs-title function_\">match</span>(<span class=\"hljs-regexp\">/#(.*)$/</span>);\n      <span class=\"hljs-keyword\">return</span> match ? match[<span class=\"hljs-number\">1</span>] : <span class=\"hljs-string\">&#x27;&#x27;</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-239\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-239\">&#x00a7;</a>\n              </div>\n              <p>Get the pathname and search params, without the root.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">getPath</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">var</span> path = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">decodeFragment</span>(\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">location</span>.<span class=\"hljs-property\">pathname</span> + <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getSearch</span>()\n      ).<span class=\"hljs-title function_\">slice</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">root</span>.<span class=\"hljs-property\">length</span> - <span class=\"hljs-number\">1</span>);\n      <span class=\"hljs-keyword\">return</span> path.<span class=\"hljs-title function_\">charAt</span>(<span class=\"hljs-number\">0</span>) === <span class=\"hljs-string\">&#x27;/&#x27;</span> ? path.<span class=\"hljs-title function_\">slice</span>(<span class=\"hljs-number\">1</span>) : path;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-240\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-240\">&#x00a7;</a>\n              </div>\n              <p>Get the cross-browser normalized URL fragment from the path or hash.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">getFragment</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">fragment</span>) {\n      <span class=\"hljs-keyword\">if</span> (fragment == <span class=\"hljs-literal\">null</span>) {\n        <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_usePushState</span> || !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsHashChange</span>) {\n          fragment = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getPath</span>();\n        } <span class=\"hljs-keyword\">else</span> {\n          fragment = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getHash</span>();\n        }\n      }\n      <span class=\"hljs-keyword\">return</span> fragment.<span class=\"hljs-title function_\">replace</span>(routeStripper, <span class=\"hljs-string\">&#x27;&#x27;</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-241\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-241\">&#x00a7;</a>\n              </div>\n              <p>Start the hash change handling, returning <code>true</code> if the current URL matches\nan existing route, and <code>false</code> otherwise.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">start</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">options</span>) {\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-title class_\">History</span>.<span class=\"hljs-property\">started</span>) <span class=\"hljs-keyword\">throw</span> <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">Error</span>(<span class=\"hljs-string\">&#x27;Backbone.history has already been started&#x27;</span>);\n      <span class=\"hljs-title class_\">History</span>.<span class=\"hljs-property\">started</span> = <span class=\"hljs-literal\">true</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-242\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-242\">&#x00a7;</a>\n              </div>\n              <p>Figure out the initial configuration. Do we need an iframe?\nIs pushState desired … is it available?</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">options</span>          = _.<span class=\"hljs-title function_\">extend</span>({<span class=\"hljs-attr\">root</span>: <span class=\"hljs-string\">&#x27;/&#x27;</span>}, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">options</span>, options);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">root</span>             = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">options</span>.<span class=\"hljs-property\">root</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_trailingSlash</span>   = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">options</span>.<span class=\"hljs-property\">trailingSlash</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsHashChange</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">options</span>.<span class=\"hljs-property\">hashChange</span> !== <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_hasHashChange</span>   = <span class=\"hljs-string\">&#x27;onhashchange&#x27;</span> <span class=\"hljs-keyword\">in</span> <span class=\"hljs-variable language_\">window</span> &amp;&amp; (<span class=\"hljs-variable language_\">document</span>.<span class=\"hljs-property\">documentMode</span> === <span class=\"hljs-keyword\">void</span> <span class=\"hljs-number\">0</span> || <span class=\"hljs-variable language_\">document</span>.<span class=\"hljs-property\">documentMode</span> &gt; <span class=\"hljs-number\">7</span>);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_useHashChange</span>   = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsHashChange</span> &amp;&amp; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_hasHashChange</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsPushState</span>  = !!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">options</span>.<span class=\"hljs-property\">pushState</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_hasPushState</span>    = !!(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">history</span> &amp;&amp; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">history</span>.<span class=\"hljs-property\">pushState</span>);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_usePushState</span>    = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsPushState</span> &amp;&amp; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_hasPushState</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">fragment</span>         = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getFragment</span>();</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-243\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-243\">&#x00a7;</a>\n              </div>\n              <p>Normalize root to always include a leading and trailing slash.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">root</span> = (<span class=\"hljs-string\">&#x27;/&#x27;</span> + <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">root</span> + <span class=\"hljs-string\">&#x27;/&#x27;</span>).<span class=\"hljs-title function_\">replace</span>(rootStripper, <span class=\"hljs-string\">&#x27;/&#x27;</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-244\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-244\">&#x00a7;</a>\n              </div>\n              <p>Transition from hashChange to pushState or vice versa if both are\nrequested.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsHashChange</span> &amp;&amp; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsPushState</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-245\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-245\">&#x00a7;</a>\n              </div>\n              <p>If we’ve started off with a route from a <code>pushState</code>-enabled\nbrowser, but we’re currently in a browser that doesn’t support it…</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_hasPushState</span> &amp;&amp; !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">atRoot</span>()) {\n          <span class=\"hljs-keyword\">var</span> rootPath = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">root</span>.<span class=\"hljs-title function_\">slice</span>(<span class=\"hljs-number\">0</span>, -<span class=\"hljs-number\">1</span>) || <span class=\"hljs-string\">&#x27;/&#x27;</span>;\n          <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">location</span>.<span class=\"hljs-title function_\">replace</span>(rootPath + <span class=\"hljs-string\">&#x27;#&#x27;</span> + <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getPath</span>());</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-246\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-246\">&#x00a7;</a>\n              </div>\n              <p>Return immediately as browser will do redirect to new url</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>          <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-247\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-247\">&#x00a7;</a>\n              </div>\n              <p>Or if we’ve started out with a hash-based route, but we’re currently\nin a browser where it could be <code>pushState</code>-based instead…</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_hasPushState</span> &amp;&amp; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">atRoot</span>()) {\n          <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">navigate</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getHash</span>(), {<span class=\"hljs-attr\">replace</span>: <span class=\"hljs-literal\">true</span>});\n        }\n\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-248\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-248\">&#x00a7;</a>\n              </div>\n              <p>Proxy an iframe to handle location events if the browser doesn’t\nsupport the <code>hashchange</code> event, HTML5 history, or the user wants\n<code>hashChange</code> but not <code>pushState</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_hasHashChange</span> &amp;&amp; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsHashChange</span> &amp;&amp; !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_usePushState</span>) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span> = <span class=\"hljs-variable language_\">document</span>.<span class=\"hljs-title function_\">createElement</span>(<span class=\"hljs-string\">&#x27;iframe&#x27;</span>);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>.<span class=\"hljs-property\">src</span> = <span class=\"hljs-string\">&#x27;javascript:0&#x27;</span>;\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>.<span class=\"hljs-property\">style</span>.<span class=\"hljs-property\">display</span> = <span class=\"hljs-string\">&#x27;none&#x27;</span>;\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>.<span class=\"hljs-property\">tabIndex</span> = -<span class=\"hljs-number\">1</span>;\n        <span class=\"hljs-keyword\">var</span> body = <span class=\"hljs-variable language_\">document</span>.<span class=\"hljs-property\">body</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-249\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-249\">&#x00a7;</a>\n              </div>\n              <p>Using <code>appendChild</code> will throw on IE &lt; 9 if the document is not ready.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"hljs-keyword\">var</span> iWindow = body.<span class=\"hljs-title function_\">insertBefore</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>, body.<span class=\"hljs-property\">firstChild</span>).<span class=\"hljs-property\">contentWindow</span>;\n        iWindow.<span class=\"hljs-property\">document</span>.<span class=\"hljs-title function_\">open</span>();\n        iWindow.<span class=\"hljs-property\">document</span>.<span class=\"hljs-title function_\">close</span>();\n        iWindow.<span class=\"hljs-property\">location</span>.<span class=\"hljs-property\">hash</span> = <span class=\"hljs-string\">&#x27;#&#x27;</span> + <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">fragment</span>;\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-250\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-250\">&#x00a7;</a>\n              </div>\n              <p>Add a cross-platform <code>addEventListener</code> shim for older browsers.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> addEventListener = <span class=\"hljs-variable language_\">window</span>.<span class=\"hljs-property\">addEventListener</span> || <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">eventName, listener</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title function_\">attachEvent</span>(<span class=\"hljs-string\">&#x27;on&#x27;</span> + eventName, listener);\n      };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-251\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-251\">&#x00a7;</a>\n              </div>\n              <p>Depending on whether we’re using pushState or hashes, and whether\n‘onhashchange’ is supported, determine how we check the URL state.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_usePushState</span>) {\n        <span class=\"hljs-title function_\">addEventListener</span>(<span class=\"hljs-string\">&#x27;popstate&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">checkUrl</span>, <span class=\"hljs-literal\">false</span>);\n      } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_useHashChange</span> &amp;&amp; !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>) {\n        <span class=\"hljs-title function_\">addEventListener</span>(<span class=\"hljs-string\">&#x27;hashchange&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">checkUrl</span>, <span class=\"hljs-literal\">false</span>);\n      } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsHashChange</span>) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_checkUrlInterval</span> = <span class=\"hljs-built_in\">setInterval</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">checkUrl</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">interval</span>);\n      }\n\n      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">options</span>.<span class=\"hljs-property\">silent</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">loadUrl</span>();\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-252\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-252\">&#x00a7;</a>\n              </div>\n              <p>Disable Backbone.history, perhaps temporarily. Not useful in a real app,\nbut possibly useful for unit testing Routers.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">stop</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-253\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-253\">&#x00a7;</a>\n              </div>\n              <p>Add a cross-platform <code>removeEventListener</code> shim for older browsers.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> removeEventListener = <span class=\"hljs-variable language_\">window</span>.<span class=\"hljs-property\">removeEventListener</span> || <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">eventName, listener</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title function_\">detachEvent</span>(<span class=\"hljs-string\">&#x27;on&#x27;</span> + eventName, listener);\n      };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-254\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-254\">&#x00a7;</a>\n              </div>\n              <p>Remove window listeners.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_usePushState</span>) {\n        <span class=\"hljs-title function_\">removeEventListener</span>(<span class=\"hljs-string\">&#x27;popstate&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">checkUrl</span>, <span class=\"hljs-literal\">false</span>);\n      } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_useHashChange</span> &amp;&amp; !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>) {\n        <span class=\"hljs-title function_\">removeEventListener</span>(<span class=\"hljs-string\">&#x27;hashchange&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">checkUrl</span>, <span class=\"hljs-literal\">false</span>);\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-255\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-255\">&#x00a7;</a>\n              </div>\n              <p>Clean up the iframe if necessary.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>) {\n        <span class=\"hljs-variable language_\">document</span>.<span class=\"hljs-property\">body</span>.<span class=\"hljs-title function_\">removeChild</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>);\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span> = <span class=\"hljs-literal\">null</span>;\n      }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-256\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-256\">&#x00a7;</a>\n              </div>\n              <p>Some environments will throw when clearing an undefined interval.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_checkUrlInterval</span>) <span class=\"hljs-built_in\">clearInterval</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_checkUrlInterval</span>);\n      <span class=\"hljs-title class_\">History</span>.<span class=\"hljs-property\">started</span> = <span class=\"hljs-literal\">false</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-257\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-257\">&#x00a7;</a>\n              </div>\n              <p>Add a route to be tested when the fragment changes. Routes added later\nmay override previous routes.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">route</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">route, callback</span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">handlers</span>.<span class=\"hljs-title function_\">unshift</span>({<span class=\"hljs-attr\">route</span>: route, <span class=\"hljs-attr\">callback</span>: callback});\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-258\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-258\">&#x00a7;</a>\n              </div>\n              <p>Checks the current URL to see if it has changed, and if it has,\ncalls <code>loadUrl</code>, normalizing across the hidden iframe.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">checkUrl</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">e</span>) {\n      <span class=\"hljs-keyword\">var</span> current = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getFragment</span>();</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-259\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-259\">&#x00a7;</a>\n              </div>\n              <p>If the user pressed the back button, the iframe’s hash will have\nchanged and we should use that for comparison.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (current === <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">fragment</span> &amp;&amp; <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>) {\n        current = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getHash</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>.<span class=\"hljs-property\">contentWindow</span>);\n      }\n\n      <span class=\"hljs-keyword\">if</span> (current === <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">fragment</span>) {\n        <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">matchRoot</span>()) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">notfound</span>();\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      }\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">navigate</span>(current);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">loadUrl</span>();\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-260\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-260\">&#x00a7;</a>\n              </div>\n              <p>Attempt to load the current URL fragment. If a route succeeds with a\nmatch, returns <code>true</code>. If no defined routes matches the fragment,\nreturns <code>false</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">loadUrl</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">fragment</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-261\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-261\">&#x00a7;</a>\n              </div>\n              <p>If the root doesn’t match, no routes can match either.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">matchRoot</span>()) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">notfound</span>();\n      fragment = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">fragment</span> = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getFragment</span>(fragment);\n      <span class=\"hljs-keyword\">return</span> _.<span class=\"hljs-title function_\">some</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">handlers</span>, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">handler</span>) {\n        <span class=\"hljs-keyword\">if</span> (handler.<span class=\"hljs-property\">route</span>.<span class=\"hljs-title function_\">test</span>(fragment)) {\n          handler.<span class=\"hljs-title function_\">callback</span>(fragment);\n          <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n        }\n      }) || <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">notfound</span>();\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-262\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-262\">&#x00a7;</a>\n              </div>\n              <p>When no route could be matched, this method is called internally to\ntrigger the <code>&#39;notfound&#39;</code> event. It returns <code>false</code> so that it can be used\nin tail position.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">notfound</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;notfound&#x27;</span>);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-263\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-263\">&#x00a7;</a>\n              </div>\n              <p>Save a fragment into the hash history, or replace the URL state if the\n‘replace’ option is passed. You are responsible for properly URL-encoding\nthe fragment in advance.</p>\n<p>The options object can contain <code>trigger: true</code> if you wish to have the\nroute callback be fired (not usually desirable), or <code>replace: true</code>, if\nyou wish to modify the current URL without adding an entry to the history.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">navigate</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">fragment, options</span>) {\n      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-title class_\">History</span>.<span class=\"hljs-property\">started</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      <span class=\"hljs-keyword\">if</span> (!options || options === <span class=\"hljs-literal\">true</span>) options = {<span class=\"hljs-attr\">trigger</span>: !!options};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-264\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-264\">&#x00a7;</a>\n              </div>\n              <p>Normalize the fragment.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      fragment = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getFragment</span>(fragment || <span class=\"hljs-string\">&#x27;&#x27;</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-265\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-265\">&#x00a7;</a>\n              </div>\n              <p>Strip trailing slash on the root unless _trailingSlash is true</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> rootPath = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">root</span>;\n      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_trailingSlash</span> &amp;&amp; (fragment === <span class=\"hljs-string\">&#x27;&#x27;</span> || fragment.<span class=\"hljs-title function_\">charAt</span>(<span class=\"hljs-number\">0</span>) === <span class=\"hljs-string\">&#x27;?&#x27;</span>)) {\n        rootPath = rootPath.<span class=\"hljs-title function_\">slice</span>(<span class=\"hljs-number\">0</span>, -<span class=\"hljs-number\">1</span>) || <span class=\"hljs-string\">&#x27;/&#x27;</span>;\n      }\n      <span class=\"hljs-keyword\">var</span> url = rootPath + fragment;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-266\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-266\">&#x00a7;</a>\n              </div>\n              <p>Strip the fragment of the query and hash for matching.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      fragment = fragment.<span class=\"hljs-title function_\">replace</span>(pathStripper, <span class=\"hljs-string\">&#x27;&#x27;</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-267\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-267\">&#x00a7;</a>\n              </div>\n              <p>Decode for matching.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">var</span> decodedFragment = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">decodeFragment</span>(fragment);\n\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">fragment</span> === decodedFragment) <span class=\"hljs-keyword\">return</span>;\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">fragment</span> = decodedFragment;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-268\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-268\">&#x00a7;</a>\n              </div>\n              <p>If pushState is available, we use it to set the fragment as a real URL.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_usePushState</span>) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">history</span>[options.<span class=\"hljs-property\">replace</span> ? <span class=\"hljs-string\">&#x27;replaceState&#x27;</span> : <span class=\"hljs-string\">&#x27;pushState&#x27;</span>]({}, <span class=\"hljs-variable language_\">document</span>.<span class=\"hljs-property\">title</span>, url);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-269\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-269\">&#x00a7;</a>\n              </div>\n              <p>If hash changes haven’t been explicitly disabled, update the hash\nfragment to store history.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      } <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">_wantsHashChange</span>) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_updateHash</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">location</span>, fragment, options.<span class=\"hljs-property\">replace</span>);\n        <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span> &amp;&amp; fragment !== <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">getHash</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>.<span class=\"hljs-property\">contentWindow</span>)) {\n          <span class=\"hljs-keyword\">var</span> iWindow = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">iframe</span>.<span class=\"hljs-property\">contentWindow</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-270\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-270\">&#x00a7;</a>\n              </div>\n              <p>Opening and closing the iframe tricks IE7 and earlier to push a\nhistory entry on hash-tag change.  When replace is true, we don’t\nwant this.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>          <span class=\"hljs-keyword\">if</span> (!options.<span class=\"hljs-property\">replace</span>) {\n            iWindow.<span class=\"hljs-property\">document</span>.<span class=\"hljs-title function_\">open</span>();\n            iWindow.<span class=\"hljs-property\">document</span>.<span class=\"hljs-title function_\">close</span>();\n          }\n\n          <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">_updateHash</span>(iWindow.<span class=\"hljs-property\">location</span>, fragment, options.<span class=\"hljs-property\">replace</span>);\n        }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-271\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-271\">&#x00a7;</a>\n              </div>\n              <p>If you’ve told us that you explicitly don’t want fallback hashchange-\nbased history, then <code>navigate</code> becomes a page refresh.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      } <span class=\"hljs-keyword\">else</span> {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">location</span>.<span class=\"hljs-title function_\">assign</span>(url);\n      }\n      <span class=\"hljs-keyword\">if</span> (options.<span class=\"hljs-property\">trigger</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">loadUrl</span>(fragment);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-272\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-272\">&#x00a7;</a>\n              </div>\n              <p>Update the hash location, either replacing the current entry, or adding\na new one to the browser history.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">_updateHash</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">location, fragment, replace</span>) {\n      <span class=\"hljs-keyword\">if</span> (replace) {\n        <span class=\"hljs-keyword\">var</span> href = location.<span class=\"hljs-property\">href</span>.<span class=\"hljs-title function_\">replace</span>(<span class=\"hljs-regexp\">/(javascript:|#).*$/</span>, <span class=\"hljs-string\">&#x27;&#x27;</span>);\n        location.<span class=\"hljs-title function_\">replace</span>(href + <span class=\"hljs-string\">&#x27;#&#x27;</span> + fragment);\n      } <span class=\"hljs-keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-273\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-273\">&#x00a7;</a>\n              </div>\n              <p>Some browsers require that <code>hash</code> contains a leading #.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        location.<span class=\"hljs-property\">hash</span> = <span class=\"hljs-string\">&#x27;#&#x27;</span> + fragment;\n      }\n    }\n\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-274\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-274\">&#x00a7;</a>\n              </div>\n              <p>Create the default Backbone.history.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">history</span> = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">History</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-275\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-275\">&#x00a7;</a>\n              </div>\n              <h2 id=\"helpers\">Helpers</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-276\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-276\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-277\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-277\">&#x00a7;</a>\n              </div>\n              <p>Helper function to correctly set up the prototype chain for subclasses.\nSimilar to <code>goog.inherits</code>, but uses a hash of prototype properties and\nclass properties to be extended.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> extend = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">protoProps, staticProps</span>) {\n    <span class=\"hljs-keyword\">var</span> parent = <span class=\"hljs-variable language_\">this</span>;\n    <span class=\"hljs-keyword\">var</span> child;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-278\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-278\">&#x00a7;</a>\n              </div>\n              <p>The constructor function for the new subclass is either defined by you\n(the “constructor” property in your <code>extend</code> definition), or defaulted\nby us to simply call the parent constructor.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-keyword\">if</span> (protoProps &amp;&amp; _.<span class=\"hljs-title function_\">has</span>(protoProps, <span class=\"hljs-string\">&#x27;constructor&#x27;</span>)) {\n      child = protoProps.<span class=\"hljs-property\">constructor</span>;\n    } <span class=\"hljs-keyword\">else</span> {\n      child = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){ <span class=\"hljs-keyword\">return</span> parent.<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-variable language_\">arguments</span>); };\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-279\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-279\">&#x00a7;</a>\n              </div>\n              <p>Add static properties to the constructor function, if supplied.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    _.<span class=\"hljs-title function_\">extend</span>(child, parent, staticProps);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-280\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-280\">&#x00a7;</a>\n              </div>\n              <p>Set the prototype chain to inherit from <code>parent</code>, without calling\n<code>parent</code>‘s constructor function and add the prototype properties.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    child.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span> = _.<span class=\"hljs-title function_\">create</span>(parent.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>, protoProps);\n    child.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>.<span class=\"hljs-property\">constructor</span> = child;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-281\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-281\">&#x00a7;</a>\n              </div>\n              <p>Set a convenience property in case the parent’s prototype is needed\nlater.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    child.<span class=\"hljs-property\">__super__</span> = parent.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>;\n\n    <span class=\"hljs-keyword\">return</span> child;\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-282\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-282\">&#x00a7;</a>\n              </div>\n              <p>Set up inheritance for the model, collection, router, view and history.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Model</span>.<span class=\"hljs-property\">extend</span> = <span class=\"hljs-title class_\">Collection</span>.<span class=\"hljs-property\">extend</span> = <span class=\"hljs-title class_\">Router</span>.<span class=\"hljs-property\">extend</span> = <span class=\"hljs-title class_\">View</span>.<span class=\"hljs-property\">extend</span> = <span class=\"hljs-title class_\">History</span>.<span class=\"hljs-property\">extend</span> = extend;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-283\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-283\">&#x00a7;</a>\n              </div>\n              <p>Throw an error when a URL is needed, and none is supplied.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> urlError = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    <span class=\"hljs-keyword\">throw</span> <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">Error</span>(<span class=\"hljs-string\">&#x27;A &quot;url&quot; property or function must be specified&#x27;</span>);\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-284\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-284\">&#x00a7;</a>\n              </div>\n              <p>Wrap an optional error callback with a fallback error event.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> wrapError = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model, options</span>) {\n    <span class=\"hljs-keyword\">var</span> error = options.<span class=\"hljs-property\">error</span>;\n    options.<span class=\"hljs-property\">error</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">resp</span>) {\n      <span class=\"hljs-keyword\">if</span> (error) error.<span class=\"hljs-title function_\">call</span>(options.<span class=\"hljs-property\">context</span>, model, resp, options);\n      model.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&#x27;error&#x27;</span>, model, resp, options);\n    };\n  };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-285\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-285\">&#x00a7;</a>\n              </div>\n              <p>Provide useful information when things go wrong. This method is not meant\nto be used directly; it merely provides the necessary introspection for the\nexternal <code>debugInfo</code> function.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">_debug</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    <span class=\"hljs-keyword\">return</span> {<span class=\"hljs-attr\">root</span>: root, <span class=\"hljs-attr\">_</span>: _};\n  };\n\n  <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title class_\">Backbone</span>;\n});</pre></div></div>\n            \n        </li>\n        \n    </ul>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "docs/backbone.localStorage.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head></head>\n<body>\n  <p>This annotated source has moved to <a href=\"examples/backbone.localStorage.html\">examples/backbone.localStorage.html</a>. You will be automatically redirected in two seconds.</p>\n  <script>\n    setTimeout(function() {\n      location = 'examples/backbone.localStorage.html';\n    }, 2000);\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/docco.css",
    "content": "/*--------------------- Typography ----------------------------*/\n\n@font-face {\n    font-family: 'aller-light';\n    src: url('public/fonts/aller-light.eot');\n    src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'),\n         url('public/fonts/aller-light.woff') format('woff'),\n         url('public/fonts/aller-light.ttf') format('truetype');\n    font-weight: normal;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'aller-bold';\n    src: url('public/fonts/aller-bold.eot');\n    src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'),\n         url('public/fonts/aller-bold.woff') format('woff'),\n         url('public/fonts/aller-bold.ttf') format('truetype');\n    font-weight: normal;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'roboto-black';\n    src: url('public/fonts/roboto-black.eot');\n    src: url('public/fonts/roboto-black.eot?#iefix') format('embedded-opentype'),\n         url('public/fonts/roboto-black.woff') format('woff'),\n         url('public/fonts/roboto-black.ttf') format('truetype');\n    font-weight: normal;\n    font-style: normal;\n}\n\n/*--------------------- Layout ----------------------------*/\nhtml { height: 100%; }\nbody {\n  font-family: \"aller-light\";\n  font-size: 14px;\n  line-height: 18px;\n  color: #30404f;\n  margin: 0; padding: 0;\n  height:100%;\n}\n#container { min-height: 100%; }\n\na {\n  color: #000;\n}\n\nb, strong {\n  font-weight: normal;\n  font-family: \"aller-bold\";\n}\n\np {\n  margin: 15px 0 0px;\n}\n  .annotation ul, .annotation ol {\n    margin: 25px 0;\n  }\n    .annotation ul li, .annotation ol li {\n      font-size: 14px;\n      line-height: 18px;\n      margin: 10px 0;\n    }\n\nh1, h2, h3, h4, h5, h6 {\n  color: #112233;\n  line-height: 1em;\n  font-weight: normal;\n  font-family: \"roboto-black\";\n  text-transform: uppercase;\n  margin: 30px 0 15px 0;\n}\n\nh1 {\n  margin-top: 40px;\n}\nh2 {\n  font-size: 1.26em;\n}\n\nhr {\n  border: 0;\n  background: 1px #ddd;\n  height: 1px;\n  margin: 20px 0;\n}\n\npre, tt, code {\n  font-size: 12px; line-height: 16px;\n  font-family: Menlo, Monaco, Consolas, \"Lucida Console\", monospace;\n  margin: 0; padding: 0;\n}\n  .annotation pre {\n    display: block;\n    margin: 0;\n    padding: 7px 10px;\n    background: #fcfcfc;\n    -moz-box-shadow:    inset 0 0 10px rgba(0,0,0,0.1);\n    -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);\n    box-shadow:         inset 0 0 10px rgba(0,0,0,0.1);\n    overflow-x: auto;\n  }\n    .annotation pre code {\n      border: 0;\n      padding: 0;\n      background: transparent;\n    }\n\n\nblockquote {\n  border-left: 5px solid #ccc;\n  margin: 0;\n  padding: 1px 0 1px 1em;\n}\n  .sections blockquote p {\n    font-family: Menlo, Consolas, Monaco, monospace;\n    font-size: 12px; line-height: 16px;\n    color: #999;\n    margin: 10px 0 0;\n    white-space: pre-wrap;\n  }\n\nul.sections {\n  list-style: none;\n  padding:0 0 5px 0;;\n  margin:0;\n}\n\n/*\n  Force border-box so that % widths fit the parent\n  container without overlap because of margin/padding.\n\n  More Info : http://www.quirksmode.org/css/box.html\n*/\nul.sections > li > div {\n  -moz-box-sizing: border-box;    /* firefox */\n  -ms-box-sizing: border-box;     /* ie */\n  -webkit-box-sizing: border-box; /* webkit */\n  -khtml-box-sizing: border-box;  /* konqueror */\n  box-sizing: border-box;         /* css3 */\n}\n\n\n/*---------------------- Jump Page -----------------------------*/\n#jump_to, #jump_page {\n  margin: 0;\n  background: white;\n  -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;\n  -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;\n  font: 16px Arial;\n  cursor: pointer;\n  text-align: right;\n  list-style: none;\n}\n\n#jump_to a {\n  text-decoration: none;\n}\n\n#jump_to a.large {\n  display: none;\n}\n#jump_to a.small {\n  font-size: 22px;\n  font-weight: bold;\n  color: #676767;\n}\n\n#jump_to, #jump_wrapper {\n  position: fixed;\n  right: 0; top: 0;\n  padding: 10px 15px;\n  margin:0;\n}\n\n#jump_wrapper {\n  display: none;\n  padding:0;\n}\n\n#jump_to:hover #jump_wrapper {\n  display: block;\n}\n\n#jump_page_wrapper{\n  position: fixed;\n  right: 0;\n  top: 0;\n  bottom: 0;\n}\n\n#jump_page {\n  padding: 5px 0 3px;\n  margin: 0 0 25px 25px;\n  max-height: 100%;\n  overflow: auto;\n}\n\n#jump_page .source {\n  display: block;\n  padding: 15px;\n  text-decoration: none;\n  border-top: 1px solid #eee;\n}\n\n#jump_page .source:hover {\n  background: #f5f5ff;\n}\n\n#jump_page .source:first-child {\n}\n\n/*---------------------- Low resolutions (> 320px) ---------------------*/\n@media only screen and (min-width: 320px) {\n  .sswrap { display: none; }\n\n  ul.sections > li > div {\n    display: block;\n    padding:5px 10px 0 10px;\n  }\n\n  ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {\n    padding-left: 30px;\n  }\n\n  ul.sections > li > div.content {\n    overflow-x:auto;\n    -webkit-box-shadow: inset 0 0 5px #e5e5ee;\n    box-shadow: inset 0 0 5px #e5e5ee;\n    border: 1px solid #dedede;\n    margin:5px 10px 5px 10px;\n    padding-bottom: 5px;\n  }\n\n  ul.sections > li > div.annotation pre {\n    margin: 7px 0 7px;\n    padding-left: 15px;\n  }\n\n  ul.sections > li > div.annotation p tt, .annotation code {\n    background: #f8f8ff;\n    border: 1px solid #dedede;\n    font-size: 12px;\n    padding: 0 0.2em;\n  }\n}\n\n/*----------------------  (> 481px) ---------------------*/\n@media only screen and (min-width: 481px) {\n  #container {\n    position: relative;\n  }\n  body {\n    background-color: #F5F5FF;\n    font-size: 15px;\n    line-height: 21px;\n  }\n  pre, tt, code {\n    line-height: 18px;\n  }\n  p, ul, ol {\n    margin: 0 0 15px;\n  }\n\n\n  #jump_to {\n    padding: 5px 10px;\n  }\n  #jump_wrapper {\n    padding: 0;\n  }\n  #jump_to, #jump_page {\n    font: 10px Arial;\n    text-transform: uppercase;\n  }\n  #jump_page .source {\n    padding: 5px 10px;\n  }\n  #jump_to a.large {\n    display: inline-block;\n  }\n  #jump_to a.small {\n    display: none;\n  }\n\n\n\n  #background {\n    position: absolute;\n    top: 0; bottom: 0;\n    width: 350px;\n    background: #fff;\n    border-right: 1px solid #e5e5ee;\n    z-index: -1;\n  }\n\n  ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {\n    padding-left: 40px;\n  }\n\n  ul.sections > li {\n    white-space: nowrap;\n  }\n\n  ul.sections > li > div {\n    display: inline-block;\n  }\n\n  ul.sections > li > div.annotation {\n    max-width: 350px;\n    min-width: 350px;\n    min-height: 5px;\n    padding: 13px;\n    overflow-x: hidden;\n    white-space: normal;\n    vertical-align: top;\n    text-align: left;\n  }\n  ul.sections > li > div.annotation pre {\n    margin: 15px 0 15px;\n    padding-left: 15px;\n  }\n\n  ul.sections > li > div.content {\n    padding: 13px;\n    vertical-align: top;\n    border: none;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n\n  .sswrap {\n    position: relative;\n    display: inline;\n  }\n\n  .ss {\n    font: 12px Arial;\n    text-decoration: none;\n    color: #454545;\n    position: absolute;\n    top: 3px; left: -20px;\n    padding: 1px 2px;\n    opacity: 0;\n    -webkit-transition: opacity 0.2s linear;\n  }\n    .for-h1 .ss {\n      top: 47px;\n    }\n    .for-h2 .ss, .for-h3 .ss, .for-h4 .ss {\n      top: 35px;\n    }\n\n  ul.sections > li > div.annotation:hover .ss {\n    opacity: 1;\n  }\n}\n\n/*---------------------- (> 1025px) ---------------------*/\n@media only screen and (min-width: 1025px) {\n\n  body {\n    font-size: 16px;\n    line-height: 24px;\n  }\n\n  #background {\n    width: 525px;\n  }\n  ul.sections > li > div.annotation {\n    max-width: 525px;\n    min-width: 525px;\n    padding: 10px 25px 1px 50px;\n  }\n  ul.sections > li > div.content {\n    padding: 9px 15px 16px 25px;\n  }\n}\n\n/*---------------------- Syntax Highlighting -----------------------------*/\n\ntd.linenos { background-color: #f0f0f0; padding-right: 10px; }\nspan.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n/*\n\ngithub.com style (c) Vasily Polovnyov <vast@whiteants.net>\n\n*/\n\npre code {\n  display: block; padding: 0.5em;\n  color: #000;\n  background: #f8f8ff\n}\n\npre .hljs-comment,\npre .hljs-template_comment,\npre .hljs-diff .hljs-header,\npre .hljs-javadoc {\n  color: #408080;\n  font-style: italic\n}\n\npre .hljs-keyword,\npre .hljs-assignment,\npre .hljs-literal,\npre .hljs-css .hljs-rule .hljs-keyword,\npre .hljs-winutils,\npre .hljs-javascript .hljs-title,\npre .hljs-lisp .hljs-title,\npre .hljs-subst {\n  color: #954121;\n  /*font-weight: bold*/\n}\n\npre .hljs-number,\npre .hljs-hexcolor {\n  color: #40a070\n}\n\npre .hljs-string,\npre .hljs-tag .hljs-value,\npre .hljs-phpdoc,\npre .hljs-tex .hljs-formula {\n  color: #219161;\n}\n\npre .hljs-title,\npre .hljs-id {\n  color: #19469D;\n}\npre .hljs-params {\n  color: #00F;\n}\n\npre .hljs-javascript .hljs-title,\npre .hljs-lisp .hljs-title,\npre .hljs-subst {\n  font-weight: normal\n}\n\npre .hljs-class .hljs-title,\npre .hljs-haskell .hljs-label,\npre .hljs-tex .hljs-command {\n  color: #458;\n  font-weight: bold\n}\n\npre .hljs-tag,\npre .hljs-tag .hljs-title,\npre .hljs-rules .hljs-property,\npre .hljs-django .hljs-tag .hljs-keyword {\n  color: #000080;\n  font-weight: normal\n}\n\npre .hljs-attribute,\npre .hljs-variable,\npre .hljs-instancevar,\npre .hljs-lisp .hljs-body {\n  color: #008080\n}\n\npre .hljs-regexp {\n  color: #B68\n}\n\npre .hljs-class {\n  color: #458;\n  font-weight: bold\n}\n\npre .hljs-symbol,\npre .hljs-ruby .hljs-symbol .hljs-string,\npre .hljs-ruby .hljs-symbol .hljs-keyword,\npre .hljs-ruby .hljs-symbol .hljs-keymethods,\npre .hljs-lisp .hljs-keyword,\npre .hljs-tex .hljs-special,\npre .hljs-input_number {\n  color: #990073\n}\n\npre .hljs-builtin,\npre .hljs-constructor,\npre .hljs-built_in,\npre .hljs-lisp .hljs-title {\n  color: #0086b3\n}\n\npre .hljs-preprocessor,\npre .hljs-pi,\npre .hljs-doctype,\npre .hljs-shebang,\npre .hljs-cdata {\n  color: #999;\n  font-weight: bold\n}\n\npre .hljs-deletion {\n  background: #fdd\n}\n\npre .hljs-addition {\n  background: #dfd\n}\n\npre .hljs-diff .hljs-change {\n  background: #0086b3\n}\n\npre .hljs-chunk {\n  color: #aaa\n}\n\npre .hljs-tex .hljs-formula {\n  opacity: 0.5;\n}\n"
  },
  {
    "path": "docs/examples/backbone.localStorage.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head>\n  <title>backbone.localStorage.js</title>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;\">\n  <link rel=\"stylesheet\" media=\"all\" href=\"../docco.css\" />\n</head>\n<body>\n  <div id=\"container\">\n    <div id=\"background\"></div>\n    \n      <ul id=\"jump_to\">\n        <li>\n          <a class=\"large\" href=\"javascript:void(0);\">Jump To &hellip;</a>\n          <a class=\"small\" href=\"javascript:void(0);\">+</a>\n          <div id=\"jump_wrapper\">\n          <div id=\"jump_page_wrapper\">\n            <div id=\"jump_page\">\n              \n                \n                <a class=\"source\" href=\"backbone.localStorage.html\">\n                  examples/backbone.localStorage.js\n                </a>\n              \n                \n                <a class=\"source\" href=\"todos/todos.html\">\n                  examples/todos/todos.js\n                </a>\n              \n            </div>\n          </div>\n        </li>\n      </ul>\n    \n    <ul class=\"sections\">\n        \n          <li id=\"title\">\n              <div class=\"annotation\">\n                  <h1>backbone.localStorage.js</h1>\n              </div>\n          </li>\n        \n        \n        \n        <li id=\"section-1\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-1\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"hljs-comment\">/**\n * Backbone localStorage Adapter\n * Version 1.1.0\n *\n * https://github.com/jeromegn/Backbone.localStorage\n */</span>\n(<span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\">root, factory</span>) {\n   <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-keyword\">typeof</span> define === <span class=\"hljs-string\">&quot;function&quot;</span> &amp;&amp; define.<span class=\"hljs-property\">amd</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-2\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-2\">&#x00a7;</a>\n              </div>\n              <p>AMD. Register as an anonymous module.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-title function_\">define</span>([<span class=\"hljs-string\">&quot;underscore&quot;</span>,<span class=\"hljs-string\">&quot;backbone&quot;</span>], <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">_, Backbone</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-3\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-3\">&#x00a7;</a>\n              </div>\n              <p>Use global variables if the locals are undefined.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title function_\">factory</span>(_ || root.<span class=\"hljs-property\">_</span>, <span class=\"hljs-title class_\">Backbone</span> || root.<span class=\"hljs-property\">Backbone</span>);\n      });\n   } <span class=\"hljs-keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-4\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-4\">&#x00a7;</a>\n              </div>\n              <p>RequireJS isn’t being used. Assume underscore and backbone are loaded in script tags</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>      <span class=\"hljs-title function_\">factory</span>(_, <span class=\"hljs-title class_\">Backbone</span>);\n   }\n}(<span class=\"hljs-variable language_\">this</span>, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">_, Backbone</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-5\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-5\">&#x00a7;</a>\n              </div>\n              <p>A simple module to replace <code>Backbone.sync</code> with <em>localStorage</em>-based\npersistence. Models are given GUIDS, and saved into a JSON object. Simple\nas that.</p>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-6\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-6\">&#x00a7;</a>\n              </div>\n              <p>Hold reference to Underscore.js and Backbone.js in the closure in order\nto make things work even if they are removed from the global namespace</p>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-7\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-7\">&#x00a7;</a>\n              </div>\n              <p>Generate four random hex digits.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"hljs-keyword\">function</span> <span class=\"hljs-title function_\">S4</span>(<span class=\"hljs-params\"></span>) {\n   <span class=\"hljs-keyword\">return</span> (((<span class=\"hljs-number\">1</span>+<span class=\"hljs-title class_\">Math</span>.<span class=\"hljs-title function_\">random</span>())*<span class=\"hljs-number\">0x10000</span>)|<span class=\"hljs-number\">0</span>).<span class=\"hljs-title function_\">toString</span>(<span class=\"hljs-number\">16</span>).<span class=\"hljs-title function_\">substring</span>(<span class=\"hljs-number\">1</span>);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-8\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-8\">&#x00a7;</a>\n              </div>\n              <p>Generate a pseudo-GUID by concatenating random hexadecimal.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"hljs-keyword\">function</span> <span class=\"hljs-title function_\">guid</span>(<span class=\"hljs-params\"></span>) {\n   <span class=\"hljs-keyword\">return</span> (<span class=\"hljs-title function_\">S4</span>()+<span class=\"hljs-title function_\">S4</span>()+<span class=\"hljs-string\">&quot;-&quot;</span>+<span class=\"hljs-title function_\">S4</span>()+<span class=\"hljs-string\">&quot;-&quot;</span>+<span class=\"hljs-title function_\">S4</span>()+<span class=\"hljs-string\">&quot;-&quot;</span>+<span class=\"hljs-title function_\">S4</span>()+<span class=\"hljs-string\">&quot;-&quot;</span>+<span class=\"hljs-title function_\">S4</span>()+<span class=\"hljs-title function_\">S4</span>()+<span class=\"hljs-title function_\">S4</span>());\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-9\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-9\">&#x00a7;</a>\n              </div>\n              <p>Our Store is represented by a single JS object in <em>localStorage</em>. Create it\nwith a meaningful name, like the name you’d give a table.\nwindow.Store is deprecated, use Backbone.LocalStorage instead</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">LocalStorage</span> = <span class=\"hljs-variable language_\">window</span>.<span class=\"hljs-property\">Store</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">name</span>) {\n  <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">name</span> = name;\n  <span class=\"hljs-keyword\">var</span> store = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">localStorage</span>().<span class=\"hljs-title function_\">getItem</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">name</span>);\n  <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">records</span> = (store &amp;&amp; store.<span class=\"hljs-title function_\">split</span>(<span class=\"hljs-string\">&quot;,&quot;</span>)) || [];\n};\n\n_.<span class=\"hljs-title function_\">extend</span>(<span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">LocalStorage</span>.<span class=\"hljs-property\"><span class=\"hljs-keyword\">prototype</span></span>, {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-10\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-10\">&#x00a7;</a>\n              </div>\n              <p>Save the current state of the <strong>Store</strong> to <em>localStorage</em>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-attr\">save</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">localStorage</span>().<span class=\"hljs-title function_\">setItem</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">name</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">records</span>.<span class=\"hljs-title function_\">join</span>(<span class=\"hljs-string\">&quot;,&quot;</span>));\n  },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-11\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-11\">&#x00a7;</a>\n              </div>\n              <p>Add a model, giving it a (hopefully)-unique GUID, if it doesn’t already\nhave an id of it’s own.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-attr\">create</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model</span>) {\n    <span class=\"hljs-keyword\">if</span> (!model.<span class=\"hljs-property\">id</span>) {\n      model.<span class=\"hljs-property\">id</span> = <span class=\"hljs-title function_\">guid</span>();\n      model.<span class=\"hljs-title function_\">set</span>(model.<span class=\"hljs-property\">idAttribute</span>, model.<span class=\"hljs-property\">id</span>);\n    }\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">localStorage</span>().<span class=\"hljs-title function_\">setItem</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">name</span>+<span class=\"hljs-string\">&quot;-&quot;</span>+model.<span class=\"hljs-property\">id</span>, <span class=\"hljs-title class_\">JSON</span>.<span class=\"hljs-title function_\">stringify</span>(model));\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">records</span>.<span class=\"hljs-title function_\">push</span>(model.<span class=\"hljs-property\">id</span>.<span class=\"hljs-title function_\">toString</span>());\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">save</span>();\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">find</span>(model);\n  },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-12\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-12\">&#x00a7;</a>\n              </div>\n              <p>Update a model by replacing its copy in <code>this.data</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-attr\">update</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model</span>) {\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">localStorage</span>().<span class=\"hljs-title function_\">setItem</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">name</span>+<span class=\"hljs-string\">&quot;-&quot;</span>+model.<span class=\"hljs-property\">id</span>, <span class=\"hljs-title class_\">JSON</span>.<span class=\"hljs-title function_\">stringify</span>(model));\n    <span class=\"hljs-keyword\">if</span> (!_.<span class=\"hljs-title function_\">include</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">records</span>, model.<span class=\"hljs-property\">id</span>.<span class=\"hljs-title function_\">toString</span>()))\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">records</span>.<span class=\"hljs-title function_\">push</span>(model.<span class=\"hljs-property\">id</span>.<span class=\"hljs-title function_\">toString</span>()); <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">save</span>();\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">find</span>(model);\n  },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-13\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-13\">&#x00a7;</a>\n              </div>\n              <p>Retrieve a model from <code>this.data</code> by id.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-attr\">find</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model</span>) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">jsonData</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">localStorage</span>().<span class=\"hljs-title function_\">getItem</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">name</span>+<span class=\"hljs-string\">&quot;-&quot;</span>+model.<span class=\"hljs-property\">id</span>));\n  },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-14\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-14\">&#x00a7;</a>\n              </div>\n              <p>Return the array of all models currently in storage.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-attr\">findAll</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title function_\">_</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">records</span>).<span class=\"hljs-title function_\">chain</span>()\n      .<span class=\"hljs-title function_\">map</span>(<span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">id</span>){\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">jsonData</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">localStorage</span>().<span class=\"hljs-title function_\">getItem</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">name</span>+<span class=\"hljs-string\">&quot;-&quot;</span>+id));\n      }, <span class=\"hljs-variable language_\">this</span>)\n      .<span class=\"hljs-title function_\">compact</span>()\n      .<span class=\"hljs-title function_\">value</span>();\n  },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-15\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-15\">&#x00a7;</a>\n              </div>\n              <p>Delete a model from <code>this.data</code>, returning it.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-attr\">destroy</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model</span>) {\n    <span class=\"hljs-keyword\">if</span> (model.<span class=\"hljs-title function_\">isNew</span>())\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">localStorage</span>().<span class=\"hljs-title function_\">removeItem</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">name</span>+<span class=\"hljs-string\">&quot;-&quot;</span>+model.<span class=\"hljs-property\">id</span>);\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">records</span> = _.<span class=\"hljs-title function_\">reject</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">records</span>, <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">id</span>){\n      <span class=\"hljs-keyword\">return</span> id === model.<span class=\"hljs-property\">id</span>.<span class=\"hljs-title function_\">toString</span>();\n    });\n    <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">save</span>();\n    <span class=\"hljs-keyword\">return</span> model;\n  },\n\n  <span class=\"hljs-attr\">localStorage</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">localStorage</span>;\n  },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-16\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-16\">&#x00a7;</a>\n              </div>\n              <p>fix for “illegal access” error on Android when JSON.parse is passed null</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-attr\">jsonData</span>: <span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\">data</span>) {\n      <span class=\"hljs-keyword\">return</span> data &amp;&amp; <span class=\"hljs-title class_\">JSON</span>.<span class=\"hljs-title function_\">parse</span>(data);\n  }\n\n});</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-17\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-17\">&#x00a7;</a>\n              </div>\n              <p>localSync delegate to the model or collection’s\n<em>localStorage</em> property, which should be an instance of <code>Store</code>.\nwindow.Store.sync and Backbone.localSync is deprecated, use Backbone.LocalStorage.sync instead</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">LocalStorage</span>.<span class=\"hljs-property\">sync</span> = <span class=\"hljs-variable language_\">window</span>.<span class=\"hljs-property\">Store</span>.<span class=\"hljs-property\">sync</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">localSync</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">method, model, options</span>) {\n  <span class=\"hljs-keyword\">var</span> store = model.<span class=\"hljs-property\">localStorage</span> || model.<span class=\"hljs-property\">collection</span>.<span class=\"hljs-property\">localStorage</span>;\n\n  <span class=\"hljs-keyword\">var</span> resp, errorMessage, syncDfd = $.<span class=\"hljs-title class_\">Deferred</span> &amp;&amp; $.<span class=\"hljs-title class_\">Deferred</span>(); <span class=\"hljs-comment\">//If $ is having Deferred - use it.</span>\n\n  <span class=\"hljs-keyword\">try</span> {\n\n    <span class=\"hljs-keyword\">switch</span> (method) {\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-string\">&quot;read&quot;</span>:\n        resp = model.<span class=\"hljs-property\">id</span> != <span class=\"hljs-literal\">undefined</span> ? store.<span class=\"hljs-title function_\">find</span>(model) : store.<span class=\"hljs-title function_\">findAll</span>();\n        <span class=\"hljs-keyword\">break</span>;\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-string\">&quot;create&quot;</span>:\n        resp = store.<span class=\"hljs-title function_\">create</span>(model);\n        <span class=\"hljs-keyword\">break</span>;\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-string\">&quot;update&quot;</span>:\n        resp = store.<span class=\"hljs-title function_\">update</span>(model);\n        <span class=\"hljs-keyword\">break</span>;\n      <span class=\"hljs-keyword\">case</span> <span class=\"hljs-string\">&quot;delete&quot;</span>:\n        resp = store.<span class=\"hljs-title function_\">destroy</span>(model);\n        <span class=\"hljs-keyword\">break</span>;\n    }\n\n  } <span class=\"hljs-keyword\">catch</span>(error) {\n    <span class=\"hljs-keyword\">if</span> (error.<span class=\"hljs-property\">code</span> === <span class=\"hljs-title class_\">DOMException</span>.<span class=\"hljs-property\">QUOTA_EXCEEDED_ERR</span> &amp;&amp; <span class=\"hljs-variable language_\">window</span>.<span class=\"hljs-property\">localStorage</span>.<span class=\"hljs-property\">length</span> === <span class=\"hljs-number\">0</span>)\n      errorMessage = <span class=\"hljs-string\">&quot;Private browsing is unsupported&quot;</span>;\n    <span class=\"hljs-keyword\">else</span>\n      errorMessage = error.<span class=\"hljs-property\">message</span>;\n  }\n\n  <span class=\"hljs-keyword\">if</span> (resp) {\n    model.<span class=\"hljs-title function_\">trigger</span>(<span class=\"hljs-string\">&quot;sync&quot;</span>, model, resp, options);\n    <span class=\"hljs-keyword\">if</span> (options &amp;&amp; options.<span class=\"hljs-property\">success</span>)\n      options.<span class=\"hljs-title function_\">success</span>(resp);\n    <span class=\"hljs-keyword\">if</span> (syncDfd)\n      syncDfd.<span class=\"hljs-title function_\">resolve</span>(resp);\n\n  } <span class=\"hljs-keyword\">else</span> {\n    errorMessage = errorMessage ? errorMessage\n                                : <span class=\"hljs-string\">&quot;Record Not Found&quot;</span>;\n\n    <span class=\"hljs-keyword\">if</span> (options &amp;&amp; options.<span class=\"hljs-property\">error</span>)\n      options.<span class=\"hljs-title function_\">error</span>(errorMessage);\n    <span class=\"hljs-keyword\">if</span> (syncDfd)\n      syncDfd.<span class=\"hljs-title function_\">reject</span>(errorMessage);\n  }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-18\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-18\">&#x00a7;</a>\n              </div>\n              <p>add compatibility with $.ajax\nalways execute callback for success and error</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">if</span> (options &amp;&amp; options.<span class=\"hljs-property\">complete</span>) options.<span class=\"hljs-title function_\">complete</span>(resp);\n\n  <span class=\"hljs-keyword\">return</span> syncDfd &amp;&amp; syncDfd.<span class=\"hljs-title function_\">promise</span>();\n};\n\n<span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">ajaxSync</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">sync</span>;\n\n<span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">getSyncMethod</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">model</span>) {\n  <span class=\"hljs-keyword\">if</span>(model.<span class=\"hljs-property\">localStorage</span> || (model.<span class=\"hljs-property\">collection</span> &amp;&amp; model.<span class=\"hljs-property\">collection</span>.<span class=\"hljs-property\">localStorage</span>)) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">localSync</span>;\n  }\n\n  <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">ajaxSync</span>;\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-19\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-19\">&#x00a7;</a>\n              </div>\n              <p>Override ‘Backbone.sync’ to default to localSync,\nthe original ‘Backbone.sync’ is still available in ‘Backbone.ajaxSync’</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">sync</span> = <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">method, model, options</span>) {\n  <span class=\"hljs-keyword\">return</span> <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-title function_\">getSyncMethod</span>(model).<span class=\"hljs-title function_\">apply</span>(<span class=\"hljs-variable language_\">this</span>, [method, model, options]);\n};\n\n<span class=\"hljs-keyword\">return</span> <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">LocalStorage</span>;\n}));</pre></div></div>\n            \n        </li>\n        \n    </ul>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "docs/examples/todos/todos.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head>\n  <title>todos.js</title>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;\">\n  <link rel=\"stylesheet\" media=\"all\" href=\"../../docco.css\" />\n</head>\n<body>\n  <div id=\"container\">\n    <div id=\"background\"></div>\n    \n      <ul id=\"jump_to\">\n        <li>\n          <a class=\"large\" href=\"javascript:void(0);\">Jump To &hellip;</a>\n          <a class=\"small\" href=\"javascript:void(0);\">+</a>\n          <div id=\"jump_wrapper\">\n          <div id=\"jump_page_wrapper\">\n            <div id=\"jump_page\">\n              \n                \n                <a class=\"source\" href=\"../backbone.localStorage.html\">\n                  examples/backbone.localStorage.js\n                </a>\n              \n                \n                <a class=\"source\" href=\"todos.html\">\n                  examples/todos/todos.js\n                </a>\n              \n            </div>\n          </div>\n        </li>\n      </ul>\n    \n    <ul class=\"sections\">\n        \n          <li id=\"title\">\n              <div class=\"annotation\">\n                  <h1>todos.js</h1>\n              </div>\n          </li>\n        \n        \n        \n        <li id=\"section-1\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-1\">&#x00a7;</a>\n              </div>\n              <p>An example Backbone application contributed by\n<a href=\"http://jgn.me/\">Jérôme Gravel-Niquet</a>. This demo uses a simple\n<a href=\"backbone.localStorage.html\">LocalStorage adapter</a>\nto persist Backbone models within your browser.</p>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-2\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-2\">&#x00a7;</a>\n              </div>\n              <p>Load the application once the DOM is ready, using <code>jQuery.ready</code>:</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>$(<span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>){</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-3\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-3\">&#x00a7;</a>\n              </div>\n              <h2 id=\"todo-model\">Todo Model</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-4\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-4\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-5\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-5\">&#x00a7;</a>\n              </div>\n              <p>Our basic <strong>Todo</strong> model has <code>title</code>, <code>order</code>, and <code>done</code> attributes.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">Todo</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">Model</span>.<span class=\"hljs-title function_\">extend</span>({</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-6\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-6\">&#x00a7;</a>\n              </div>\n              <p>Default attributes for the todo item.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">defaults</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> {\n        <span class=\"hljs-attr\">title</span>: <span class=\"hljs-string\">&quot;empty todo...&quot;</span>,\n        <span class=\"hljs-attr\">order</span>: <span class=\"hljs-title class_\">Todos</span>.<span class=\"hljs-title function_\">nextOrder</span>(),\n        <span class=\"hljs-attr\">done</span>: <span class=\"hljs-literal\">false</span>\n      };\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-7\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-7\">&#x00a7;</a>\n              </div>\n              <p>Toggle the <code>done</code> state of this todo item.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">toggle</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">save</span>({<span class=\"hljs-attr\">done</span>: !<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">get</span>(<span class=\"hljs-string\">&quot;done&quot;</span>)});\n    }\n\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-8\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-8\">&#x00a7;</a>\n              </div>\n              <h2 id=\"todo-collection\">Todo Collection</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-9\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-9\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-10\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-10\">&#x00a7;</a>\n              </div>\n              <p>The collection of todos is backed by <em>localStorage</em> instead of a remote\nserver.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">TodoList</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">Collection</span>.<span class=\"hljs-title function_\">extend</span>({</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-11\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-11\">&#x00a7;</a>\n              </div>\n              <p>Reference to this collection’s model.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">model</span>: <span class=\"hljs-title class_\">Todo</span>,</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-12\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-12\">&#x00a7;</a>\n              </div>\n              <p>Save all of the todo items under the <code>&quot;todos-backbone&quot;</code> namespace.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">localStorage</span>: <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-title class_\">LocalStorage</span>(<span class=\"hljs-string\">&quot;todos-backbone&quot;</span>),</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-13\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-13\">&#x00a7;</a>\n              </div>\n              <p>Filter down the list of all todo items that are finished.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">done</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">where</span>({<span class=\"hljs-attr\">done</span>: <span class=\"hljs-literal\">true</span>});\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-14\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-14\">&#x00a7;</a>\n              </div>\n              <p>Filter down the list to only todo items that are still not finished.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">remaining</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">where</span>({<span class=\"hljs-attr\">done</span>: <span class=\"hljs-literal\">false</span>});\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-15\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-15\">&#x00a7;</a>\n              </div>\n              <p>We keep the Todos in sequential order, despite being saved by unordered\nGUID in the database. This generates the next order number for new items.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">nextOrder</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">length</span>) <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">1</span>;\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">last</span>().<span class=\"hljs-title function_\">get</span>(<span class=\"hljs-string\">&#x27;order&#x27;</span>) + <span class=\"hljs-number\">1</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-16\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-16\">&#x00a7;</a>\n              </div>\n              <p>Todos are sorted by their original insertion order.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">comparator</span>: <span class=\"hljs-string\">&#x27;order&#x27;</span>\n\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-17\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-17\">&#x00a7;</a>\n              </div>\n              <p>Create our global collection of <strong>Todos</strong>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">Todos</span> = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">TodoList</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-18\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-18\">&#x00a7;</a>\n              </div>\n              <h2 id=\"todo-item-view\">Todo Item View</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-19\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-19\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-20\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-20\">&#x00a7;</a>\n              </div>\n              <p>The DOM element for a todo item…</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">TodoView</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">View</span>.<span class=\"hljs-title function_\">extend</span>({</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-21\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-21\">&#x00a7;</a>\n              </div>\n              <p>… is a list tag.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">tagName</span>:  <span class=\"hljs-string\">&quot;li&quot;</span>,</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-22\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-22\">&#x00a7;</a>\n              </div>\n              <p>Cache the template function for a single item.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">template</span>: _.<span class=\"hljs-title function_\">template</span>($(<span class=\"hljs-string\">&#x27;#item-template&#x27;</span>).<span class=\"hljs-title function_\">html</span>()),</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-23\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-23\">&#x00a7;</a>\n              </div>\n              <p>The DOM events specific to an item.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">events</span>: {\n      <span class=\"hljs-string\">&quot;click .toggle&quot;</span>   : <span class=\"hljs-string\">&quot;toggleDone&quot;</span>,\n      <span class=\"hljs-string\">&quot;dblclick .view&quot;</span>  : <span class=\"hljs-string\">&quot;edit&quot;</span>,\n      <span class=\"hljs-string\">&quot;click a.destroy&quot;</span> : <span class=\"hljs-string\">&quot;clear&quot;</span>,\n      <span class=\"hljs-string\">&quot;keypress .edit&quot;</span>  : <span class=\"hljs-string\">&quot;updateOnEnter&quot;</span>,\n      <span class=\"hljs-string\">&quot;blur .edit&quot;</span>      : <span class=\"hljs-string\">&quot;close&quot;</span>\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-24\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-24\">&#x00a7;</a>\n              </div>\n              <p>The TodoView listens for changes to its model, re-rendering. Since there’s\na one-to-one correspondence between a <strong>Todo</strong> and a <strong>TodoView</strong> in this\napp, we set a direct reference on the model for convenience.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">initialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">listenTo</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span>, <span class=\"hljs-string\">&#x27;change&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">render</span>);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">listenTo</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span>, <span class=\"hljs-string\">&#x27;destroy&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">remove</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-25\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-25\">&#x00a7;</a>\n              </div>\n              <p>Re-render the titles of the todo item.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">render</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">html</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">template</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span>.<span class=\"hljs-title function_\">toJSON</span>()));\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">toggleClass</span>(<span class=\"hljs-string\">&#x27;done&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span>.<span class=\"hljs-title function_\">get</span>(<span class=\"hljs-string\">&#x27;done&#x27;</span>));\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">input</span> = <span class=\"hljs-variable language_\">this</span>.$(<span class=\"hljs-string\">&#x27;.edit&#x27;</span>);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-variable language_\">this</span>;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-26\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-26\">&#x00a7;</a>\n              </div>\n              <p>Toggle the <code>&quot;done&quot;</code> state of the model.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">toggleDone</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span>.<span class=\"hljs-title function_\">toggle</span>();\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-27\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-27\">&#x00a7;</a>\n              </div>\n              <p>Switch this view into <code>&quot;editing&quot;</code> mode, displaying the input field.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">edit</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">addClass</span>(<span class=\"hljs-string\">&quot;editing&quot;</span>);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">input</span>.<span class=\"hljs-title function_\">focus</span>();\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-28\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-28\">&#x00a7;</a>\n              </div>\n              <p>Close the <code>&quot;editing&quot;</code> mode, saving changes to the todo.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">close</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">var</span> value = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">input</span>.<span class=\"hljs-title function_\">val</span>();\n      <span class=\"hljs-keyword\">if</span> (!value) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">clear</span>();\n      } <span class=\"hljs-keyword\">else</span> {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span>.<span class=\"hljs-title function_\">save</span>({<span class=\"hljs-attr\">title</span>: value});\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">$el</span>.<span class=\"hljs-title function_\">removeClass</span>(<span class=\"hljs-string\">&quot;editing&quot;</span>);\n      }\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-29\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-29\">&#x00a7;</a>\n              </div>\n              <p>If you hit <code>enter</code>, we’re through editing the item.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">updateOnEnter</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">e</span>) {\n      <span class=\"hljs-keyword\">if</span> (e.<span class=\"hljs-property\">keyCode</span> == <span class=\"hljs-number\">13</span>) <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">close</span>();\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-30\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-30\">&#x00a7;</a>\n              </div>\n              <p>Remove the item, destroy the model.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">clear</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">model</span>.<span class=\"hljs-title function_\">destroy</span>();\n    }\n\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-31\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-31\">&#x00a7;</a>\n              </div>\n              <h2 id=\"the-application\">The Application</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-32\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-32\">&#x00a7;</a>\n              </div>\n              \n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-33\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-33\">&#x00a7;</a>\n              </div>\n              <p>Our overall <strong>AppView</strong> is the top-level piece of UI.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">AppView</span> = <span class=\"hljs-title class_\">Backbone</span>.<span class=\"hljs-property\">View</span>.<span class=\"hljs-title function_\">extend</span>({</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-34\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-34\">&#x00a7;</a>\n              </div>\n              <p>Instead of generating a new element, bind to the existing skeleton of\nthe App already present in the HTML.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">el</span>: $(<span class=\"hljs-string\">&quot;#todoapp&quot;</span>),</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-35\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-35\">&#x00a7;</a>\n              </div>\n              <p>Our template for the line of statistics at the bottom of the app.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">statsTemplate</span>: _.<span class=\"hljs-title function_\">template</span>($(<span class=\"hljs-string\">&#x27;#stats-template&#x27;</span>).<span class=\"hljs-title function_\">html</span>()),</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-36\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-36\">&#x00a7;</a>\n              </div>\n              <p>Delegated events for creating new items, and clearing completed ones.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">events</span>: {\n      <span class=\"hljs-string\">&quot;keypress #new-todo&quot;</span>:  <span class=\"hljs-string\">&quot;createOnEnter&quot;</span>,\n      <span class=\"hljs-string\">&quot;click #clear-completed&quot;</span>: <span class=\"hljs-string\">&quot;clearCompleted&quot;</span>,\n      <span class=\"hljs-string\">&quot;click #toggle-all&quot;</span>: <span class=\"hljs-string\">&quot;toggleAllComplete&quot;</span>\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-37\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-37\">&#x00a7;</a>\n              </div>\n              <p>At initialization we bind to the relevant events on the <code>Todos</code>\ncollection, when items are added or changed. Kick things off by\nloading any preexisting todos that might be saved in <em>localStorage</em>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">initialize</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">input</span> = <span class=\"hljs-variable language_\">this</span>.$(<span class=\"hljs-string\">&quot;#new-todo&quot;</span>);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">allCheckbox</span> = <span class=\"hljs-variable language_\">this</span>.$(<span class=\"hljs-string\">&quot;#toggle-all&quot;</span>)[<span class=\"hljs-number\">0</span>];\n\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">listenTo</span>(<span class=\"hljs-title class_\">Todos</span>, <span class=\"hljs-string\">&#x27;add&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">addOne</span>);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">listenTo</span>(<span class=\"hljs-title class_\">Todos</span>, <span class=\"hljs-string\">&#x27;reset&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">addAll</span>);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">listenTo</span>(<span class=\"hljs-title class_\">Todos</span>, <span class=\"hljs-string\">&#x27;all&#x27;</span>, <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">render</span>);\n\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">footer</span> = <span class=\"hljs-variable language_\">this</span>.$(<span class=\"hljs-string\">&#x27;footer&#x27;</span>);\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">main</span> = $(<span class=\"hljs-string\">&#x27;#main&#x27;</span>);\n\n      <span class=\"hljs-title class_\">Todos</span>.<span class=\"hljs-title function_\">fetch</span>();\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-38\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-38\">&#x00a7;</a>\n              </div>\n              <p>Re-rendering the App just means refreshing the statistics – the rest\nof the app doesn’t change.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">render</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">var</span> done = <span class=\"hljs-title class_\">Todos</span>.<span class=\"hljs-title function_\">done</span>().<span class=\"hljs-property\">length</span>;\n      <span class=\"hljs-keyword\">var</span> remaining = <span class=\"hljs-title class_\">Todos</span>.<span class=\"hljs-title function_\">remaining</span>().<span class=\"hljs-property\">length</span>;\n\n      <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-title class_\">Todos</span>.<span class=\"hljs-property\">length</span>) {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">main</span>.<span class=\"hljs-title function_\">show</span>();\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">footer</span>.<span class=\"hljs-title function_\">show</span>();\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">footer</span>.<span class=\"hljs-title function_\">html</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-title function_\">statsTemplate</span>({<span class=\"hljs-attr\">done</span>: done, <span class=\"hljs-attr\">remaining</span>: remaining}));\n      } <span class=\"hljs-keyword\">else</span> {\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">main</span>.<span class=\"hljs-title function_\">hide</span>();\n        <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">footer</span>.<span class=\"hljs-title function_\">hide</span>();\n      }\n\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">allCheckbox</span>.<span class=\"hljs-property\">checked</span> = !remaining;\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-39\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-39\">&#x00a7;</a>\n              </div>\n              <p>Add a single todo item to the list by creating a view for it, and\nappending its element to the <code>&lt;ul&gt;</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">addOne</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">todo</span>) {\n      <span class=\"hljs-keyword\">var</span> view = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">TodoView</span>({<span class=\"hljs-attr\">model</span>: todo});\n      <span class=\"hljs-variable language_\">this</span>.$(<span class=\"hljs-string\">&quot;#todo-list&quot;</span>).<span class=\"hljs-title function_\">append</span>(view.<span class=\"hljs-title function_\">render</span>().<span class=\"hljs-property\">el</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-40\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-40\">&#x00a7;</a>\n              </div>\n              <p>Add all items in the <strong>Todos</strong> collection at once.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">addAll</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-title class_\">Todos</span>.<span class=\"hljs-title function_\">each</span>(<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">addOne</span>, <span class=\"hljs-variable language_\">this</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-41\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-41\">&#x00a7;</a>\n              </div>\n              <p>If you hit return in the main input field, create new <strong>Todo</strong> model,\npersisting it to <em>localStorage</em>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">createOnEnter</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\">e</span>) {\n      <span class=\"hljs-keyword\">if</span> (e.<span class=\"hljs-property\">keyCode</span> != <span class=\"hljs-number\">13</span>) <span class=\"hljs-keyword\">return</span>;\n      <span class=\"hljs-keyword\">if</span> (!<span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">input</span>.<span class=\"hljs-title function_\">val</span>()) <span class=\"hljs-keyword\">return</span>;\n\n      <span class=\"hljs-title class_\">Todos</span>.<span class=\"hljs-title function_\">create</span>({<span class=\"hljs-attr\">title</span>: <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">input</span>.<span class=\"hljs-title function_\">val</span>()});\n      <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">input</span>.<span class=\"hljs-title function_\">val</span>(<span class=\"hljs-string\">&#x27;&#x27;</span>);\n    },</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-42\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-42\">&#x00a7;</a>\n              </div>\n              <p>Clear all done todo items, destroying their models.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"hljs-attr\">clearCompleted</span>: <span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) {\n      _.<span class=\"hljs-title function_\">invoke</span>(<span class=\"hljs-title class_\">Todos</span>.<span class=\"hljs-title function_\">done</span>(), <span class=\"hljs-string\">&#x27;destroy&#x27;</span>);\n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n    },\n\n    <span class=\"hljs-attr\">toggleAllComplete</span>: <span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) {\n      <span class=\"hljs-keyword\">var</span> done = <span class=\"hljs-variable language_\">this</span>.<span class=\"hljs-property\">allCheckbox</span>.<span class=\"hljs-property\">checked</span>;\n      <span class=\"hljs-title class_\">Todos</span>.<span class=\"hljs-title function_\">each</span>(<span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\">todo</span>) { todo.<span class=\"hljs-title function_\">save</span>({<span class=\"hljs-string\">&#x27;done&#x27;</span>: done}); });\n    }\n\n  });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-43\">\n            <div class=\"annotation\">\n              \n              <div class=\"sswrap \">\n                <a class=\"ss\" href=\"#section-43\">&#x00a7;</a>\n              </div>\n              <p>Finally, we kick things off by creating the <strong>App</strong>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>  <span class=\"hljs-keyword\">var</span> <span class=\"hljs-title class_\">App</span> = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">AppView</span>;\n\n});</pre></div></div>\n            \n        </li>\n        \n    </ul>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "docs/js/jquery.lazyload.js",
    "content": "/*\n * Lazy Load - jQuery plugin for lazy loading images\n *\n * Copyright (c) 2007-2012 Mika Tuupola\n *\n * Licensed under the MIT license:\n *   http://www.opensource.org/licenses/mit-license.php\n *\n * Project home:\n *   http://www.appelsiini.net/projects/lazyload\n *\n * Version:  1.7.2\n *\n */\n(function($, window) {\n\n    $window = $(window);\n\n    $.fn.lazyload = function(options) {\n        var elements = this;\n        var settings = {\n            threshold       : 0,\n            failure_limit   : 0,\n            event           : \"scroll\",\n            effect          : \"show\",\n            container       : window,\n            data_attribute  : \"original\",\n            skip_invisible  : true,\n            appear          : null,\n            load            : null\n        };\n\n        function update() {\n            var counter = 0;\n\n            elements.each(function() {\n                var $this = $(this);\n                if (settings.skip_invisible && !$this.is(\":visible\")) {\n                    return;\n                }\n                if ($.abovethetop(this, settings) ||\n                    $.leftofbegin(this, settings)) {\n                        /* Nothing. */\n                } else if (!$.belowthefold(this, settings) &&\n                    !$.rightoffold(this, settings)) {\n                        $this.trigger(\"appear\");\n                } else {\n                    if (++counter > settings.failure_limit) {\n                        return false;\n                    }\n                }\n            });\n\n        }\n\n        if(options) {\n            /* Maintain BC for a couple of versions. */\n            if (undefined !== options.failurelimit) {\n                options.failure_limit = options.failurelimit;\n                delete options.failurelimit;\n            }\n            if (undefined !== options.effectspeed) {\n                options.effect_speed = options.effectspeed;\n                delete options.effectspeed;\n            }\n\n            $.extend(settings, options);\n        }\n\n        /* Cache container as jQuery as object. */\n        $container = (settings.container === undefined ||\n                      settings.container === window) ? $window : $(settings.container);\n\n        /* Fire one scroll event per scroll. Not one scroll event per image. */\n        if (0 === settings.event.indexOf(\"scroll\")) {\n            $container.bind(settings.event, function(event) {\n                return update();\n            });\n        }\n\n        this.each(function() {\n            var self = this;\n            var $self = $(self);\n\n            self.loaded = false;\n\n            /* When appear is triggered load original image. */\n            $self.one(\"appear\", function() {\n                if (!this.loaded) {\n                    if (settings.appear) {\n                        var elements_left = elements.length;\n                        settings.appear.call(self, elements_left, settings);\n                    }\n                    $(\"<img />\")\n                        .bind(\"load\", function() {\n                            $self\n                                .hide()\n                                .attr(\"src\", $self.data(settings.data_attribute))\n                                [settings.effect](settings.effect_speed);\n                            self.loaded = true;\n\n                            /* Remove image from array so it is not looped next time. */\n                            var temp = $.grep(elements, function(element) {\n                                return !element.loaded;\n                            });\n                            elements = $(temp);\n\n                            if (settings.load) {\n                                var elements_left = elements.length;\n                                settings.load.call(self, elements_left, settings);\n                            }\n                        })\n                        .attr(\"src\", $self.data(settings.data_attribute));\n                }\n            });\n\n            /* When wanted event is triggered load original image */\n            /* by triggering appear.                              */\n            if (0 !== settings.event.indexOf(\"scroll\")) {\n                $self.bind(settings.event, function(event) {\n                    if (!self.loaded) {\n                        $self.trigger(\"appear\");\n                    }\n                });\n            }\n        });\n\n        /* Check if something appears when window is resized. */\n        $window.bind(\"resize\", function(event) {\n            update();\n        });\n\n        /* Force initial check if images should appear. */\n        update();\n\n        return this;\n    };\n\n    /* Convenience methods in jQuery namespace.           */\n    /* Use as  $.belowthefold(element, {threshold : 100, container : window}) */\n\n    $.belowthefold = function(element, settings) {\n        var fold;\n\n        if (settings.container === undefined || settings.container === window) {\n            fold = $window.height() + $window.scrollTop();\n        } else {\n            fold = $container.offset().top + $container.height();\n        }\n\n        return fold <= $(element).offset().top - settings.threshold;\n    };\n\n    $.rightoffold = function(element, settings) {\n        var fold;\n\n        if (settings.container === undefined || settings.container === window) {\n            fold = $window.width() + $window.scrollLeft();\n        } else {\n            fold = $container.offset().left + $container.width();\n        }\n\n        return fold <= $(element).offset().left - settings.threshold;\n    };\n\n    $.abovethetop = function(element, settings) {\n        var fold;\n\n        if (settings.container === undefined || settings.container === window) {\n            fold = $window.scrollTop();\n        } else {\n            fold = $container.offset().top;\n        }\n\n        return fold >= $(element).offset().top + settings.threshold  + $(element).height();\n    };\n\n    $.leftofbegin = function(element, settings) {\n        var fold;\n\n        if (settings.container === undefined || settings.container === window) {\n            fold = $window.scrollLeft();\n        } else {\n            fold = $container.offset().left;\n        }\n\n        return fold >= $(element).offset().left + settings.threshold + $(element).width();\n    };\n\n    $.inviewport = function(element, settings) {\n         return !$.rightofscreen(element, settings) && !$.leftofscreen(element, settings) &&\n                !$.belowthefold(element, settings) && !$.abovethetop(element, settings);\n     };\n\n    /* Custom selectors for your convenience.   */\n    /* Use as $(\"img:below-the-fold\").something() */\n\n    $.extend($.expr[':'], {\n        \"below-the-fold\" : function(a) { return $.belowthefold(a, {threshold : 0, container: window}); },\n        \"above-the-top\"  : function(a) { return !$.belowthefold(a, {threshold : 0, container: window}); },\n        \"right-of-screen\": function(a) { return $.rightoffold(a, {threshold : 0, container: window}); },\n        \"left-of-screen\" : function(a) { return !$.rightoffold(a, {threshold : 0, container: window}); },\n        \"in-viewport\"    : function(a) { return !$.inviewport(a, {threshold : 0, container: window}); },\n        /* Maintain BC for couple of versions. */\n        \"above-the-fold\" : function(a) { return !$.belowthefold(a, {threshold : 0, container: window}); },\n        \"right-of-fold\"  : function(a) { return $.rightoffold(a, {threshold : 0, container: window}); },\n        \"left-of-fold\"   : function(a) { return !$.rightoffold(a, {threshold : 0, container: window}); }\n    });\n\n})(jQuery, window);\n"
  },
  {
    "path": "docs/public/stylesheets/normalize.css",
    "content": "/*! normalize.css v2.0.1 | MIT License | git.io/normalize */\n\n/* ==========================================================================\n   HTML5 display definitions\n   ========================================================================== */\n\n/*\n * Corrects `block` display not defined in IE 8/9.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nnav,\nsection,\nsummary {\n    display: block;\n}\n\n/*\n * Corrects `inline-block` display not defined in IE 8/9.\n */\n\naudio,\ncanvas,\nvideo {\n    display: inline-block;\n}\n\n/*\n * Prevents modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n    display: none;\n    height: 0;\n}\n\n/*\n * Addresses styling for `hidden` attribute not present in IE 8/9.\n */\n\n[hidden] {\n    display: none;\n}\n\n/* ==========================================================================\n   Base\n   ========================================================================== */\n\n/*\n * 1. Sets default font family to sans-serif.\n * 2. Prevents iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n    font-family: sans-serif; /* 1 */\n    -webkit-text-size-adjust: 100%; /* 2 */\n    -ms-text-size-adjust: 100%; /* 2 */\n}\n\n/*\n * Removes default margin.\n */\n\nbody {\n    margin: 0;\n}\n\n/* ==========================================================================\n   Links\n   ========================================================================== */\n\n/*\n * Addresses `outline` inconsistency between Chrome and other browsers.\n */\n\na:focus {\n    outline: thin dotted;\n}\n\n/*\n * Improves readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n    outline: 0;\n}\n\n/* ==========================================================================\n   Typography\n   ========================================================================== */\n\n/*\n * Addresses `h1` font sizes within `section` and `article` in Firefox 4+,\n * Safari 5, and Chrome.\n */\n\nh1 {\n    font-size: 2em;\n}\n\n/*\n * Addresses styling not present in IE 8/9, Safari 5, and Chrome.\n */\n\nabbr[title] {\n    border-bottom: 1px dotted;\n}\n\n/*\n * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.\n */\n\nb,\nstrong {\n    font-weight: bold;\n}\n\n/*\n * Addresses styling not present in Safari 5 and Chrome.\n */\n\ndfn {\n    font-style: italic;\n}\n\n/*\n * Addresses styling not present in IE 8/9.\n */\n\nmark {\n    background: #ff0;\n    color: #000;\n}\n\n\n/*\n * Corrects font family set oddly in Safari 5 and Chrome.\n */\n\ncode,\nkbd,\npre,\nsamp {\n    font-family: monospace, serif;\n    font-size: 1em;\n}\n\n/*\n * Improves readability of pre-formatted text in all browsers.\n */\n\npre {\n    white-space: pre;\n    white-space: pre-wrap;\n    word-wrap: break-word;\n}\n\n/*\n * Sets consistent quote types.\n */\n\nq {\n    quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\";\n}\n\n/*\n * Addresses inconsistent and variable font size in all browsers.\n */\n\nsmall {\n    font-size: 80%;\n}\n\n/*\n * Prevents `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n    font-size: 75%;\n    line-height: 0;\n    position: relative;\n    vertical-align: baseline;\n}\n\nsup {\n    top: -0.5em;\n}\n\nsub {\n    bottom: -0.25em;\n}\n\n/* ==========================================================================\n   Embedded content\n   ========================================================================== */\n\n/*\n * Removes border when inside `a` element in IE 8/9.\n */\n\nimg {\n    border: 0;\n}\n\n/*\n * Corrects overflow displayed oddly in IE 9.\n */\n\nsvg:not(:root) {\n    overflow: hidden;\n}\n\n/* ==========================================================================\n   Figures\n   ========================================================================== */\n\n/*\n * Addresses margin not present in IE 8/9 and Safari 5.\n */\n\nfigure {\n    margin: 0;\n}\n\n/* ==========================================================================\n   Forms\n   ========================================================================== */\n\n/*\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n    border: 1px solid #c0c0c0;\n    margin: 0 2px;\n    padding: 0.35em 0.625em 0.75em;\n}\n\n/*\n * 1. Corrects color not being inherited in IE 8/9.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n    border: 0; /* 1 */\n    padding: 0; /* 2 */\n}\n\n/*\n * 1. Corrects font family not being inherited in all browsers.\n * 2. Corrects font size not being inherited in all browsers.\n * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome\n */\n\nbutton,\ninput,\nselect,\ntextarea {\n    font-family: inherit; /* 1 */\n    font-size: 100%; /* 2 */\n    margin: 0; /* 3 */\n}\n\n/*\n * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\nbutton,\ninput {\n    line-height: normal;\n}\n\n/*\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Corrects inability to style clickable `input` types in iOS.\n * 3. Improves usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n    -webkit-appearance: button; /* 2 */\n    cursor: pointer; /* 3 */\n}\n\n/*\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\ninput[disabled] {\n    cursor: default;\n}\n\n/*\n * 1. Addresses box sizing set to `content-box` in IE 8/9.\n * 2. Removes excess padding in IE 8/9.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n    box-sizing: border-box; /* 1 */\n    padding: 0; /* 2 */\n}\n\n/*\n * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.\n * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n    -webkit-appearance: textfield; /* 1 */\n    -moz-box-sizing: content-box;\n    -webkit-box-sizing: content-box; /* 2 */\n    box-sizing: content-box;\n}\n\n/*\n * Removes inner padding and search cancel button in Safari 5 and Chrome\n * on OS X.\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n    -webkit-appearance: none;\n}\n\n/*\n * Removes inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n    border: 0;\n    padding: 0;\n}\n\n/*\n * 1. Removes default vertical scrollbar in IE 8/9.\n * 2. Improves readability and alignment in all browsers.\n */\n\ntextarea {\n    overflow: auto; /* 1 */\n    vertical-align: top; /* 2 */\n}\n\n/* ==========================================================================\n   Tables\n   ========================================================================== */\n\n/*\n * Remove most spacing between table cells.\n */\n\ntable {\n    border-collapse: collapse;\n    border-spacing: 0;\n}"
  },
  {
    "path": "docs/search.js",
    "content": "(function() {\n  var functions = document.querySelectorAll('[data-name]');\n  var sections = document.querySelectorAll('.searchable_section');\n  var searchInput = document.getElementById('function_filter');\n\n  function strIn(a, b) {\n    a = a.toLowerCase();\n    b = b.toLowerCase();\n    return b.indexOf(a) >= 0;\n  }\n\n  function doesMatch(element) {\n    var name = element.getAttribute('data-name');\n    var aliases = element.getAttribute('data-aliases') || '';\n    return strIn(searchInput.value, name) || strIn(searchInput.value, aliases);\n  }\n\n  function filterElement(element) {\n    element.style.display = doesMatch(element) ? '' : 'none';\n  }\n\n  function filterToc() {\n    _.each(functions, filterElement);\n\n    var emptySearch = searchInput.value === '';\n\n    // Hide the titles of empty sections\n    _.each(sections, function(section) {\n      var sectionFunctions = section.querySelectorAll('[data-name]');\n      var showSection = emptySearch || _.some(sectionFunctions, doesMatch);\n      section.style.display = showSection ? '' : 'none';\n    });\n  }\n\n  function gotoFirst() {\n    var firstFunction = _.find(functions, doesMatch);\n    if(firstFunction) {\n      window.location.hash = firstFunction.lastChild.getAttribute('href');\n      searchInput.focus();\n    }\n  }\n\n  searchInput.addEventListener('input', filterToc, false);\n\n  // Press \"Enter\" to jump to the first matching function\n  searchInput.addEventListener('keypress', function(e) {\n    if (e.which === 13) {\n      gotoFirst();\n    }\n  });\n\n  // Press \"/\" to search\n  document.body.addEventListener('keyup', function(event) {\n    if (191 === event.which) {\n      searchInput.focus();\n    }\n  });\n}());\n"
  },
  {
    "path": "docs/todos.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head></head>\n<body>\n  <p>This annotated source has moved to <a href=\"examples/todos/todos.html\">examples/todos/todos.html</a>. You will be automatically redirected in two seconds.</p>\n  <script>\n    setTimeout(function() {\n      location = 'examples/todos/todos.html';\n    }, 2000);\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/backbone.localStorage.js",
    "content": "/**\n * Backbone localStorage Adapter\n * Version 1.1.0\n *\n * https://github.com/jeromegn/Backbone.localStorage\n */\n(function (root, factory) {\n   if (typeof define === \"function\" && define.amd) {\n      // AMD. Register as an anonymous module.\n      define([\"underscore\",\"backbone\"], function(_, Backbone) {\n        // Use global variables if the locals are undefined.\n        return factory(_ || root._, Backbone || root.Backbone);\n      });\n   } else {\n      // RequireJS isn't being used. Assume underscore and backbone are loaded in script tags\n      factory(_, Backbone);\n   }\n}(this, function(_, Backbone) {\n// A simple module to replace `Backbone.sync` with *localStorage*-based\n// persistence. Models are given GUIDS, and saved into a JSON object. Simple\n// as that.\n\n// Hold reference to Underscore.js and Backbone.js in the closure in order\n// to make things work even if they are removed from the global namespace\n\n// Generate four random hex digits.\nfunction S4() {\n   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);\n};\n\n// Generate a pseudo-GUID by concatenating random hexadecimal.\nfunction guid() {\n   return (S4()+S4()+\"-\"+S4()+\"-\"+S4()+\"-\"+S4()+\"-\"+S4()+S4()+S4());\n};\n\n// Our Store is represented by a single JS object in *localStorage*. Create it\n// with a meaningful name, like the name you'd give a table.\n// window.Store is deprecated, use Backbone.LocalStorage instead\nBackbone.LocalStorage = window.Store = function(name) {\n  this.name = name;\n  var store = this.localStorage().getItem(this.name);\n  this.records = (store && store.split(\",\")) || [];\n};\n\n_.extend(Backbone.LocalStorage.prototype, {\n\n  // Save the current state of the **Store** to *localStorage*.\n  save: function() {\n    this.localStorage().setItem(this.name, this.records.join(\",\"));\n  },\n\n  // Add a model, giving it a (hopefully)-unique GUID, if it doesn't already\n  // have an id of it's own.\n  create: function(model) {\n    if (!model.id) {\n      model.id = guid();\n      model.set(model.idAttribute, model.id);\n    }\n    this.localStorage().setItem(this.name+\"-\"+model.id, JSON.stringify(model));\n    this.records.push(model.id.toString());\n    this.save();\n    return this.find(model);\n  },\n\n  // Update a model by replacing its copy in `this.data`.\n  update: function(model) {\n    this.localStorage().setItem(this.name+\"-\"+model.id, JSON.stringify(model));\n    if (!_.include(this.records, model.id.toString()))\n      this.records.push(model.id.toString()); this.save();\n    return this.find(model);\n  },\n\n  // Retrieve a model from `this.data` by id.\n  find: function(model) {\n    return this.jsonData(this.localStorage().getItem(this.name+\"-\"+model.id));\n  },\n\n  // Return the array of all models currently in storage.\n  findAll: function() {\n    return _(this.records).chain()\n      .map(function(id){\n        return this.jsonData(this.localStorage().getItem(this.name+\"-\"+id));\n      }, this)\n      .compact()\n      .value();\n  },\n\n  // Delete a model from `this.data`, returning it.\n  destroy: function(model) {\n    if (model.isNew())\n      return false\n    this.localStorage().removeItem(this.name+\"-\"+model.id);\n    this.records = _.reject(this.records, function(id){\n      return id === model.id.toString();\n    });\n    this.save();\n    return model;\n  },\n\n  localStorage: function() {\n    return localStorage;\n  },\n\n  // fix for \"illegal access\" error on Android when JSON.parse is passed null\n  jsonData: function (data) {\n      return data && JSON.parse(data);\n  }\n\n});\n\n// localSync delegate to the model or collection's\n// *localStorage* property, which should be an instance of `Store`.\n// window.Store.sync and Backbone.localSync is deprecated, use Backbone.LocalStorage.sync instead\nBackbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {\n  var store = model.localStorage || model.collection.localStorage;\n\n  var resp, errorMessage, syncDfd = $.Deferred && $.Deferred(); //If $ is having Deferred - use it.\n\n  try {\n\n    switch (method) {\n      case \"read\":\n        resp = model.id != undefined ? store.find(model) : store.findAll();\n        break;\n      case \"create\":\n        resp = store.create(model);\n        break;\n      case \"update\":\n        resp = store.update(model);\n        break;\n      case \"delete\":\n        resp = store.destroy(model);\n        break;\n    }\n\n  } catch(error) {\n    if (error.code === DOMException.QUOTA_EXCEEDED_ERR && window.localStorage.length === 0)\n      errorMessage = \"Private browsing is unsupported\";\n    else\n      errorMessage = error.message;\n  }\n\n  if (resp) {\n    model.trigger(\"sync\", model, resp, options);\n    if (options && options.success)\n      options.success(resp);\n    if (syncDfd)\n      syncDfd.resolve(resp);\n\n  } else {\n    errorMessage = errorMessage ? errorMessage\n                                : \"Record Not Found\";\n\n    if (options && options.error)\n      options.error(errorMessage);\n    if (syncDfd)\n      syncDfd.reject(errorMessage);\n  }\n\n  // add compatibility with $.ajax\n  // always execute callback for success and error\n  if (options && options.complete) options.complete(resp);\n\n  return syncDfd && syncDfd.promise();\n};\n\nBackbone.ajaxSync = Backbone.sync;\n\nBackbone.getSyncMethod = function(model) {\n  if(model.localStorage || (model.collection && model.collection.localStorage)) {\n    return Backbone.localSync;\n  }\n\n  return Backbone.ajaxSync;\n};\n\n// Override 'Backbone.sync' to default to localSync,\n// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'\nBackbone.sync = function(method, model, options) {\n  return Backbone.getSyncMethod(model).apply(this, [method, model, options]);\n};\n\nreturn Backbone.LocalStorage;\n}));\n"
  },
  {
    "path": "examples/todos/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"utf-8\">\n  <title>Backbone.js Todos</title>\n  <link rel=\"stylesheet\" href=\"todos.css\"/>\n</head>\n\n<body>\n\n  <div id=\"todoapp\">\n\n    <header>\n      <h1>Todos</h1>\n      <input id=\"new-todo\" type=\"text\" placeholder=\"What needs to be done?\">\n    </header>\n\n    <section id=\"main\">\n      <input id=\"toggle-all\" type=\"checkbox\">\n      <label for=\"toggle-all\">Mark all as complete</label>\n      <ul id=\"todo-list\"></ul>\n    </section>\n\n    <footer>\n      <a id=\"clear-completed\">Clear completed</a>\n      <div id=\"todo-count\"></div>\n    </footer>\n\n  </div>\n\n  <div id=\"instructions\">\n    Double-click to edit a todo.\n  </div>\n\n  <div id=\"credits\">\n    Created by\n    <br />\n    <a href=\"http://jgn.me/\">J&eacute;r&ocirc;me Gravel-Niquet</a>.\n    <br />Rewritten by: <a href=\"https://github.com/tastejs/todomvc\">TodoMVC</a>.\n  </div>\n\n  <script src=\"../../test/vendor/json2.js\"></script>\n  <script src=\"../../test/vendor/jquery.js\"></script>\n  <script src=\"../../test/vendor/underscore.js\"></script>\n  <script src=\"../../backbone.js\"></script>\n  <script src=\"../backbone.localStorage.js\"></script>\n  <script src=\"todos.js\"></script>\n\n  <!-- Templates -->\n\n  <script type=\"text/template\" id=\"item-template\">\n    <div class=\"view\">\n      <input class=\"toggle\" type=\"checkbox\" <%= done ? 'checked=\"checked\"' : '' %> />\n      <label><%- title %></label>\n      <a class=\"destroy\"></a>\n    </div>\n    <input class=\"edit\" type=\"text\" value=\"<%- title %>\" />\n  </script>\n\n  <script type=\"text/template\" id=\"stats-template\">\n    <% if (done) { %>\n      <a id=\"clear-completed\">Clear <%= done %> completed <%= done == 1 ? 'item' : 'items' %></a>\n    <% } %>\n    <div class=\"todo-count\"><b><%= remaining %></b> <%= remaining == 1 ? 'item' : 'items' %> left</div>\n  </script>\n\n  </body>\n</html>\n"
  },
  {
    "path": "examples/todos/todos.css",
    "content": "html,\nbody {\n\tmargin: 0;\n\tpadding: 0;\n}\n\nbody {\n\tfont: 14px \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n\tline-height: 1.4em;\n\tbackground: #eeeeee;\n\tcolor: #333333;\n\twidth: 520px;\n\tmargin: 0 auto;\n\t-webkit-font-smoothing: antialiased;\n}\n\n#todoapp {\n\tbackground: #fff;\n\tpadding: 20px;\n\tmargin-bottom: 40px;\n\t-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;\n\t-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;\n\t-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;\n\t-o-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;\n\tbox-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;\n\t-webkit-border-radius: 0 0 5px 5px;\n\t-moz-border-radius: 0 0 5px 5px;\n\t-ms-border-radius: 0 0 5px 5px;\n\t-o-border-radius: 0 0 5px 5px;\n\tborder-radius: 0 0 5px 5px;\n}\n\n#todoapp h1 {\n\tfont-size: 36px;\n\tfont-weight: bold;\n\ttext-align: center;\n\tpadding: 0 0 10px 0;\n}\n\n#todoapp input[type=\"text\"] {\n\twidth: 466px;\n\tfont-size: 24px;\n\tfont-family: inherit;\n\tline-height: 1.4em;\n\tborder: 0;\n\toutline: none;\n\tpadding: 6px;\n\tborder: 1px solid #999999;\n\t-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;\n\t-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;\n\t-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;\n\t-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;\n\tbox-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;\n}\n\n#todoapp input::-webkit-input-placeholder {\n\tfont-style: italic;\n}\n\n#main {\n\tdisplay: none;\n}\n\n#todo-list {\n\tmargin: 10px 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n#todo-list li {\n\tpadding: 18px 20px 18px 0;\n\tposition: relative;\n\tfont-size: 24px;\n\tborder-bottom: 1px solid #cccccc;\n}\n\n#todo-list li:last-child {\n\tborder-bottom: none;\n}\n\n#todo-list li.done label {\n\tcolor: #777777;\n\ttext-decoration: line-through;\n}\n\n#todo-list .destroy {\n\tposition: absolute;\n\tright: 5px;\n\ttop: 20px;\n\tdisplay: none;\n\tcursor: pointer;\n\twidth: 20px;\n\theight: 20px;\n\tbackground: url(destroy.png) no-repeat;\n}\n\n#todo-list li:hover .destroy {\n  \tdisplay: block;\n}\n\n#todo-list .destroy:hover {\n  \tbackground-position: 0 -20px;\n}\n\n#todo-list li.editing {\n\tborder-bottom: none;\n\tmargin-top: -1px;\n\tpadding: 0;\n}\n\n#todo-list li.editing:last-child {\n\tmargin-bottom: -1px;\n}\n\n#todo-list li.editing .edit {\n\tdisplay: block;\n\twidth: 444px;\n\tpadding: 13px 15px 14px 20px;\n\tmargin: 0;\n}\n\n#todo-list li.editing .view {\n\tdisplay: none;\n}\n\n#todo-list li .view label {\n\tword-break: break-word;\n}\n\n#todo-list li .edit {\n\tdisplay: none;\n}\n\n#todoapp footer {\n\tdisplay: none;\n\tmargin: 0 -20px -20px -20px;\n\toverflow: hidden;\n\tcolor: #555555;\n\tbackground: #f4fce8;\n\tborder-top: 1px solid #ededed;\n\tpadding: 0 20px;\n\tline-height: 37px;\n\t-webkit-border-radius: 0 0 5px 5px;\n\t-moz-border-radius: 0 0 5px 5px;\n\t-ms-border-radius: 0 0 5px 5px;\n\t-o-border-radius: 0 0 5px 5px;\n\tborder-radius: 0 0 5px 5px;\n}\n\n#clear-completed {\n\tfloat: right;\n\tline-height: 20px;\n\ttext-decoration: none;\n\tbackground: rgba(0, 0, 0, 0.1);\n\tcolor: #555555;\n\tfont-size: 11px;\n\tmargin-top: 8px;\n\tmargin-bottom: 8px;\n\tpadding: 0 10px 1px;\n\tcursor: pointer;\n\t-webkit-border-radius: 12px;\n\t-moz-border-radius: 12px;\n\t-ms-border-radius: 12px;\n\t-o-border-radius: 12px;\n\tborder-radius: 12px;\n\t-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;\n\t-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;\n\t-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;\n\t-o-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;\n\tbox-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;\n}\n\n#clear-completed:hover {\n\tbackground: rgba(0, 0, 0, 0.15);\n\t-webkit-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;\n\t-moz-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;\n\t-ms-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;\n\t-o-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;\n\tbox-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;\n}\n\n#clear-completed:active {\n\tposition: relative;\n\ttop: 1px;\n}\n\n#todo-count span {\n\tfont-weight: bold;\n}\n\n#instructions {\n\tmargin: 10px auto;\n\tcolor: #777777;\n\ttext-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;\n\ttext-align: center;\n}\n\n#instructions a {\n\tcolor: #336699;\n}\n\n#credits {\n\tmargin: 30px auto;\n\tcolor: #999;\n\ttext-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;\n\ttext-align: center;\n}\n\n#credits a {\n\tcolor: #888;\n}\n"
  },
  {
    "path": "examples/todos/todos.js",
    "content": "// An example Backbone application contributed by\n// [Jérôme Gravel-Niquet](http://jgn.me/). This demo uses a simple\n// [LocalStorage adapter](backbone.localStorage.html)\n// to persist Backbone models within your browser.\n\n// Load the application once the DOM is ready, using `jQuery.ready`:\n$(function(){\n\n  // Todo Model\n  // ----------\n\n  // Our basic **Todo** model has `title`, `order`, and `done` attributes.\n  var Todo = Backbone.Model.extend({\n\n    // Default attributes for the todo item.\n    defaults: function() {\n      return {\n        title: \"empty todo...\",\n        order: Todos.nextOrder(),\n        done: false\n      };\n    },\n\n    // Toggle the `done` state of this todo item.\n    toggle: function() {\n      this.save({done: !this.get(\"done\")});\n    }\n\n  });\n\n  // Todo Collection\n  // ---------------\n\n  // The collection of todos is backed by *localStorage* instead of a remote\n  // server.\n  var TodoList = Backbone.Collection.extend({\n\n    // Reference to this collection's model.\n    model: Todo,\n\n    // Save all of the todo items under the `\"todos-backbone\"` namespace.\n    localStorage: new Backbone.LocalStorage(\"todos-backbone\"),\n\n    // Filter down the list of all todo items that are finished.\n    done: function() {\n      return this.where({done: true});\n    },\n\n    // Filter down the list to only todo items that are still not finished.\n    remaining: function() {\n      return this.where({done: false});\n    },\n\n    // We keep the Todos in sequential order, despite being saved by unordered\n    // GUID in the database. This generates the next order number for new items.\n    nextOrder: function() {\n      if (!this.length) return 1;\n      return this.last().get('order') + 1;\n    },\n\n    // Todos are sorted by their original insertion order.\n    comparator: 'order'\n\n  });\n\n  // Create our global collection of **Todos**.\n  var Todos = new TodoList;\n\n  // Todo Item View\n  // --------------\n\n  // The DOM element for a todo item...\n  var TodoView = Backbone.View.extend({\n\n    //... is a list tag.\n    tagName:  \"li\",\n\n    // Cache the template function for a single item.\n    template: _.template($('#item-template').html()),\n\n    // The DOM events specific to an item.\n    events: {\n      \"click .toggle\"   : \"toggleDone\",\n      \"dblclick .view\"  : \"edit\",\n      \"click a.destroy\" : \"clear\",\n      \"keypress .edit\"  : \"updateOnEnter\",\n      \"blur .edit\"      : \"close\"\n    },\n\n    // The TodoView listens for changes to its model, re-rendering. Since there's\n    // a one-to-one correspondence between a **Todo** and a **TodoView** in this\n    // app, we set a direct reference on the model for convenience.\n    initialize: function() {\n      this.listenTo(this.model, 'change', this.render);\n      this.listenTo(this.model, 'destroy', this.remove);\n    },\n\n    // Re-render the titles of the todo item.\n    render: function() {\n      this.$el.html(this.template(this.model.toJSON()));\n      this.$el.toggleClass('done', this.model.get('done'));\n      this.input = this.$('.edit');\n      return this;\n    },\n\n    // Toggle the `\"done\"` state of the model.\n    toggleDone: function() {\n      this.model.toggle();\n    },\n\n    // Switch this view into `\"editing\"` mode, displaying the input field.\n    edit: function() {\n      this.$el.addClass(\"editing\");\n      this.input.focus();\n    },\n\n    // Close the `\"editing\"` mode, saving changes to the todo.\n    close: function() {\n      var value = this.input.val();\n      if (!value) {\n        this.clear();\n      } else {\n        this.model.save({title: value});\n        this.$el.removeClass(\"editing\");\n      }\n    },\n\n    // If you hit `enter`, we're through editing the item.\n    updateOnEnter: function(e) {\n      if (e.keyCode == 13) this.close();\n    },\n\n    // Remove the item, destroy the model.\n    clear: function() {\n      this.model.destroy();\n    }\n\n  });\n\n  // The Application\n  // ---------------\n\n  // Our overall **AppView** is the top-level piece of UI.\n  var AppView = Backbone.View.extend({\n\n    // Instead of generating a new element, bind to the existing skeleton of\n    // the App already present in the HTML.\n    el: $(\"#todoapp\"),\n\n    // Our template for the line of statistics at the bottom of the app.\n    statsTemplate: _.template($('#stats-template').html()),\n\n    // Delegated events for creating new items, and clearing completed ones.\n    events: {\n      \"keypress #new-todo\":  \"createOnEnter\",\n      \"click #clear-completed\": \"clearCompleted\",\n      \"click #toggle-all\": \"toggleAllComplete\"\n    },\n\n    // At initialization we bind to the relevant events on the `Todos`\n    // collection, when items are added or changed. Kick things off by\n    // loading any preexisting todos that might be saved in *localStorage*.\n    initialize: function() {\n\n      this.input = this.$(\"#new-todo\");\n      this.allCheckbox = this.$(\"#toggle-all\")[0];\n\n      this.listenTo(Todos, 'add', this.addOne);\n      this.listenTo(Todos, 'reset', this.addAll);\n      this.listenTo(Todos, 'all', this.render);\n\n      this.footer = this.$('footer');\n      this.main = $('#main');\n\n      Todos.fetch();\n    },\n\n    // Re-rendering the App just means refreshing the statistics -- the rest\n    // of the app doesn't change.\n    render: function() {\n      var done = Todos.done().length;\n      var remaining = Todos.remaining().length;\n\n      if (Todos.length) {\n        this.main.show();\n        this.footer.show();\n        this.footer.html(this.statsTemplate({done: done, remaining: remaining}));\n      } else {\n        this.main.hide();\n        this.footer.hide();\n      }\n\n      this.allCheckbox.checked = !remaining;\n    },\n\n    // Add a single todo item to the list by creating a view for it, and\n    // appending its element to the `<ul>`.\n    addOne: function(todo) {\n      var view = new TodoView({model: todo});\n      this.$(\"#todo-list\").append(view.render().el);\n    },\n\n    // Add all items in the **Todos** collection at once.\n    addAll: function() {\n      Todos.each(this.addOne, this);\n    },\n\n    // If you hit return in the main input field, create new **Todo** model,\n    // persisting it to *localStorage*.\n    createOnEnter: function(e) {\n      if (e.keyCode != 13) return;\n      if (!this.input.val()) return;\n\n      Todos.create({title: this.input.val()});\n      this.input.val('');\n    },\n\n    // Clear all done todo items, destroying their models.\n    clearCompleted: function() {\n      _.invoke(Todos.done(), 'destroy');\n      return false;\n    },\n\n    toggleAllComplete: function () {\n      var done = this.allCheckbox.checked;\n      Todos.each(function (todo) { todo.save({'done': done}); });\n    }\n\n  });\n\n  // Finally, we kick things off by creating the **App**.\n  var App = new AppView;\n\n});\n"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n  <meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\" />\n  <meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />\n  <meta name=\"viewport\" content=\"width=device-width\">\n  <link rel=\"canonical\" href=\"http://backbonejs.org\" />\n  <title>Backbone.js</title>\n  <style>\n    body {\n      font-size: 14px;\n      line-height: 22px;\n      font-family: Helvetica Neue, Helvetica, Arial;\n      background: #f4f4f4 url(docs/images/background.png);\n    }\n    .interface {\n      font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, sans-serif !important;\n    }\n    div#sidebar {\n      background: #fff;\n      position: fixed;\n      z-index: 10;\n      top: 0; left: 0; bottom: 0;\n      width: 200px;\n      overflow-y: auto;\n      overflow-x: hidden;\n      -webkit-overflow-scrolling: touch;\n      padding: 15px 0 30px 30px;\n      border-right: 1px solid #bbb;\n      box-shadow: 0 0 20px #ccc; -webkit-box-shadow: 0 0 20px #ccc; -moz-box-shadow: 0 0 20px #ccc;\n    }\n      a.toc_title, a.toc_title:visited {\n        display: block;\n        color: black;\n        font-weight: bold;\n        margin-top: 15px;\n      }\n        a.toc_title:hover {\n          text-decoration: underline;\n        }\n        #sidebar .version {\n          font-size: 10px;\n          font-weight: normal;\n        }\n      ul.toc_section {\n        font-size: 11px;\n        line-height: 14px;\n        margin: 5px 0 0 0;\n        padding-left: 0px;\n        list-style-type: none;\n        font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, sans-serif;\n      }\n        .toc_section li {\n          cursor: pointer;\n          margin: 0 0 3px 0;\n        }\n          .toc_section li a {\n            text-decoration: none;\n            color: black;\n          }\n            .toc_section li a:hover {\n              text-decoration: underline;\n            }\n      input#function_filter {\n        width: 80%;\n      }\n    div.container {\n      position: relative;\n      width: 550px;\n      margin: 40px 0 50px 260px;\n    }\n    img#logo {\n      width: 450px;\n      height: 80px;\n    }\n    div.run {\n      position: absolute;\n      right: 15px;\n      width: 26px; height: 18px;\n      background: url('docs/images/arrows.png') no-repeat -26px 0;\n    }\n      div.run:active {\n        background-position: -51px 0;\n      }\n    p, div.container ul {\n      margin: 25px 0;\n      width: 550px;\n    }\n      p.warning {\n        font-size: 12px;\n        line-height: 18px;\n        font-style: italic;\n      }\n      div.container ul {\n        list-style: circle;\n        padding-left: 15px;\n        font-size: 13px;\n        line-height: 18px;\n      }\n        div.container ul li {\n          margin-bottom: 10px;\n        }\n        div.container ul.small {\n          font-size: 12px;\n        }\n    a, a:visited {\n      color: #444;\n    }\n    a:active, a:hover {\n      color: #000;\n    }\n    a.punch {\n      display: inline-block;\n      background: #4162a8;\n      border-top: 1px solid #38538c;\n      border-right: 1px solid #1f2d4d;\n      border-bottom: 1px solid #151e33;\n      border-left: 1px solid #1f2d4d;\n      -webkit-border-radius: 4px;\n      -moz-border-radius: 4px;\n      -ms-border-radius: 4px;\n      -o-border-radius: 4px;\n      border-radius: 4px;\n      -webkit-box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n      -moz-box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n      -ms-box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n      -o-box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n      box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n      color: #fff;\n      font: bold 14px \"helvetica neue\", helvetica, arial, sans-serif;\n      line-height: 1;\n      margin-bottom: 15px;\n      padding: 8px 0 10px 0;\n      text-align: center;\n      text-shadow: 0px -1px 1px #1e2d4d;\n      text-decoration: none;\n      width: 225px;\n      -webkit-background-clip: padding-box; }\n      a.punch:hover {\n        -webkit-box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n        -moz-box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n        -ms-box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n        -o-box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n        box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111;\n        cursor: pointer; }\n      a.punch:active {\n        -webkit-box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111;\n        -moz-box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111;\n        -ms-box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111;\n        -o-box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111;\n        box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111;\n        margin-top: 5px; margin-bottom: 10px; }\n    a img {\n      border: 0;\n    }\n    h1, h2, h3, h4, h5, h6 {\n      padding-top: 20px;\n    }\n      h2 {\n        font-size: 22px;\n      }\n    b.header {\n      font-size: 18px;\n      line-height: 35px;\n    }\n    span.alias {\n      font-size: 14px;\n      font-style: italic;\n      margin-left: 20px;\n    }\n    table {\n      margin: 15px 0 0; padding: 0;\n    }\n      tr, td {\n        margin: 0; padding: 0;\n      }\n        td {\n          padding: 0px 15px 5px 0;\n        }\n        table .rule {\n          height: 1px;\n          background: #ccc;\n          margin: 5px 0;\n        }\n    code, pre, tt {\n      font-family: Monaco, Consolas, \"Lucida Console\", monospace;\n      font-size: 12px;\n      line-height: 18px;\n      font-style: normal;\n    }\n      tt {\n        padding: 0px 3px;\n        background: #fff;\n        border: 1px solid #ddd;\n        zoom: 1;\n      }\n      code {\n        margin-left: 20px;\n      }\n      pre {\n        font-size: 12px;\n        padding: 2px 0 2px 15px;\n        border: 4px solid #bbb; border-top: 0; border-bottom: 0;\n        margin: 0px 0 25px;\n      }\n      img.example_image {\n        margin: 0px auto;\n      }\n        img.example_retina {\n          margin: 20px;\n          box-shadow: 0 8px 15px rgba(0,0,0,0.4);\n        }\n    @media only screen and (-webkit-max-device-pixel-ratio: 1) and (max-width: 600px),\n           only screen and (max--moz-device-pixel-ratio: 1) and (max-width: 600px) {\n      div#sidebar {\n        display: none;\n      }\n      img#logo {\n        max-width: 450px;\n        width: 100%;\n        height: auto;\n      }\n      div.container {\n        width: auto;\n        margin-left: 15px;\n        margin-right: 15px;\n      }\n        p, div.container ul {\n          width: auto;\n        }\n    }\n    @media only screen and (-webkit-min-device-pixel-ratio: 1.5) and (max-width: 640px),\n          only screen and (-o-min-device-pixel-ratio: 3/2) and (max-width: 640px),\n          only screen and (min-device-pixel-ratio: 1.5) and (max-width: 640px) {\n      img {\n        max-width: 100%;\n        height: auto;\n      }\n      div#sidebar {\n        -webkit-overflow-scrolling: initial;\n        position: relative;\n        width: 90%;\n        height: 120px;\n        left: 0;\n        top: -7px;\n        padding: 10px 0 10px 30px;\n        border: 0;\n      }\n      img#logo {\n        width: auto;\n        height: auto;\n      }\n      div.container {\n        margin: 0;\n        width: 100%;\n      }\n      p, div.container ul {\n        max-width: 98%;\n        overflow-x: scroll;\n      }\n      table {\n        position: relative;\n      }\n        tr:first-child td {\n          padding-bottom: 25px;\n        }\n        td.text {\n          line-height: 12px;\n          padding: 0;\n          position: absolute;\n          left: 0;\n          top: 48px;\n        }\n        tr:last-child td.text {\n          top: 122px;\n        }\n      pre {\n        overflow: scroll;\n      }\n    }\n    img.figure {\n      width: 100%;\n    }\n    div.columns {\n      display: table;\n      table-layout: fixed;\n      width: 100%;\n    }\n      div.columns ul {\n        margin: 10px 0;\n      }\n    div.col-50 {\n      display: table-cell;\n      width: 50%;\n    }\n  </style>\n</head>\n<body>\n\n  <div id=\"sidebar\" class=\"interface\">\n\n    <a class=\"toc_title\" href=\"#\">\n      Backbone.js <span class=\"version\">(1.6.1)</span>\n    </a>\n    <ul class=\"toc_section\">\n      <li>&raquo; <a href=\"http://github.com/jashkenas/backbone\">GitHub Repository</a></li>\n      <li>&raquo; <a href=\"docs/backbone.html\">Annotated Source</a></li>\n    </ul>\n\n    <input id=\"function_filter\" placeholder=\"Filter\" type=\"text\" autofocus />\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#Getting-started\">\n        Getting Started\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"Introduction\">- <a href=\"#Getting-started\">Introduction</a></li>\n        <li data-name=\"Models and Views\">– <a href=\"#Model-View-separation\">Models and Views</a></li>\n        <li data-name=\"Collections\">– <a href=\"#Model-Collections\">Collections</a></li>\n        <li data-name=\"API Integration\">– <a href=\"#API-integration\">API Integration</a></li>\n        <li data-name=\"Rendering\">– <a href=\"#View-rendering\">Rendering</a></li>\n        <li data-name=\"Routing\">– <a href=\"#Routing\">Routing</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#Events\">\n        Events\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"on\">– <a href=\"#Events-on\">on</a></li>\n        <li data-name=\"off\">– <a href=\"#Events-off\">off</a></li>\n        <li data-name=\"trigger\">– <a href=\"#Events-trigger\">trigger</a></li>\n        <li data-name=\"once\">– <a href=\"#Events-once\">once</a></li>\n        <li data-name=\"listenTo\">– <a href=\"#Events-listenTo\">listenTo</a></li>\n        <li data-name=\"stopListening\">– <a href=\"#Events-stopListening\">stopListening</a></li>\n        <li data-name=\"listenToOnce\">– <a href=\"#Events-listenToOnce\">listenToOnce</a></li>\n        <li data-name=\"Catalog of Built-in Events\">- <a href=\"#Events-catalog\"><b>Catalog of Built-in Events</b></a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#Model\">\n        Model\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"extend\">– <a href=\"#Model-extend\">extend</a></li>\n        <li data-name=\"preinitialize\">– <a href=\"#Model-preinitialize\">preinitialize</a></li>\n        <li data-name=\"constructor / initialize\">– <a href=\"#Model-constructor\">constructor / initialize</a></li>\n        <li data-name=\"get\">– <a href=\"#Model-get\">get</a></li>\n        <li data-name=\"set\">– <a href=\"#Model-set\">set</a></li>\n        <li data-name=\"escape\">– <a href=\"#Model-escape\">escape</a></li>\n        <li data-name=\"has\">– <a href=\"#Model-has\">has</a></li>\n        <li data-name=\"unset\">– <a href=\"#Model-unset\">unset</a></li>\n        <li data-name=\"clear\">– <a href=\"#Model-clear\">clear</a></li>\n        <li data-name=\"id\">– <a href=\"#Model-id\">id</a></li>\n        <li data-name=\"idAttribute\">– <a href=\"#Model-idAttribute\">idAttribute</a></li>\n        <li data-name=\"cid\">– <a href=\"#Model-cid\">cid</a></li>\n        <li data-name=\"cidPrefix\">– <a href=\"#Model-cidPrefix\">cidPrefix</a></li>\n        <li data-name=\"attributes\">– <a href=\"#Model-attributes\">attributes</a></li>\n        <li data-name=\"changed\">– <a href=\"#Model-changed\">changed</a></li>\n        <li data-name=\"defaults\">– <a href=\"#Model-defaults\">defaults</a></li>\n        <li data-name=\"toJSON\">– <a href=\"#Model-toJSON\">toJSON</a></li>\n        <li data-name=\"sync\">– <a href=\"#Model-sync\">sync</a></li>\n        <li data-name=\"fetch\">– <a href=\"#Model-fetch\">fetch</a></li>\n        <li data-name=\"save\">– <a href=\"#Model-save\">save</a></li>\n        <li data-name=\"destroy\">– <a href=\"#Model-destroy\">destroy</a></li>\n        <li data-name=\"Underscore Methods\">– <a href=\"#Model-Underscore-Methods\"><b>Underscore Methods (9)</b></a></li>\n        <li data-name=\"validate\">– <a href=\"#Model-validate\">validate</a></li>\n        <li data-name=\"validationError\">– <a href=\"#Model-validationError\">validationError</a></li>\n        <li data-name=\"isValid\">– <a href=\"#Model-isValid\">isValid</a></li>\n        <li data-name=\"url\">– <a href=\"#Model-url\">url</a></li>\n        <li data-name=\"urlRoot\">– <a href=\"#Model-urlRoot\">urlRoot</a></li>\n        <li data-name=\"parse\">– <a href=\"#Model-parse\">parse</a></li>\n        <li data-name=\"clone\">– <a href=\"#Model-clone\">clone</a></li>\n        <li data-name=\"isNew\">– <a href=\"#Model-isNew\">isNew</a></li>\n        <li data-name=\"hasChanged\">– <a href=\"#Model-hasChanged\">hasChanged</a></li>\n        <li data-name=\"changedAttributes\">– <a href=\"#Model-changedAttributes\">changedAttributes</a></li>\n        <li data-name=\"previous\">– <a href=\"#Model-previous\">previous</a></li>\n        <li data-name=\"previousAttributes\">– <a href=\"#Model-previousAttributes\">previousAttributes</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#Collection\">\n        Collection\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"extend\">– <a href=\"#Collection-extend\">extend</a></li>\n        <li data-name=\"model\">– <a href=\"#Collection-model\">model</a></li>\n        <li data-name=\"modelId\">– <a href=\"#Collection-modelId\">modelId</a></li>\n        <li data-name=\"preinitialize\" data-name=\"preinitialize\">– <a href=\"#Collection-preinitialize\">preinitialize</a></li>\n        <li data-name=\"constructor / initialize\" data-name=\"constructor / initialize\">– <a href=\"#Collection-constructor\">constructor / initialize</a></li>\n        <li data-name=\"models\">– <a href=\"#Collection-models\">models</a></li>\n        <li data-name=\"toJSON\">– <a href=\"#Collection-toJSON\">toJSON</a></li>\n        <li data-name=\"sync\">– <a href=\"#Collection-sync\">sync</a></li>\n        <li data-name=\"Underscore Methods\">– <a href=\"#Collection-Underscore-Methods\"><b>Underscore Methods (46)</b></a></li>\n        <li data-name=\"add\">– <a href=\"#Collection-add\">add</a></li>\n        <li data-name=\"remove\">– <a href=\"#Collection-remove\">remove</a></li>\n        <li data-name=\"reset\">– <a href=\"#Collection-reset\">reset</a></li>\n        <li data-name=\"set\">– <a href=\"#Collection-set\">set</a></li>\n        <li data-name=\"get\">– <a href=\"#Collection-get\">get</a></li>\n        <li data-name=\"at\">– <a href=\"#Collection-at\">at</a></li>\n        <li data-name=\"push\">– <a href=\"#Collection-push\">push</a></li>\n        <li data-name=\"pop\">– <a href=\"#Collection-pop\">pop</a></li>\n        <li data-name=\"unshift\">– <a href=\"#Collection-unshift\">unshift</a></li>\n        <li data-name=\"shift\">– <a href=\"#Collection-shift\">shift</a></li>\n        <li data-name=\"slice\">– <a href=\"#Collection-slice\">slice</a></li>\n        <li data-name=\"length\">– <a href=\"#Collection-length\">length</a></li>\n        <li data-name=\"comparator\">– <a href=\"#Collection-comparator\">comparator</a></li>\n        <li data-name=\"sort\">– <a href=\"#Collection-sort\">sort</a></li>\n        <li data-name=\"pluck\">– <a href=\"#Collection-pluck\">pluck</a></li>\n        <li data-name=\"where\">– <a href=\"#Collection-where\">where</a></li>\n        <li data-name=\"findWhere\">– <a href=\"#Collection-findWhere\">findWhere</a></li>\n        <li data-name=\"url\">– <a href=\"#Collection-url\">url</a></li>\n        <li data-name=\"parse\">– <a href=\"#Collection-parse\">parse</a></li>\n        <li data-name=\"clone\">– <a href=\"#Collection-clone\">clone</a></li>\n        <li data-name=\"fetch\">– <a href=\"#Collection-fetch\">fetch</a></li>\n        <li data-name=\"create\">– <a href=\"#Collection-create\">create</a></li>\n        <li data-name=\"sync\">– <a href=\"#Collection-mixin\">mixin</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#Router\">\n        Router\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"extend\">– <a href=\"#Router-extend\">extend</a></li>\n        <li data-name=\"routes\">– <a href=\"#Router-routes\">routes</a></li>\n        <li data-name=\"preinitialize\">– <a href=\"#Router-preinitialize\">preinitialize</a></li>\n        <li data-name=\"constructor / initialize\">– <a href=\"#Router-constructor\">constructor / initialize</a></li>\n        <li data-name=\"route\">– <a href=\"#Router-route\">route</a></li>\n        <li data-name=\"navigate\">– <a href=\"#Router-navigate\">navigate</a></li>\n        <li data-name=\"execute\">– <a href=\"#Router-execute\">execute</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#History\">\n        History\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"start\">– <a href=\"#History-start\">start</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#Sync\">\n        Sync\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"Backbone.sync\">– <a href=\"#Sync\">Backbone.sync</a></li>\n        <li data-name=\"Backbone.ajax\">– <a href=\"#Sync-ajax\">Backbone.ajax</a></li>\n        <li data-name=\"Backbone.emulateHTTP\">– <a href=\"#Sync-emulateHTTP\">Backbone.emulateHTTP</a></li>\n        <li data-name=\"Backbone.emulateJSON\">– <a href=\"#Sync-emulateJSON\">Backbone.emulateJSON</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#View\">\n        View\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"extend\">– <a href=\"#View-extend\">extend</a></li>\n        <li data-name=\"preinitialize\">– <a href=\"#View-preinitialize\">preinitialize</a></li>\n        <li data-name=\"constructor / initialize\">– <a href=\"#View-constructor\">constructor / initialize</a></li>\n        <li data-name=\"el\">– <a href=\"#View-el\">el</a></li>\n        <li data-name=\"$el\">– <a href=\"#View-$el\">$el</a></li>\n        <li data-name=\"setElement\">– <a href=\"#View-setElement\">setElement</a></li>\n        <li data-name=\"attributes\">– <a href=\"#View-attributes\">attributes</a></li>\n        <li data-name=\"$ (jQuery)\">– <a href=\"#View-dollar\">$ (jQuery)</a></li>\n        <li data-name=\"template\">– <a href=\"#View-template\">template</a></li>\n        <li data-name=\"render\">– <a href=\"#View-render\">render</a></li>\n        <li data-name=\"remove\">– <a href=\"#View-remove\">remove</a></li>\n        <li data-name=\"events\">– <a href=\"#View-events\">events</a></li>\n        <li data-name=\"delegateEvents\">– <a href=\"#View-delegateEvents\">delegateEvents</a></li>\n        <li data-name=\"undelegateEvents\">– <a href=\"#View-undelegateEvents\">undelegateEvents</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#Utility\">\n        Utility\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"Backbone.noConflict\">– <a href=\"#Utility-Backbone-noConflict\">Backbone.noConflict</a></li>\n        <li data-name=\"Backbone.$\">– <a href=\"#Utility-Backbone-$\">Backbone.$</a></li>\n        <li data-name=\"Backbone.debugInfo\">– <a href=\"#Utility-Backbone-debugInfo\">debugInfo</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#faq\">\n        F.A.Q.\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"Why Backbone?\">– <a href=\"#FAQ-why-backbone\">Why Backbone?</a></li>\n        <li data-name=\"More Than One Way To Do It\">– <a href=\"#FAQ-tim-toady\">More Than One Way To Do It</a></li>\n        <li data-name=\"Nested Models and Collections\">– <a href=\"#FAQ-nested\">Nested Models &amp; Collections</a></li>\n        <li data-name=\"Loading Bootstrapped Models\">– <a href=\"#FAQ-bootstrap\">Loading Bootstrapped Models</a></li>\n        <li data-name=\"Extending Backbone\">– <a href=\"#FAQ-extending\">Extending Backbone</a></li>\n        <li data-name=\"Traditional MVC\">– <a href=\"#FAQ-mvc\">Traditional MVC</a></li>\n        <li data-name=\"Binding this\">– <a href=\"#FAQ-this\">Binding \"this\"</a></li>\n        <li data-name=\"Working with Rails\">– <a href=\"#FAQ-rails\">Working with Rails</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#examples\">\n        Examples\n      </a>\n      <ul class=\"toc_section\">\n        <li data-name=\"Todos\">– <a href=\"#examples-todos\">Todos</a></li>\n        <li data-name=\"DocumentCloud\">– <a href=\"#examples-documentcloud\">DocumentCloud</a></li>\n        <li data-name=\"USA Today\">– <a href=\"#examples-usa-today\">USA Today</a></li>\n        <li data-name=\"Rdio\">– <a href=\"#examples-rdio\">Rdio</a></li>\n        <li data-name=\"Hulu\">– <a href=\"#examples-hulu\">Hulu</a></li>\n        <li data-name=\"Quartz\">– <a href=\"#examples-quartz\">Quartz</a></li>\n        <li data-name=\"Earth\">– <a href=\"#examples-earth\">Earth</a></li>\n        <li data-name=\"Vox\">– <a href=\"#examples-vox\">Vox</a></li>\n        <li data-name=\"Gawker Media\">– <a href=\"#examples-gawker\">Gawker Media</a></li>\n        <li data-name=\"Flow\">– <a href=\"#examples-flow\">Flow</a></li>\n        <li data-name=\"Gilt Groupe\">– <a href=\"#examples-gilt\">Gilt Groupe</a></li>\n        <li data-name=\"Enigma\">– <a href=\"#examples-enigma\">Enigma</a></li>\n        <li data-name=\"NewsBlur\">– <a href=\"#examples-newsblur\">NewsBlur</a></li>\n        <li data-name=\"WordPress.com\">– <a href=\"#examples-wordpress\">WordPress.com</a></li>\n        <li data-name=\"Foursquare\">– <a href=\"#examples-foursquare\">Foursquare</a></li>\n        <li data-name=\"Bitbucket\">– <a href=\"#examples-bitbucket\">Bitbucket</a></li>\n        <li data-name=\"Disqus\">– <a href=\"#examples-disqus\">Disqus</a></li>\n        <li data-name=\"Delicious\">– <a href=\"#examples-delicious\">Delicious</a></li>\n        <li data-name=\"Khan Academy\">– <a href=\"#examples-khan-academy\">Khan Academy</a></li>\n        <li data-name=\"IRCCloud\">– <a href=\"#examples-irccloud\">IRCCloud</a></li>\n        <li data-name=\"Pitchfork\">– <a href=\"#examples-pitchfork\">Pitchfork</a></li>\n        <li data-name=\"Spin\">– <a href=\"#examples-spin\">Spin</a></li>\n        <li data-name=\"ZocDoc\">– <a href=\"#examples-zocdoc\">ZocDoc</a></li>\n        <li data-name=\"Walmart Mobile\">– <a href=\"#examples-walmart\">Walmart Mobile</a></li>\n        <li data-name=\"Groupon Now!\">– <a href=\"#examples-groupon\">Groupon Now!</a></li>\n        <li data-name=\"Basecamp\">– <a href=\"#examples-basecamp\">Basecamp</a></li>\n        <li data-name=\"Slavery Footprint\">– <a href=\"#examples-slavery-footprint\">Slavery Footprint</a></li>\n        <li data-name=\"Stripe\">– <a href=\"#examples-stripe\">Stripe</a></li>\n        <li data-name=\"Airbnb\">– <a href=\"#examples-airbnb\">Airbnb</a></li>\n        <li data-name=\"SoundCloud Mobile\">– <a href=\"#examples-soundcloud\">SoundCloud Mobile</a></li>\n        <li data-name=\"Art.sy\">- <a href=\"#examples-artsy\">Art.sy</a></li>\n        <li data-name=\"Pandora\">– <a href=\"#examples-pandora\">Pandora</a></li>\n        <li data-name=\"Inkling\">– <a href=\"#examples-inkling\">Inkling</a></li>\n        <li data-name=\"Code School\">– <a href=\"#examples-code-school\">Code School</a></li>\n        <li data-name=\"CloudApp\">– <a href=\"#examples-cloudapp\">CloudApp</a></li>\n        <li data-name=\"SeatGeek\">– <a href=\"#examples-seatgeek\">SeatGeek</a></li>\n        <li data-name=\"Easel\">– <a href=\"#examples-easel\">Easel</a></li>\n        <li data-name=\"Jolicloud\">- <a href=\"#examples-jolicloud\">Jolicloud</a></li>\n        <li data-name=\"Salon.io\">– <a href=\"#examples-salon\">Salon.io</a></li>\n        <li data-name=\"TileMill\">– <a href=\"#examples-tilemill\">TileMill</a></li>\n        <li data-name=\"Blossom\">– <a href=\"#examples-blossom\">Blossom</a></li>\n        <li data-name=\"Trello\">– <a href=\"#examples-trello\">Trello</a></li>\n        <li data-name=\"Tzigla\">– <a href=\"#examples-tzigla\">Tzigla</a></li>\n      </ul>\n    </div>\n\n    <div class=\"searchable_section\">\n      <a class=\"toc_title\" href=\"#changelog\">\n        Change Log\n      </a>\n    </div>\n\n  </div>\n\n  <div class=\"container\">\n\n    <p>\n      <img id=\"logo\" src=\"docs/images/backbone.png\" alt=\"Backbone.js\" />\n    </p>\n\n    <p>\n      Backbone.js gives structure to web applications\n      by providing <b>models</b> with key-value binding and custom events,\n      <b>collections</b> with a rich API of enumerable functions,\n      <b>views</b> with declarative event handling, and connects it all to your\n      existing API over a RESTful JSON interface.\n    </p>\n\n    <p>\n      The project is <a href=\"http://github.com/jashkenas/backbone/\">hosted on GitHub</a>,\n      and the <a href=\"docs/backbone.html\">annotated source code</a> is available,\n      as well as an online <a href=\"test/\">test suite</a>,\n      an <a href=\"examples/todos/index.html\">example application</a>,\n      a <a href=\"https://github.com/jashkenas/backbone/wiki/Tutorials%2C-blog-posts-and-example-sites\">list of tutorials</a>\n      and a <a href=\"#examples\">long list of real-world projects</a> that use Backbone.\n      Backbone is available for use under the <a href=\"http://github.com/jashkenas/backbone/blob/master/LICENSE\">MIT software license</a>.\n    </p>\n\n    <p>\n      You can report bugs and discuss features on the\n      <a href=\"http://github.com/jashkenas/backbone/issues\">GitHub issues page</a>,\n      or add pages to the <a href=\"https://github.com/jashkenas/backbone/wiki\">wiki</a>.\n    </p>\n\n    <p>\n      <i>\n        Backbone is an open-source component of\n        <a href=\"http://documentcloud.org/\">DocumentCloud</a>.\n      </i>\n    </p>\n\n    <h2 id=\"downloads\">\n      Downloads &amp; Dependencies\n      <span style=\"padding-left: 7px; font-size:11px; font-weight: normal;\" class=\"interface\">(Right-click, and use \"Save As\")</span>\n    </h2>\n\n    <table>\n      <tr>\n        <td><a class=\"punch\" href=\"backbone.js\">Development Version (1.6.1)</a></td>\n        <td class=\"text\"><i>72kb, Full source, tons of comments</i></td>\n      </tr>\n      <tr>\n        <td><a class=\"punch\" href=\"backbone-min.js\">Production Version (1.6.1)</a></td>\n        <td class=\"text\" style=\"line-height: 16px;\">\n          <i>7.9kb, Packed and gzipped</i><br />\n          <small>(<a href=\"backbone-min.map\">Source Map</a>)</small>\n        </td>\n      </tr>\n      <tr>\n        <td><a class=\"punch\" href=\"https://raw.github.com/jashkenas/backbone/master/backbone.js\">Edge Version (master)</a></td>\n        <td>\n          <i>Unreleased, use at your own risk</i>\n        </td>\n      </tr>\n    </table>\n\n    <p>\n      Backbone's only hard dependency is\n      <a href=\"http://underscorejs.org/\">Underscore.js</a> <small>( >= 1.8.3)</small>.\n      For RESTful persistence and DOM manipulation with <a href=\"#View\">Backbone.View</a>,\n      include <b><a href=\"https://jquery.com/\">jQuery</a></b> ( >= 1.11.0).\n      <i>(Mimics of the Underscore and jQuery APIs, such as\n      <a href=\"https://lodash.com/\">Lodash</a> and\n      <a href=\"http://zeptojs.com/\">Zepto</a>, will\n      also tend to work, with varying degrees of compatibility.)</i>\n    </p>\n    <h2 id=\"Getting-started\">Getting Started</h2>\n\n    <p>\n      When working on a web application that involves a lot of JavaScript, one\n      of the first things you learn is to stop tying your data to the DOM. It's all\n      too easy to create JavaScript applications that end up as tangled piles of\n      jQuery selectors and callbacks, all trying frantically to keep data in\n      sync between the HTML UI, your JavaScript logic, and the database on your\n      server. For rich client-side applications, a more structured approach\n      is often helpful.\n    </p>\n\n    <p>\n      With Backbone, you represent your data as\n      <a href=\"#Model\">Models</a>, which can be created, validated, destroyed,\n      and saved to the server. Whenever a UI action causes an attribute of\n      a model to change, the model triggers a <i>\"change\"</i> event; all\n      the <a href=\"#View\">Views</a> that display the model's state can be notified of the\n      change, so that they are able to respond accordingly, re-rendering themselves with\n      the new information. In a finished Backbone app, you don't have to write the glue\n      code that looks into the DOM to find an element with a specific <i>id</i>,\n      and update the HTML manually\n      &mdash; when the model changes, the views simply update themselves.\n    </p>\n\n    <p>\n      Philosophically, Backbone is an attempt to discover the minimal set\n      of data-structuring (models and collections) and user interface (views\n      and URLs) primitives that are generally useful when building web applications with\n      JavaScript. In an ecosystem where overarching, decides-everything-for-you\n      frameworks are commonplace, and many libraries require your site to be\n      reorganized to suit their look, feel, and default behavior — Backbone should\n      continue to be a tool that gives you the <i>freedom</i> to design the full\n      experience of your web application.\n    </p>\n\n    <p>\n      If you're new here, and aren't yet quite sure what Backbone is for, start by\n      browsing the <a href=\"#examples\">list of Backbone-based projects</a>.\n    </p>\n\n    <p>\n      Many of the code examples in this documentation are runnable, because\n      Backbone is included on this page.\n      Click the <i>play</i> button to execute them.\n    </p>\n\n    <h2 id=\"Model-View-separation\">Models and Views</h2>\n\n    <img class=\"figure\" src=\"docs/images/intro-model-view.svg\" alt=\"Model-View Separation.\">\n\n    <p>\n      The single most important thing that Backbone can help you with is keeping\n      your business logic separate from your user interface. When the two are\n      entangled, change is hard; when logic doesn't depend on UI, your\n      interface becomes easier to work with.\n    </p>\n\n    <div class=\"columns\">\n      <div class=\"col-50\">\n        <b>Model</b>\n        <ul>\n          <li>Orchestrates data and business logic.</li>\n          <li>Loads and saves data from the server.</li>\n          <li>Emits events when data changes.</li>\n        </ul>\n      </div>\n      <div class=\"col-50\">\n        <b>View</b>\n        <ul>\n          <li>Listens for changes and renders UI.</li>\n          <li>Handles user input and interactivity.</li>\n          <li>Sends captured input to the model.</li>\n        </ul>\n      </div>\n    </div>\n\n    <p>\n      A <b>Model</b> manages an internal table of data attributes, and\n      triggers <tt>\"change\"</tt> events when any of its data is modified.\n      Models handle syncing data with a persistence layer — usually a REST API\n      with a backing database. Design your models as the atomic reusable objects\n      containing all of the helpful functions for manipulating their particular\n      bit of data. Models should be able to be passed around throughout your app,\n      and used anywhere that bit of data is needed.\n    </p>\n\n    <p>\n      A <b>View</b> is an atomic chunk of user interface. It often renders the\n      data from a specific model, or number of models &mdash; but views can\n      also be data-less chunks of UI that stand alone.\n      Models should be generally unaware of views. Instead, views listen to\n      the model <tt>\"change\"</tt> events, and react or re-render themselves\n      appropriately.\n    </p>\n\n    <h2 id=\"Model-Collections\">Collections</h2>\n\n    <img class=\"figure\" src=\"docs/images/intro-collections.svg\" alt=\"Model Collections.\">\n\n    <p>\n      A <b>Collection</b> helps you deal with a group of related models, handling\n      the loading and saving of new models to the server and providing helper\n      functions for performing aggregations or computations against a list of models.\n      Aside from their own events, collections also proxy through all of the\n      events that occur to models within them, allowing you to listen in one place\n      for any change that might happen to any model in the collection.\n    </p>\n\n    <h2 id=\"API-integration\">API Integration</h2>\n\n    <p>\n      Backbone is pre-configured to sync with a RESTful API. Simply create a\n      new Collection with the <tt>url</tt> of your resource endpoint:\n    </p>\n\n<pre>\nvar Books = Backbone.Collection.extend({\n  url: '/books'\n});\n</pre>\n\n    <p>\n      The <b>Collection</b> and <b>Model</b> components together form a direct\n      mapping of REST resources using the following methods:\n    </p>\n\n<pre>\nGET  /books/ .... collection.fetch();\nPOST /books/ .... collection.create();\nGET  /books/1 ... model.fetch();\nPUT  /books/1 ... model.save();\nDEL  /books/1 ... model.destroy();\n</pre>\n\n    <p>\n      When fetching raw JSON data from an API, a <b>Collection</b> will\n      automatically populate itself with data formatted as an array, while\n      a <b>Model</b> will automatically populate itself with data formatted\n      as an object:\n    </p>\n\n<pre>\n[{\"id\": 1}] ..... populates a Collection with one model.\n{\"id\": 1} ....... populates a Model with one attribute.\n</pre>\n\n    <p>\n      However, it's fairly common to encounter APIs that return data in a\n      different format than what Backbone expects. For example, consider\n      fetching a <b>Collection</b> from an API that returns the real data\n      array wrapped in metadata:\n    </p>\n\n<pre>\n{\n  \"page\": 1,\n  \"limit\": 10,\n  \"total\": 2,\n  \"books\": [\n    {\"id\": 1, \"title\": \"Pride and Prejudice\"},\n    {\"id\": 4, \"title\": \"The Great Gatsby\"}\n  ]\n}\n</pre>\n\n    <p>\n      In the above example data, a <b>Collection</b> should populate using the\n      <tt>\"books\"</tt> array rather than the root object structure. This\n      difference is easily reconciled using a <tt>parse</tt> method that\n      returns (or transforms) the desired portion of API data:\n    </p>\n\n<pre>\nvar Books = Backbone.Collection.extend({\n  url: '/books',\n  parse: function(data) {\n    return data.books;\n  }\n});\n</pre>\n\n    <h2 id=\"View-rendering\">View Rendering</h2>\n\n    <img class=\"figure\" src=\"docs/images/intro-views.svg\" alt=\"View rendering.\">\n\n    <p>\n      Each <b>View</b> manages the rendering and user interaction within its own\n      DOM element. If you're strict about not allowing views to reach outside\n      of themselves, it helps keep your interface flexible &mdash; allowing\n      views to be rendered in isolation in any place where they might be needed.\n    </p>\n\n    <p>\n      Backbone remains unopinionated about the process used to render <b>View</b>\n      objects and their subviews into UI: you define how your models get translated\n      into HTML (or SVG, or Canvas, or something even more exotic).\n      It could be as prosaic as a simple\n      <a href=\"http://underscorejs.org/#template\">Underscore template</a>, or as fancy as the\n      <a href=\"http://facebook.github.io/react/docs/tutorial.html\">React virtual DOM</a>.\n      Some basic approaches to rendering views can be found\n      in the <a href=\"https://github.com/jashkenas/backbone/wiki/Backbone%2C-The-Primer\">Backbone primer</a>.\n    </p>\n\n    <h2 id=\"Routing\">Routing with URLs</h2>\n\n    <img class=\"figure\" src=\"docs/images/intro-routing.svg\" alt=\"Routing\">\n\n    <p>\n      In rich web applications, we still want to provide linkable,\n      bookmarkable, and shareable URLs to meaningful locations within an app.\n      Use the <b>Router</b> to update the browser URL whenever the user\n      reaches a new \"place\" in your app that they might want to bookmark or share.\n      Conversely, the <b>Router</b> detects changes to the URL &mdash; say,\n      pressing the \"Back\" button &mdash; and can tell your application exactly where you\n      are now.\n    </p>\n\n    <h2 id=\"Events\">Backbone.Events</h2>\n\n    <p>\n      <b>Events</b> is a module that can be mixed in to any object, giving the\n      object the ability to bind and trigger custom named events. Events do not\n      have to be declared before they are bound, and may take passed arguments.\n      For example:\n    </p>\n\n<pre class=\"runnable\">\nvar object = {};\n\n_.extend(object, Backbone.Events);\n\nobject.on(\"alert\", function(msg) {\n  alert(\"Triggered \" + msg);\n});\n\nobject.trigger(\"alert\", \"an event\");\n</pre>\n\n    <p>\n      For example, to make a handy event dispatcher that can coordinate events\n      among different areas of your application: <tt>var dispatcher = _.clone(Backbone.Events)</tt>\n    </p>\n\n    <p id=\"Events-on\">\n      <b class=\"header\">on</b><code>object.on(event, callback, [context])</code><span class=\"alias\">Alias: bind</span>\n      <br />\n      Bind a <b>callback</b> function to an object. The callback will be invoked\n      whenever the <b>event</b> is fired.\n      If you have a large number of different events on a page, the convention is to use colons to\n      namespace them: <tt>\"poll:start\"</tt>, or <tt>\"change:selection\"</tt>.\n      The event string may also be a space-delimited list of several events...\n    </p>\n\n<pre>\nbook.on(\"change:title change:author\", ...);\n</pre>\n\n    <p>\n      Callbacks bound to the special\n      <tt>\"all\"</tt> event will be triggered when any event occurs, and are passed\n      the name of the event as the first argument. For example, to proxy all events\n      from one object to another:\n    </p>\n\n<pre>\nproxy.on(\"all\", function(eventName) {\n  object.trigger(eventName);\n});\n</pre>\n\n    <p>\n      All Backbone event methods also support an event map syntax, as an alternative\n      to positional arguments:\n    </p>\n\n<pre>\nbook.on({\n  \"change:author\": authorPane.update,\n  \"change:title change:subtitle\": titleView.update,\n  \"destroy\": bookView.remove\n});\n</pre>\n\n    <p>\n      To supply a <b>context</b> value for <tt>this</tt> when the callback is invoked,\n      pass the optional last argument: <tt>model.on('change', this.render, this)</tt> or\n      <tt>model.on({change: this.render}, this)</tt>.\n    </p>\n\n    <p id=\"Events-off\">\n      <b class=\"header\">off</b><code>object.off([event], [callback], [context])</code><span class=\"alias\">Alias: unbind</span>\n      <br />\n      Remove a previously-bound <b>callback</b> function from an object. If no\n      <b>context</b> is specified, all of the versions of the callback with\n      different contexts will be removed. If no\n      callback is specified, all callbacks for the <b>event</b> will be\n      removed. If no event is specified, callbacks for <i>all</i> events\n      will be removed.\n    </p>\n\n<pre>\n// Removes just the `onChange` callback.\nobject.off(\"change\", onChange);\n\n// Removes all \"change\" callbacks.\nobject.off(\"change\");\n\n// Removes the `onChange` callback for all events.\nobject.off(null, onChange);\n\n// Removes all callbacks for `context` for all events.\nobject.off(null, null, context);\n\n// Removes all callbacks on `object`.\nobject.off();\n</pre>\n\n    <p>\n      Note that calling <tt>model.off()</tt>, for example, will indeed remove <i>all</i> events\n      on the model &mdash; including events that Backbone uses for internal bookkeeping.\n    </p>\n\n    <p id=\"Events-trigger\">\n      <b class=\"header\">trigger</b><code>object.trigger(event, [*args])</code>\n      <br />\n      Trigger callbacks for the given <b>event</b>, or space-delimited list of events.\n      Subsequent arguments to <b>trigger</b> will be passed along to the\n      event callbacks.\n    </p>\n\n    <p id=\"Events-once\">\n      <b class=\"header\">once</b><code>object.once(event, callback, [context])</code>\n      <br />\n      Just like <a href=\"#Events-on\">on</a>, but causes the bound callback to fire\n      only once before being removed. Handy for saying \"the next time that X happens, do this\".\n      When multiple events are passed in using the space separated syntax, the event will fire once\n      for every event you passed in, not once for a combination of all events\n    </p>\n\n    <p id=\"Events-listenTo\">\n      <b class=\"header\">listenTo</b><code>object.listenTo(other, event, callback)</code>\n      <br />\n      Tell an <b>object</b> to listen to a particular event on an <b>other</b>\n      object.  The advantage of using this form, instead of <tt>other.on(event,\n      callback, object)</tt>, is that <b>listenTo</b> allows the <b>object</b>\n      to keep track of the events, and they can be removed all at once later\n      on.  The <b>callback</b> will always be called with <b>object</b> as\n      context.\n    </p>\n\n<pre>\nview.listenTo(model, 'change', view.render);\n</pre>\n\n    <p id=\"Events-stopListening\">\n      <b class=\"header\">stopListening</b><code>object.stopListening([other], [event], [callback])</code>\n      <br />\n      Tell an <b>object</b> to stop listening to events. Either call\n      <b>stopListening</b> with no arguments to have the <b>object</b> remove\n      all of its <a href=\"#Events-listenTo\">registered</a> callbacks ... or be more\n      precise by telling it to remove just the events it's listening to on a\n      specific object, or a specific event, or just a specific callback.\n    </p>\n\n<pre>\nview.stopListening();\n\nview.stopListening(model);\n</pre>\n\n    <p id=\"Events-listenToOnce\">\n      <b class=\"header\">listenToOnce</b><code>object.listenToOnce(other, event, callback)</code>\n      <br />\n      Just like <a href=\"#Events-listenTo\">listenTo</a>, but causes the bound\n      callback to fire only once before being removed.\n    </p>\n\n    <p id=\"Events-catalog\">\n      <b class=\"header\">Catalog of Events</b>\n      <br />\n      Here's the complete list of built-in Backbone events, with arguments.\n      You're also free to trigger your own events on Models, Collections and\n      Views as you see fit. The <tt>Backbone</tt> object itself mixes in <tt>Events</tt>,\n      and can be used to emit any global events that your application needs.\n    </p>\n\n    <ul class=\"small\">\n      <li><b>\"add\"</b> (model, collection, options) &mdash; when a model is added to a collection.</li>\n      <li><b>\"remove\"</b> (model, collection, options) &mdash; when a model is removed from a collection.</li>\n      <li><b>\"update\"</b> (collection, options) &mdash; single event triggered after any number of models have been added, removed or changed in a collection.</li>\n      <li><b>\"reset\"</b> (collection, options) &mdash; when the collection's entire contents have been <a href=\"#Collection-reset\">reset</a>.</li>\n      <li><b>\"sort\"</b> (collection, options) &mdash; when the collection has been re-sorted.</li>\n      <li><b>\"change\"</b> (model, options) &mdash; when a model's attributes have changed.</li>\n      <li><b>\"changeId\"</b> (model, previousId, options) &mdash; when the model's id has been updated.</li>\n      <li><b>\"change:[attribute]\"</b> (model, value, options) &mdash; when a specific attribute has been updated.</li>\n      <li><b>\"destroy\"</b> (model, collection, options) &mdash; when a model is <a href=\"#Model-destroy\">destroyed</a>.</li>\n      <li><b>\"request\"</b> (model_or_collection, xhr, options) &mdash; when a model or collection has started a request to the server.</li>\n      <li><b>\"sync\"</b> (model_or_collection, response, options) &mdash; when a model or collection has been successfully synced with the server.</li>\n      <li><b>\"error\"</b> (model_or_collection, xhr, options) &mdash; when a model's or collection's request to the server has failed.</li>\n      <li><b>\"invalid\"</b> (model, error, options) &mdash; when a model's <a href=\"#Model-validate\">validation</a> fails on the client.</li>\n      <li><b>\"route:[name]\"</b> (params) &mdash; Fired by the router when a specific route is matched.</li>\n      <li><b>\"route\"</b> (route, params) &mdash; Fired by the router when <i>any</i> route has been matched.</li>\n      <li><b>\"route\"</b> (router, route, params) &mdash; Fired by history when <i>any</i> route has been matched.</li>\n      <li><b>\"notfound\"</b> () &mdash; Fired by history when <i>no</i> route could be matched.</li>\n      <li><b>\"all\"</b> &mdash; this special event fires for <i>any</i> triggered event, passing the event name as the first argument followed by all trigger arguments.</li>\n    </ul>\n\n    <p>\n      Generally speaking, when calling a function that emits an event\n      (<tt>model.set</tt>, <tt>collection.add</tt>, and so on...),\n      if you'd like to prevent the event from being triggered, you may pass\n      <tt>{silent: true}</tt> as an option. Note that this is <i>rarely</i>,\n      perhaps even never, a good idea. Passing through a specific flag\n      in the options for your event callback to look at, and choose to ignore,\n      will usually work out better.\n    </p>\n\n    <h2 id=\"Model\">Backbone.Model</h2>\n\n    <p>\n      <b>Models</b> are the heart of any JavaScript application, containing\n      the interactive data as well as a large part of the logic surrounding it:\n      conversions, validations, computed properties, and access control. You\n      extend <b>Backbone.Model</b> with your domain-specific methods, and\n      <b>Model</b> provides a basic set of functionality for managing changes.\n    </p>\n\n    <p>\n      The following is a contrived example, but it demonstrates defining a model\n      with a custom method, setting an attribute, and firing an event keyed\n      to changes in that specific attribute.\n      After running this code once, <tt>sidebar</tt> will be\n      available in your browser's console, so you can play around with it.\n    </p>\n\n<pre class=\"runnable\">\nvar Sidebar = Backbone.Model.extend({\n  promptColor: function() {\n    var cssColor = prompt(\"Please enter a CSS color:\");\n    this.set({color: cssColor});\n  }\n});\n\nwindow.sidebar = new Sidebar;\n\nsidebar.on('change:color', function(model, color) {\n  $('#sidebar').css({background: color});\n});\n\nsidebar.set({color: 'white'});\n\nsidebar.promptColor();\n</pre>\n\n    <p id=\"Model-extend\">\n      <b class=\"header\">extend</b><code>Backbone.Model.extend(properties, [classProperties])</code>\n      <br />\n      To create a <b>Model</b> class of your own, you extend <b>Backbone.Model</b>\n      and provide instance <b>properties</b>, as well as optional\n      <b>classProperties</b> to be attached directly to the constructor function.\n    </p>\n\n    <p>\n      <b>extend</b> correctly sets up the prototype chain, so subclasses created\n      with <b>extend</b> can be further extended and subclassed as far as you like.\n    </p>\n\n<pre>\nvar Note = Backbone.Model.extend({\n\n  initialize: function() { ... },\n\n  author: function() { ... },\n\n  coordinates: function() { ... },\n\n  allowedToEdit: function(account) {\n    return true;\n  }\n\n});\n\nvar PrivateNote = Note.extend({\n\n  allowedToEdit: function(account) {\n    return account.owns(this);\n  }\n\n});\n</pre>\n\n    <p class=\"warning\">\n        Brief aside on <tt>super</tt>: JavaScript does not provide\n        a simple way to call super &mdash; the function of the same name defined\n        higher on the prototype chain. If you override a core function like\n        <tt>set</tt>, or <tt>save</tt>, and you want to invoke the\n        parent object's implementation, you'll have to explicitly call it, along these lines:\n    </p>\n\n<pre>\nvar Note = Backbone.Model.extend({\n  set: function(attributes, options) {\n    Backbone.Model.prototype.set.apply(this, arguments);\n    ...\n  }\n});\n</pre>\n\n    <p id=\"Model-preinitialize\">\n      <b class=\"header\">preinitialize</b><code>new Model([attributes], [options])</code>\n      <br />\n      For use with models as ES classes. If you define a <b>preinitialize</b>\n      method, it will be invoked when the Model is first created, before any\n      instantiation logic is run for the Model.\n    </p>\n\n<pre>\nclass Country extends Backbone.Model {\n    preinitialize({countryCode}) {\n      this.name = COUNTRY_NAMES[countryCode];\n    }\n\n    initialize() { ... }\n}\n</pre>\n\n    <p id=\"Model-constructor\">\n      <b class=\"header\">constructor / initialize</b><code>new Model([attributes], [options])</code>\n      <br />\n      When creating an instance of a model, you can pass in the initial values\n      of the <b>attributes</b>, which will be <a href=\"#Model-set\">set</a> on the\n      model. If you define an <b>initialize</b> function, it will be invoked when\n      the model is created.\n    </p>\n\n<pre>\nnew Book({\n  title: \"One Thousand and One Nights\",\n  author: \"Scheherazade\"\n});\n</pre>\n\n    <p>\n      In rare cases, if you're looking to get fancy,\n      you may want to override <b>constructor</b>, which allows\n      you to replace the actual constructor function for your model.\n    </p>\n\n<pre>\nvar Library = Backbone.Model.extend({\n  constructor: function() {\n    this.books = new Books();\n    Backbone.Model.apply(this, arguments);\n  },\n  parse: function(data, options) {\n    this.books.reset(data.books);\n    return data.library;\n  }\n});\n</pre>\n\n    <p>\n      If you pass a <tt>{collection: ...}</tt> as the <b>options</b>, the model\n      gains a <tt>collection</tt> property that will be used to indicate which\n      collection the model belongs to, and is used to help compute the model's\n      <a href=\"#Model-url\">url</a>. The <tt>model.collection</tt> property is\n      normally created automatically when you first add a model to a collection.\n      Note that the reverse is not true, as passing this option to the constructor\n      will not automatically add the model to the collection. Useful, sometimes.\n    </p>\n\n    <p>\n      If <tt>{parse: true}</tt> is passed as an <b>option</b>, the <b>attributes</b>\n      will first be converted by <a href=\"#Model-parse\">parse</a> before being\n      <a href=\"#Model-set\">set</a> on the model.\n    </p>\n\n    <p id=\"Model-get\">\n      <b class=\"header\">get</b><code>model.get(attribute)</code>\n      <br />\n      Get the current value of an attribute from the model. For example:\n      <tt>note.get(\"title\")</tt>\n    </p>\n\n    <p id=\"Model-set\">\n      <b class=\"header\">set</b><code>model.set(attributes, [options])</code>\n      <br />\n      Set a hash of attributes (one or many) on the model. If any of the attributes\n      change the model's state, a <tt>\"change\"</tt> event will be triggered on the model.\n      Change events for specific attributes are also triggered, and you can bind\n      to those as well, for example: <tt>change:title</tt>, and <tt>change:content</tt>.\n      You may also pass individual keys and values.\n    </p>\n\n<pre>\nnote.set({title: \"March 20\", content: \"In his eyes she eclipses...\"});\n\nbook.set(\"title\", \"A Scandal in Bohemia\");\n</pre>\n\n    <p id=\"Model-escape\">\n      <b class=\"header\">escape</b><code>model.escape(attribute)</code>\n      <br />\n      Similar to <a href=\"#Model-get\">get</a>, but returns the HTML-escaped version\n      of a model's attribute. If you're interpolating data from the model into\n      HTML, using <b>escape</b> to retrieve attributes will prevent\n      <a href=\"http://en.wikipedia.org/wiki/Cross-site_scripting\">XSS</a> attacks.\n    </p>\n\n<pre class=\"runnable\">\nvar hacker = new Backbone.Model({\n  name: \"&lt;script&gt;alert('xss')&lt;/script&gt;\"\n});\n\nalert(hacker.escape('name'));\n</pre>\n\n    <p id=\"Model-has\">\n      <b class=\"header\">has</b><code>model.has(attribute)</code>\n      <br />\n      Returns <tt>true</tt> if the attribute is set to a non-null or non-undefined\n      value.\n    </p>\n\n<pre>\nif (note.has(\"title\")) {\n  ...\n}\n</pre>\n\n    <p id=\"Model-unset\">\n      <b class=\"header\">unset</b><code>model.unset(attribute, [options])</code>\n      <br />\n      Remove an attribute by deleting it from the internal attributes hash.\n      Fires a <tt>\"change\"</tt> event unless <tt>silent</tt> is passed as an option.\n    </p>\n\n    <p id=\"Model-clear\">\n      <b class=\"header\">clear</b><code>model.clear([options])</code>\n      <br />\n      Removes all attributes from the model, including the <tt>id</tt> attribute. Fires a <tt>\"change\"</tt> event unless\n      <tt>silent</tt> is passed as an option.\n    </p>\n\n    <p id=\"Model-id\">\n      <b class=\"header\">id</b><code>model.id</code>\n      <br />\n      A special property of models, the <b>id</b> is an arbitrary string\n      (integer id or UUID). If you set the <b>id</b> in the\n      attributes hash, it will be copied onto the model as a direct property.\n      <code>model.id</code> should not be manipulated directly,\n      it should be modified only via <code>model.set('id', …)</code>.\n      Models can be retrieved by id from collections, and the id is used to generate\n      model URLs by default.\n    </p>\n\n    <p id=\"Model-idAttribute\">\n      <b class=\"header\">idAttribute</b><code>model.idAttribute</code>\n      <br />\n      A model's unique identifier is stored under the <tt>id</tt> attribute.\n      If you're directly communicating with a backend (CouchDB, MongoDB) that uses\n      a different unique key, you may set a Model's <tt>idAttribute</tt> to\n      transparently map from that key to <tt>id</tt>.\n      If you set <tt>idAttribute</tt>, you may also want to\n      override <a href=\"#Model-cidPrefix\"><tt>cidPrefix</tt></a>.\n\n<pre class=\"runnable\">\nvar Meal = Backbone.Model.extend({\n  idAttribute: \"_id\"\n});\n\nvar cake = new Meal({ _id: 1, name: \"Cake\" });\nalert(\"Cake id: \" + cake.id);\n</pre>\n    </p>\n\n    <p id=\"Model-cid\">\n      <b class=\"header\">cid</b><code>model.cid</code>\n      <br />\n      A special property of models, the <b>cid</b> or client id is a unique identifier\n      automatically assigned to all models when they're first created. Client ids\n      are handy when the model has not yet been saved to the server, and does not\n      yet have its eventual true <b>id</b>, but already needs to be visible in the UI.\n    </p>\n\n    <p id=\"Model-cidPrefix\">\n      <b class=\"header\">cidPrefix</b><code>model.cidPrefix</code>\n      <br>\n      If your model has an <tt>id</tt> that is anything other than an\n      integer or a UUID, there is the possibility that it might collide with\n      its <tt>cid</tt>. To prevent this, you can override the prefix\n      that <tt>cid</tt>s start with.\n\n<pre class=\"runnable\">\n// If both lengths are 2, refresh the page before running this example.\nvar clashy = new Backbone.Collection([\n  {id: 'c2'},\n  {id: 'c1'},\n]);\nalert('clashy length: ' + clashy.length);\n\nvar ClashFree = Backbone.Model.extend({cidPrefix: 'm'});\nvar clashless = new Backbone.Collection([\n  {id: 'c3'},\n  {id: 'c2'},\n], {model: ClashFree});\nalert('clashless length: ' + clashless.length);\n</pre>\n    </p>\n\n    <p id=\"Model-attributes\">\n      <b class=\"header\">attributes</b><code>model.attributes</code>\n      <br />\n      The <b>attributes</b> property is the internal hash containing the model's\n      state &mdash; usually (but not necessarily) a form of the JSON object\n      representing the model data on the server. It's often a straightforward\n      serialization of a row from the database, but it could also be client-side\n      computed state.\n    </p>\n\n    <p>\n      Please use <a href=\"#Model-set\">set</a> to update the <b>attributes</b>\n      instead of modifying them directly. If you'd like to retrieve and munge a\n      copy of the model's attributes, use <tt>_.clone(model.attributes)</tt>\n      instead.\n    </p>\n\n    <p class=\"warning\">\n      Due to the fact that <a href=\"#Events\">Events</a> accepts space separated\n      lists of events, attribute names should not include spaces.\n    </p>\n\n    <p id=\"Model-changed\">\n      <b class=\"header\">changed</b><code>model.changed</code>\n      <br />\n      The <b>changed</b> property is the internal hash containing all the attributes\n      that have changed since its last <a href=\"#Model-set\">set</a>.\n      Please do not update <b>changed</b> directly since its state is internally maintained\n      by <a href=\"#Model-set\">set</a>.  A copy of <b>changed</b> can be acquired from\n      <a href=\"#Model-changedAttributes\">changedAttributes</a>.\n    </p>\n\n    <p id=\"Model-defaults\">\n      <b class=\"header\">defaults</b><code>model.defaults or model.defaults()</code>\n      <br />\n      The <b>defaults</b> hash (or function) can be used to specify the default\n      attributes for your model. When creating an instance of the model,\n      any unspecified attributes will be set to their default value.\n    </p>\n\n<pre class=\"runnable\">\nvar Meal = Backbone.Model.extend({\n  defaults: {\n    \"appetizer\":  \"caesar salad\",\n    \"entree\":     \"ravioli\",\n    \"dessert\":    \"cheesecake\"\n  }\n});\n\nalert(\"Dessert will be \" + (new Meal).get('dessert'));\n</pre>\n\n    <p class=\"warning\">\n      Remember that in JavaScript, objects are passed by reference, so if you\n      include an object as a default value, it will be shared among all instances.\n      Instead, define <b>defaults</b> as a function.\n    </p>\n\n    <p class=\"warning\">\n      If you set a value for the model&rsquo;s\n      <a href=\"#Model-idAttribute\"><tt>idAttribute</tt></a>, you should define\n      the defaults as a function that returns a different, <u>universally</u>\n      unique id on every invocation. Not doing so would likely prevent an\n      instance of <tt>Backbone.Collection</tt> from correctly identifying model\n      hashes and is almost certainly a mistake, unless you never add instances\n      of the model class to a collection.\n    </p>\n\n    <p id=\"Model-toJSON\">\n      <b class=\"header\">toJSON</b><code>model.toJSON([options])</code>\n      <br />\n      Return a shallow copy of the model's <a href=\"#Model-attributes\">attributes</a>\n      for JSON stringification.  This can be used for persistence,\n      serialization, or for augmentation before being sent to the server. The\n      name of this method is a bit confusing, as it doesn't actually return a\n      JSON string &mdash; but I'm afraid that it's the way that the\n      <a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON_behavior\">JavaScript API for <b>JSON.stringify</b></a>\n      works.\n    </p>\n\n<pre class=\"runnable\">\nvar artist = new Backbone.Model({\n  firstName: \"Wassily\",\n  lastName: \"Kandinsky\"\n});\n\nartist.set({birthday: \"December 16, 1866\"});\n\nalert(JSON.stringify(artist));\n</pre>\n\n    <p id=\"Model-sync\">\n      <b class=\"header\">sync</b><code>model.sync(method, model, [options])</code>\n      <br />\n      Uses <a href=\"#Sync\">Backbone.sync</a> to persist the state of a model to\n      the server.  Can be overridden for custom behavior.\n    </p>\n\n    <p id=\"Model-fetch\">\n      <b class=\"header\">fetch</b><code>model.fetch([options])</code>\n      <br />\n      Merges the model's state with attributes fetched from the server by\n      delegating to <a href=\"#Sync\">Backbone.sync</a>. Returns a\n      <a href=\"http://api.jquery.com/jQuery.ajax/#jqXHR\">jqXHR</a>.\n      Useful if the model has never\n      been populated with data, or if you'd like to ensure that you have the\n      latest server state. Triggers a <tt>\"change\"</tt> event if the\n      server's state differs from the current attributes. <tt>fetch</tt> accepts\n      <tt>success</tt> and <tt>error</tt> callbacks in the options hash, which\n      are both passed <tt>(model, response, options)</tt> as arguments.\n    </p>\n\n<pre>\n// Poll every 10 seconds to keep the channel model up-to-date.\nsetInterval(function() {\n  channel.fetch();\n}, 10000);\n</pre>\n\n    <p id=\"Model-save\">\n      <b class=\"header\">save</b><code>model.save([attributes], [options])</code>\n      <br />\n      Save a model to your database (or alternative persistence layer),\n      by delegating to <a href=\"#Sync\">Backbone.sync</a>.  Returns a\n      <a href=\"http://api.jquery.com/jQuery.ajax/#jqXHR\">jqXHR</a> if\n      validation is successful and <tt>false</tt> otherwise. The <b>attributes</b>\n      hash (as in <a href=\"#Model-set\">set</a>) should contain the attributes\n      you'd like to change &mdash; keys that aren't mentioned won't be altered &mdash; but,\n      a <i>complete representation</i> of the resource will be sent to the server.\n      As with <tt>set</tt>, you may pass individual keys and values instead of a hash.\n      If the model has a <a href=\"#Model-validate\">validate</a>\n      method, and validation fails, the model will not be saved. If the model\n      <a href=\"#Model-isNew\">isNew</a>, the save will be a <tt>\"create\"</tt>\n      (HTTP <tt>POST</tt>), if the model already\n      exists on the server, the save will be an <tt>\"update\"</tt> (HTTP <tt>PUT</tt>).\n    </p>\n\n    <p>\n      If instead, you'd only like the <i>changed</i> attributes to be sent to the\n      server, call <tt>model.save(attrs, {patch: true})</tt>. You'll get an HTTP\n      <tt>PATCH</tt> request to the server with just the passed-in attributes.\n    </p>\n\n    <p>\n      Calling <tt>save</tt> with new attributes will cause a <tt>\"change\"</tt>\n      event immediately, a <tt>\"request\"</tt> event as the Ajax request begins to\n      go to the server, and a <tt>\"sync\"</tt> event after the server has acknowledged\n      the successful change. Pass <tt>{wait: true}</tt> if you'd like to wait\n      for the server before setting the new attributes on the model.\n    </p>\n\n    <p>\n      In the following example, notice how our overridden version\n      of <tt>Backbone.sync</tt> receives a <tt>\"create\"</tt> request\n      the first time the model is saved and an <tt>\"update\"</tt>\n      request the second time.\n    </p>\n\n<pre class=\"runnable\">\nBackbone.sync = function(method, model) {\n  alert(method + \": \" + JSON.stringify(model));\n  model.set('id', 1);\n};\n\nvar book = new Backbone.Model({\n  title: \"The Rough Riders\",\n  author: \"Theodore Roosevelt\"\n});\n\nbook.save();\n\nbook.save({author: \"Teddy\"});\n</pre>\n\n    <p>\n      <b>save</b> accepts <tt>success</tt> and <tt>error</tt> callbacks in the\n      options hash, which will be passed the arguments <tt>(model, response, options)</tt>.\n      If a server-side validation fails, return a non-<tt>200</tt>\n      HTTP response code, along with an error response in text or JSON.\n    </p>\n\n<pre>\nbook.save(\"author\", \"F.D.R.\", {error: function(){ ... }});\n</pre>\n\n    <p id=\"Model-destroy\">\n      <b class=\"header\">destroy</b><code>model.destroy([options])</code>\n      <br />\n      Destroys the model on the server by delegating an HTTP <tt>DELETE</tt>\n      request to <a href=\"#Sync\">Backbone.sync</a>. Returns a\n      <a href=\"http://api.jquery.com/jQuery.ajax/#jqXHR\">jqXHR</a> object, or\n      <tt>false</tt> if the model <a href=\"#Model-isNew\">isNew</a>. Accepts\n      <tt>success</tt> and <tt>error</tt> callbacks in the options hash, which\n      will be passed <tt>(model, response, options)</tt>.\n      Triggers a <tt>\"destroy\"</tt> event on the model, which will bubble up\n      through any collections that contain it, a <tt>\"request\"</tt> event as it\n      begins the Ajax request to the server, and a <tt>\"sync\"</tt> event, after\n      the server has successfully acknowledged the model's deletion. Pass\n      <tt>{wait: true}</tt> if you'd like to wait for the server to respond\n      before removing the model from the collection.\n    </p>\n\n<pre>\nbook.destroy({success: function(model, response) {\n  ...\n}});\n</pre>\n\n    <p id=\"Model-Underscore-Methods\">\n      <b class=\"header\">Underscore Methods (9)</b>\n      <br />\n      Backbone proxies to <b>Underscore.js</b> to provide 9 object functions\n      on <b>Backbone.Model</b>. They aren't all documented here, but\n      you can take a look at the Underscore documentation for the full details&hellip;\n    </p>\n\n    <ul class=\"small\">\n      <li><a href=\"http://underscorejs.org/#keys\">keys</a></li>\n      <li><a href=\"http://underscorejs.org/#values\">values</a></li>\n      <li><a href=\"http://underscorejs.org/#pairs\">pairs</a></li>\n      <li><a href=\"http://underscorejs.org/#invert\">invert</a></li>\n      <li><a href=\"http://underscorejs.org/#pick\">pick</a></li>\n      <li><a href=\"http://underscorejs.org/#omit\">omit</a></li>\n      <li><a href=\"http://underscorejs.org/#chain\">chain</a></li>\n      <li><a href=\"http://underscorejs.org/#isEmpty\">isEmpty</a></li>\n    </ul>\n\n<pre>\nuser.pick('first_name', 'last_name', 'email');\n\nchapters.keys().join(', ');\n</pre>\n\n    <p id=\"Model-validate\">\n      <b class=\"header\">validate</b><code>model.validate(attributes, options)</code>\n      <br />\n      This method is left undefined and you're encouraged to override it with\n      any custom validation logic you have that can be performed in JavaScript.\n      If the attributes are valid, don't return anything from <b>validate</b>;\n      if they are invalid return an error of your choosing. It can be as\n      simple as a string error message to be displayed, or a complete error\n      object that describes the error programmatically.\n    </p>\n\n    <p>\n      By default <tt>save</tt> checks <b>validate</b> before\n      setting any attributes but you may also tell <tt>set</tt> to validate\n      the new attributes by passing <tt>{validate: true}</tt> as an option.\n      The <b>validate</b> method receives the model attributes as well as any\n      options passed to <tt>set</tt> or <tt>save</tt>, if <b>validate</b>\n      returns an error, <tt>save</tt> does not continue, the model attributes\n      are not modified on the server, an <tt>\"invalid\"</tt> event is triggered,\n      and the <tt>validationError</tt> property is set on the model with the\n      value returned by this method.\n    </p>\n\n<pre class=\"runnable\">\nvar Chapter = Backbone.Model.extend({\n  validate: function(attrs, options) {\n    if (attrs.end &lt; attrs.start) {\n      return \"can't end before it starts\";\n    }\n  }\n});\n\nvar one = new Chapter({\n  title : \"Chapter One: The Beginning\"\n});\n\none.on(\"invalid\", function(model, error) {\n  alert(model.get(\"title\") + \" \" + error);\n});\n\none.save({\n  start: 15,\n  end:   10\n});\n</pre>\n\n    <p>\n      <tt>\"invalid\"</tt> events are useful for providing coarse-grained error\n      messages at the model or collection level.\n    </p>\n\n    <p id=\"Model-validationError\">\n      <b class=\"header\">validationError</b><code>model.validationError</code>\n      <br />\n      The value returned by <a href=\"#Model-validate\">validate</a> during the last failed validation.\n    </p>\n\n    <p id=\"Model-isValid\">\n      <b class=\"header\">isValid</b><code>model.isValid(options)</code>\n      <br />\n      Run <a href=\"#Model-validate\">validate</a> to check the model state.\n    </p>\n\n    <p>\n      The <tt>validate</tt> method receives the model attributes as well as any\n      options passed to <b>isValid</b>, if <tt>validate</tt> returns an error\n      an <tt>\"invalid\"</tt> event is triggered, and the error is set on the\n      model in the <tt>validationError</tt> property.\n    </p>\n\n<pre class=\"runnable\">\nvar Chapter = Backbone.Model.extend({\n  validate: function(attrs, options) {\n    if (attrs.end &lt; attrs.start) {\n      return \"can't end before it starts\";\n    }\n  }\n});\n\nvar one = new Chapter({\n  title : \"Chapter One: The Beginning\"\n});\n\none.set({\n  start: 15,\n  end:   10\n});\n\nif (!one.isValid()) {\n  alert(one.get(\"title\") + \" \" + one.validationError);\n}\n</pre>\n\n    <p id=\"Model-url\">\n      <b class=\"header\">url</b><code>model.url()</code>\n      <br />\n      Returns the relative URL where the model's resource would be located on\n      the server. If your models are located somewhere else, override this method\n      with the correct logic. Generates URLs of the form: <tt>\"[collection.url]/[id]\"</tt>\n      by default, but you may override by specifying an explicit <tt>urlRoot</tt>\n      if the model's collection shouldn't be taken into account.\n    </p>\n\n    <p>\n      Delegates to <a href=\"#Collection-url\">Collection#url</a> to generate the\n      URL, so make sure that you have it defined, or a <a href=\"#Model-urlRoot\">urlRoot</a>\n      property, if all models of this class share a common root URL.\n      A model with an id of <tt>101</tt>, stored in a\n      <a href=\"#Collection\">Backbone.Collection</a> with a <tt>url</tt> of <tt>\"/documents/7/notes\"</tt>,\n      would have this URL: <tt>\"/documents/7/notes/101\"</tt>\n    </p>\n\n    <p id=\"Model-urlRoot\">\n      <b class=\"header\">urlRoot</b><code>model.urlRoot or model.urlRoot()</code>\n      <br />\n      Specify a <tt>urlRoot</tt> if you're using a model <i>outside</i> of a collection,\n      to enable the default <a href=\"#Model-url\">url</a> function to generate\n      URLs based on the model id. <tt>\"[urlRoot]/id\"</tt><br />\n      Normally, you won't need to define this.\n      Note that <tt>urlRoot</tt> may also be a function.\n    </p>\n\n<pre class=\"runnable\">\nvar Book = Backbone.Model.extend({urlRoot : '/books'});\n\nvar solaris = new Book({id: \"1083-lem-solaris\"});\n\nalert(solaris.url());\n</pre>\n\n    <p id=\"Model-parse\">\n      <b class=\"header\">parse</b><code>model.parse(response, options)</code>\n      <br />\n      <b>parse</b> is called whenever a model's data is returned by the\n      server, in <a href=\"#Model-fetch\">fetch</a>, and <a href=\"#Model-save\">save</a>.\n      The function is passed the raw <tt>response</tt> object, and should return\n      the attributes hash to be <a href=\"#Model-set\">set</a> on the model. The\n      default implementation is a no-op, simply passing through the JSON response.\n      Override this if you need to work with a preexisting API, or better namespace\n      your responses.\n    </p>\n\n    <p>\n      If you're working with a Rails backend that has a version prior to 3.1,\n      you'll notice that its default <tt>to_json</tt> implementation includes\n      a model's attributes under a namespace. To disable this behavior for\n      seamless Backbone integration, set:\n    </p>\n\n<pre>\nActiveRecord::Base.include_root_in_json = false\n</pre>\n\n    <p id=\"Model-clone\">\n      <b class=\"header\">clone</b><code>model.clone()</code>\n      <br />\n      Returns a new instance of the model with identical attributes.\n    </p>\n\n    <p id=\"Model-isNew\">\n      <b class=\"header\">isNew</b><code>model.isNew()</code>\n      <br />\n      Has this model been saved to the server yet? If the model does not yet have\n      an <tt>id</tt>, it is considered to be new.\n    </p>\n\n    <p id=\"Model-hasChanged\">\n      <b class=\"header\">hasChanged</b><code>model.hasChanged([attribute])</code>\n      <br />\n      Has the model changed since its last <a href=\"#Model-set\">set</a>? If an <b>attribute</b>\n      is passed, returns <tt>true</tt> if that specific attribute has changed.\n    </p>\n\n    <p class=\"warning\">\n      Note that this method, and the following change-related ones,\n      are only useful during the course of a <tt>\"change\"</tt> event.\n    </p>\n\n<pre>\nbook.on(\"change\", function() {\n  if (book.hasChanged(\"title\")) {\n    ...\n  }\n});\n</pre>\n\n    <p id=\"Model-changedAttributes\">\n      <b class=\"header\">changedAttributes</b><code>model.changedAttributes([attributes])</code>\n      <br />\n      Retrieve a hash of only the model's attributes that have changed since the last\n      <a href=\"#Model-set\">set</a>, or <tt>false</tt> if there are none. Optionally, an external\n      <b>attributes</b> hash can be passed in, returning the attributes in that\n      hash which differ from the model. This can be used to figure out which\n      portions of a view should be updated, or what calls\n      need to be made to sync the changes to the server.\n    </p>\n\n    <p id=\"Model-previous\">\n      <b class=\"header\">previous</b><code>model.previous(attribute)</code>\n      <br />\n      During a <tt>\"change\"</tt> event, this method can be used to get the\n      previous value of a changed attribute.\n    </p>\n\n<pre class=\"runnable\">\nvar bill = new Backbone.Model({\n  name: \"Bill Smith\"\n});\n\nbill.on(\"change:name\", function(model, name) {\n  alert(\"Changed name from \" + bill.previous(\"name\") + \" to \" + name);\n});\n\nbill.set({name : \"Bill Jones\"});\n</pre>\n\n    <p id=\"Model-previousAttributes\">\n      <b class=\"header\">previousAttributes</b><code>model.previousAttributes()</code>\n      <br />\n      Return a copy of the model's previous attributes. Useful for getting a\n      diff between versions of a model, or getting back to a valid state after\n      an error occurs.\n    </p>\n\n    <h2 id=\"Collection\">Backbone.Collection</h2>\n\n    <p>\n      Collections are ordered sets of models. You can bind <tt>\"change\"</tt> events\n      to be notified when any model in the collection has been modified,\n      listen for <tt>\"add\"</tt> and <tt>\"remove\"</tt> events, <tt>fetch</tt>\n      the collection from the server, and use a full suite of\n      <a href=\"#Collection-Underscore-Methods\">Underscore.js methods</a>.\n    </p>\n\n    <p>\n      Any event that is triggered on a model in a collection will also be\n      triggered on the collection directly, for convenience.\n      This allows you to listen for changes to specific attributes in any\n      model in a collection, for example:\n      <tt>documents.on(\"change:selected\", ...)</tt>\n    </p>\n\n    <p id=\"Collection-extend\">\n      <b class=\"header\">extend</b><code>Backbone.Collection.extend(properties, [classProperties])</code>\n      <br />\n      To create a <b>Collection</b> class of your own, extend <b>Backbone.Collection</b>,\n      providing instance <b>properties</b>, as well as optional <b>classProperties</b> to be attached\n      directly to the collection's constructor function.\n    </p>\n\n    <p id=\"Collection-model\">\n      <b class=\"header\">model</b><code>collection.model([attrs], [options])</code>\n      <br />\n      Override this property to specify the model class that the collection contains.\n      If defined, you can pass raw attributes objects (and arrays) and options to\n      <a href=\"#Collection-add\">add</a>, <a href=\"#Collection-create\">create</a>,\n      and <a href=\"#Collection-reset\">reset</a>, and the attributes will be\n      converted into a model of the proper type using the provided options, if any.\n    </p>\n\n<pre>\nvar Library = Backbone.Collection.extend({\n  model: Book\n});\n</pre>\n\n    <p>\n      A collection can also contain polymorphic models by overriding this property\n      with a constructor that returns a model.\n    </p>\n\n<pre>\nvar Library = Backbone.Collection.extend({\n\n  model: function(attrs, options) {\n    if (condition) {\n      return new PublicDocument(attrs, options);\n    } else {\n      return new PrivateDocument(attrs, options);\n    }\n  }\n\n});\n</pre>\n\n    <p id=\"Collection-modelId\">\n      <b class=\"header\">modelId</b><code>collection.modelId(attrs, idAttribute)</code>\n      <br />\n      Override this method to return the value the collection will use to\n      identify a model given its attributes. Useful for combining models from\n      multiple tables with different <a href=\"#Model-idAttribute\"><tt>idAttribute</tt></a>\n      values into a single collection.\n    </p>\n\n    <p>\n      By default returns the value of the given\n      <a href=\"#Model-idAttribute\"><tt>idAttribute</tt></a>\n      within the <tt>attrs</tt>, or failing that, <tt>id</tt>. If\n      your collection uses a <a href=\"#Collection-model\">model factory</a> and\n      the id ranges of those models might collide, you must\n      override this method.\n    </p>\n\n<pre class=\"runnable\">\nvar Library = Backbone.Collection.extend({\n  modelId: function(attrs) {\n    return attrs.type + attrs.id;\n  }\n});\n\nvar library = new Library([\n  {type: 'dvd', id: 1},\n  {type: 'vhs', id: 1}\n]);\n\nvar dvdId = library.get('dvd1').id;\nvar vhsId = library.get('vhs1').id;\nalert('dvd: ' + dvdId + ', vhs: ' + vhsId);\n</pre>\n\n    <p id=\"Collection-preinitialize\">\n      <b class=\"header\">preinitialize</b><code>new Backbone.Collection([models], [options])</code>\n      <br />\n      For use with collections as ES classes. If you define a <b>preinitialize</b>\n      method, it will be invoked when the Collection is first created and before\n      any instantiation logic is run for the Collection.\n    </p>\n\n<pre>\nclass Library extends Backbone.Collection {\n  preinitialize() {\n    this.on(\"add\", function() {\n      console.log(\"Add model event got fired!\");\n    });\n  }\n}\n</pre>\n\n    <p id=\"Collection-constructor\">\n      <b class=\"header\">constructor / initialize</b><code>new Backbone.Collection([models], [options])</code>\n      <br />\n      When creating a Collection, you may choose to pass in the initial array\n      of <b>models</b>.  The collection's <a href=\"#Collection-comparator\">comparator</a>\n      may be included as an option. Passing <tt>false</tt> as the\n      comparator option will prevent sorting. If you define an\n      <b>initialize</b> function, it will be invoked when the collection is\n      created. There are a couple of options that, if provided, are attached to\n      the collection directly: <tt>model</tt> and <tt>comparator</tt>.<br />\n      Pass <tt>null</tt> for <tt>models</tt> to create an empty Collection with <tt>options</tt>.\n    </p>\n\n<pre>\nvar tabs = new TabSet([tab1, tab2, tab3]);\nvar spaces = new Backbone.Collection(null, {\n  model: Space\n});\n</pre>\n\n    <p>\n      If <tt>{parse: true}</tt> is passed as an <b>option</b>, the <b>attributes</b>\n      will first be converted by <a href=\"#Collection-parse\">parse</a> before being\n      <a href=\"#Collection-set\">set</a> on the collection.\n    </p>\n\n    <p id=\"Collection-models\">\n      <b class=\"header\">models</b><code>collection.models</code>\n      <br />\n      Raw access to the JavaScript array of models inside of the collection. Usually you'll\n      want to use <tt>get</tt>, <tt>at</tt>, or the <b>Underscore methods</b>\n      to access model objects, but occasionally a direct reference to the array\n      is desired.\n    </p>\n\n    <p id=\"Collection-toJSON\">\n      <b class=\"header\">toJSON</b><code>collection.toJSON([options])</code>\n      <br />\n      Return an array containing the attributes hash of each model\n      (via <a href=\"#Model-toJSON\">toJSON</a>) in the\n      collection. This can be used to serialize and persist the\n      collection as a whole. The name of this method is a bit confusing, because\n      it conforms to\n      <a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON_behavior\">JavaScript's JSON API</a>.\n    </p>\n\n<pre class=\"runnable\">\nvar collection = new Backbone.Collection([\n  {name: \"Tim\", age: 5},\n  {name: \"Ida\", age: 26},\n  {name: \"Rob\", age: 55}\n]);\n\nalert(JSON.stringify(collection));\n</pre>\n\n    <p id=\"Collection-sync\">\n      <b class=\"header\">sync</b><code>collection.sync(method, collection, [options])</code>\n      <br />\n      Uses <a href=\"#Sync\">Backbone.sync</a> to persist the state of a\n      collection to the server.  Can be overridden for custom behavior.\n    </p>\n\n    <p id=\"Collection-Underscore-Methods\">\n      <b class=\"header\">Underscore Methods (46)</b>\n      <br />\n      Backbone proxies to <b>Underscore.js</b> to provide 46 iteration functions\n      on <b>Backbone.Collection</b>. They aren't all documented here, but\n      you can take a look at the Underscore documentation for the full details&hellip;\n    </p>\n\n    <p>\n      Most methods can take an object or string to support model-attribute-style\n      predicates or a function that receives the model instance as an argument.\n    </p>\n\n    <ul class=\"small\">\n      <li><a href=\"http://underscorejs.org/#each\">forEach (each)</a></li>\n      <li><a href=\"http://underscorejs.org/#map\">map (collect)</a></li>\n      <li><a href=\"http://underscorejs.org/#reduce\">reduce (foldl, inject)</a></li>\n      <li><a href=\"http://underscorejs.org/#reduceRight\">reduceRight (foldr)</a></li>\n      <li><a href=\"http://underscorejs.org/#find\">find (detect)</a></li>\n      <li><a href=\"http://underscorejs.org/#findIndex\">findIndex</a></li>\n      <li><a href=\"http://underscorejs.org/#findLastIndex\">findLastIndex</a></li>\n      <li><a href=\"http://underscorejs.org/#filter\">filter (select)</a></li>\n      <li><a href=\"http://underscorejs.org/#reject\">reject</a></li>\n      <li><a href=\"http://underscorejs.org/#every\">every (all)</a></li>\n      <li><a href=\"http://underscorejs.org/#some\">some (any)</a></li>\n      <li><a href=\"http://underscorejs.org/#contains\">contains (includes)</a></li>\n      <li><a href=\"http://underscorejs.org/#invoke\">invoke</a></li>\n      <li><a href=\"http://underscorejs.org/#max\">max</a></li>\n      <li><a href=\"http://underscorejs.org/#min\">min</a></li>\n      <li><a href=\"http://underscorejs.org/#sortBy\">sortBy</a></li>\n      <li><a href=\"http://underscorejs.org/#groupBy\">groupBy</a></li>\n      <li><a href=\"http://underscorejs.org/#shuffle\">shuffle</a></li>\n      <li><a href=\"http://underscorejs.org/#toArray\">toArray</a></li>\n      <li><a href=\"http://underscorejs.org/#size\">size</a></li>\n      <li><a href=\"http://underscorejs.org/#first\">first (head, take)</a></li>\n      <li><a href=\"http://underscorejs.org/#initial\">initial</a></li>\n      <li><a href=\"http://underscorejs.org/#rest\">rest (tail, drop)</a></li>\n      <li><a href=\"http://underscorejs.org/#last\">last</a></li>\n      <li><a href=\"http://underscorejs.org/#without\">without</a></li>\n      <li><a href=\"http://underscorejs.org/#indexOf\">indexOf</a></li>\n      <li><a href=\"http://underscorejs.org/#lastIndexOf\">lastIndexOf</a></li>\n      <li><a href=\"http://underscorejs.org/#isEmpty\">isEmpty</a></li>\n      <li><a href=\"http://underscorejs.org/#chain\">chain</a></li>\n      <li><a href=\"http://underscorejs.org/#difference\">difference</a></li>\n      <li><a href=\"http://underscorejs.org/#sample\">sample</a></li>\n      <li><a href=\"http://underscorejs.org/#partition\">partition</a></li>\n      <li><a href=\"http://underscorejs.org/#countBy\">countBy</a></li>\n      <li><a href=\"http://underscorejs.org/#indexBy\">indexBy</a></li>\n    </ul>\n\n<pre>\nbooks.each(function(book) {\n  book.publish();\n});\n\nvar titles = books.map(\"title\");\n\nvar publishedBooks = books.filter({published: true});\n\nvar alphabetical = books.sortBy(function(book) {\n  return book.author.get(\"name\").toLowerCase();\n});\n\nvar randomThree = books.sample(3);\n</pre>\n\n    <p id=\"Collection-add\">\n      <b class=\"header\">add</b><code>collection.add(models, [options])</code>\n      <br />\n      Add a model (or an array of models) to the collection, firing\n      an <tt>\"add\"</tt> event for each model, and an <tt>\"update\"</tt>\n      event afterwards. This is a variant\n      of <a href=\"#Collection-set\">set</a> with the same options and\n      return value, but it always adds and never removes. If you're\n      adding models to the collection that are <i>already</i> in the\n      collection, they'll be ignored, unless you pass <tt>{merge:\n      true}</tt>, in which case their attributes will be merged into\n      the corresponding models, firing any\n      appropriate <tt>\"change\"</tt> events.\n    </p>\n\n<pre class=\"runnable\">\nvar ships = new Backbone.Collection;\n\nships.on(\"add\", function(ship) {\n  alert(\"Ahoy \" + ship.get(\"name\") + \"!\");\n});\n\nships.add([\n  {name: \"Flying Dutchman\"},\n  {name: \"Black Pearl\"}\n]);\n</pre>\n\n    <p class=\"warning\">\n      Note that adding the same model (a model with the same <tt>id</tt>) to\n      a collection more than once <br /> is a no-op.\n    </p>\n\n    <p id=\"Collection-remove\">\n      <b class=\"header\">remove</b><code>collection.remove(models, [options])</code>\n      <br />\n      Remove a model (or an array of models) from the collection, and return\n      them. Each model can be a Model instance, an <tt>id</tt> string or a JS\n      object, any value acceptable as the <tt>id</tt> argument of\n      <a href=\"#Collection-get\"><tt>collection.get</tt></a>.\n      Fires a <tt>\"remove\"</tt> event for each model, and a single\n      <tt>\"update\"</tt> event afterwards, unless <tt>{silent: true}</tt> is passed.\n      The model's index before removal is available to listeners as\n      <tt>options.index</tt>.\n    </p>\n\n    <p id=\"Collection-reset\">\n      <b class=\"header\">reset</b><code>collection.reset([models], [options])</code>\n      <br />\n      Adding and removing models one at a time is all well and good, but sometimes\n      you have so many models to change that you'd rather just update the collection\n      in bulk. Use <b>reset</b> to replace a collection with a new list\n      of models (or attribute hashes), triggering a single <tt>\"reset\"</tt> event\n      on completion, and <i>without</i> triggering any add or remove events on any models.\n      Returns the newly-set models.\n      For convenience, within a <tt>\"reset\"</tt> event, the list of any\n      previous models is available as <tt>options.previousModels</tt>.<br />\n      Pass <tt>null</tt> for <tt>models</tt> to empty your Collection with <tt>options</tt>.\n    </p>\n\n    <p>\n      Here's an example using <b>reset</b> to bootstrap a collection during initial page load,\n      in a Rails application:\n    </p>\n\n<pre>\n&lt;script&gt;\n  var accounts = new Backbone.Collection;\n  accounts.reset(&lt;%= @accounts.to_json %&gt;);\n&lt;/script&gt;\n</pre>\n\n    <p>\n      Calling <tt>collection.reset()</tt> without passing any models as arguments\n      will empty the entire collection.\n    </p>\n\n    <p id=\"Collection-set\">\n      <b class=\"header\">set</b><code>collection.set(models, [options])</code>\n      <br />\n      The <b>set</b> method performs a \"smart\" update of the\n      collection with the passed list of models. If a model in the\n      list isn't yet in the collection it will be added; if the model\n      is already in the collection its attributes will be merged; and\n      if the collection contains any models that\n      <i>aren't</i> present in the list, they'll be removed. All of\n      the appropriate\n      <tt>\"add\"</tt>, <tt>\"remove\"</tt>, and <tt>\"change\"</tt> events\n      are fired as this happens, with a single <tt>\"update\"</tt> event\n      at the end. Returns the touched models in the collection. If\n      you'd like to customize this behavior, you can change it with\n      options: <tt>{add: false}</tt>, <tt>{remove: false}</tt>,\n      or <tt>{merge: false}</tt>.\n    </p>\n\n    <p>\n      If a <a href=\"#Collection-model\">model</a> property is defined,\n      you may also pass raw attributes objects and options, and have\n      them be vivified as instances of the model using the provided\n      options. If you set\n      a <a href=\"#Collection-comparator\">comparator</a>, the\n      collection will automatically sort itself and trigger\n      a <tt>\"sort\"</tt> event, unless you pass <tt>{sort: false}</tt>\n      or use the <tt>{at: index}</tt> option. Pass <tt>{at: index}</tt>\n      to splice the model(s) into the collection at the\n      specified <tt>index</tt>.\n    </p>\n\n<pre>\nvar vanHalen = new Backbone.Collection([eddie, alex, stone, roth]);\n\nvanHalen.set([eddie, alex, stone, hagar]);\n\n// Fires a \"remove\" event for roth, and an \"add\" event for \"hagar\".\n// Updates any of stone, alex, and eddie's attributes that may have\n// changed over the years.\n</pre>\n\n    <p id=\"Collection-get\">\n      <b class=\"header\">get</b><code>collection.get(id)</code>\n      <br />\n      Get a model from a collection, specified by an <a href=\"#Model-id\">id</a>,\n      a <a href=\"#Model-cid\">cid</a>, or by passing in a <b>model</b>.\n    </p>\n\n<pre>\nvar book = library.get(110);\n</pre>\n\n    <p id=\"Collection-at\">\n      <b class=\"header\">at</b><code>collection.at(index)</code>\n      <br />\n      Get a model from a collection, specified by index. Useful if your collection\n      is sorted, and if your collection isn't sorted, <b>at</b> will still\n      retrieve models in insertion order. When passed a negative index, it\n      will retrieve the model from the back of the collection.\n    </p>\n\n    <p id=\"Collection-push\">\n      <b class=\"header\">push</b><code>collection.push(model, [options])</code>\n      <br />\n      Like <a href=\"#Collection-add\">add</a>, but always adds a model\n      at the end of the collection and never sorts.\n    </p>\n\n    <p id=\"Collection-pop\">\n      <b class=\"header\">pop</b><code>collection.pop([options])</code>\n      <br />\n      Remove and return the last model from a collection. Takes the same options as\n      <a href=\"#Collection-remove\">remove</a>.\n    </p>\n\n    <p id=\"Collection-unshift\">\n      <b class=\"header\">unshift</b><code>collection.unshift(model, [options])</code>\n      <br />\n      Like <a href=\"#Collection-add\">add</a>, but always adds a model\n      at the beginning of the collection and never sorts.\n    </p>\n\n    <p id=\"Collection-shift\">\n      <b class=\"header\">shift</b><code>collection.shift([options])</code>\n      <br />\n      Remove and return the first model from a collection. Takes the same options as\n      <a href=\"#Collection-remove\">remove</a>.\n    </p>\n\n    <p id=\"Collection-slice\">\n      <b class=\"header\">slice</b><code>collection.slice(begin, end)</code>\n      <br />\n      Return a shallow copy of this collection's models, using the same options as\n      native\n      <a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">Array#slice</a>.\n    </p>\n\n    <p id=\"Collection-length\">\n      <b class=\"header\">length</b><code>collection.length</code>\n      <br />\n      Like an array, a Collection maintains a <tt>length</tt> property, counting\n      the number of models it contains.\n    </p>\n\n    <p id=\"Collection-comparator\">\n      <b class=\"header\">comparator</b><code>collection.comparator</code>\n      <br />\n      By default there is no <b>comparator</b> for a collection.\n      If you define a comparator, it will be used to sort the collection any\n      time a model is added.\n      A comparator can be defined as a\n      <a href=\"http://underscorejs.org/#sortBy\">sortBy</a>\n      (pass a function that takes a single argument),\n      as a\n      <a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">sort</a>\n      (pass a comparator function that expects two arguments),\n      or as a string indicating the attribute to sort by.\n    </p>\n\n    <p>\n      \"sortBy\" comparator functions take a model and return a numeric or string\n      value by which the model should be ordered relative to others.\n      \"sort\" comparator functions take two models, and return <tt>-1</tt> if\n      the first model should come before the second, <tt>0</tt> if they are of\n      the same rank and <tt>1</tt> if the first model should come after.\n      <i>Note that Backbone depends on the arity of your comparator function to\n      determine between the two styles, so be careful if your comparator function\n      is bound.</i>\n    </p>\n\n    <p>\n      Note how even though all of the chapters in this example are added backwards,\n      they come out in the proper order:\n    </p>\n\n<pre class=\"runnable\">\nvar Chapter  = Backbone.Model;\nvar chapters = new Backbone.Collection;\n\nchapters.comparator = 'page';\n\nchapters.add(new Chapter({page: 9, title: \"The End\"}));\nchapters.add(new Chapter({page: 5, title: \"The Middle\"}));\nchapters.add(new Chapter({page: 1, title: \"The Beginning\"}));\n\nalert(chapters.pluck('title'));\n</pre>\n\n    <p class=\"warning\">\n      Collections with a comparator will not automatically re-sort if you\n      later change model attributes, so you may wish to call\n      <tt>sort</tt> after changing model attributes that would affect the order.\n    </p>\n\n    <p id=\"Collection-sort\">\n      <b class=\"header\">sort</b><code>collection.sort([options])</code>\n      <br />\n      Force a collection to re-sort itself. Note that a collection with a\n      <a href=\"#Collection-comparator\">comparator</a> will sort itself\n      automatically whenever a model is added. To disable sorting when adding\n      a model, pass <tt>{sort: false}</tt> to <tt>add</tt>. Calling <b>sort</b>\n      triggers a <tt>\"sort\"</tt> event on the collection.\n    </p>\n\n    <p id=\"Collection-pluck\">\n      <b class=\"header\">pluck</b><code>collection.pluck(attribute)</code>\n      <br />\n      Pluck an attribute from each model in the collection. Equivalent to calling\n      <tt>map</tt> and returning a single attribute from the iterator.\n    </p>\n\n<pre class=\"runnable\">\nvar stooges = new Backbone.Collection([\n  {name: \"Curly\"},\n  {name: \"Larry\"},\n  {name: \"Moe\"}\n]);\n\nvar names = stooges.pluck(\"name\");\n\nalert(JSON.stringify(names));\n</pre>\n\n    <p id=\"Collection-where\">\n      <b class=\"header\">where</b><code>collection.where(attributes)</code>\n      <br />\n      Return an array of all the models in a collection that match the\n      passed <b>attributes</b>. Useful for simple cases of <tt>filter</tt>.\n    </p>\n\n<pre class=\"runnable\">\nvar friends = new Backbone.Collection([\n  {name: \"Athos\",      job: \"Musketeer\"},\n  {name: \"Porthos\",    job: \"Musketeer\"},\n  {name: \"Aramis\",     job: \"Musketeer\"},\n  {name: \"d'Artagnan\", job: \"Guard\"},\n]);\n\nvar musketeers = friends.where({job: \"Musketeer\"});\n\nalert(musketeers.length);\n</pre>\n\n    <p id=\"Collection-findWhere\">\n      <b class=\"header\">findWhere</b><code>collection.findWhere(attributes)</code>\n      <br />\n      Just like <a href=\"#Collection-where\">where</a>, but directly returns only\n      the first model in the collection that matches the passed <b>attributes</b>.\n      If no model matches returns <tt>undefined</tt>.\n    </p>\n\n    <p id=\"Collection-url\">\n      <b class=\"header\">url</b><code>collection.url or collection.url()</code>\n      <br />\n      Set the <b>url</b> property (or function) on a collection to reference\n      its location on the server. Models within the collection will use <b>url</b>\n      to construct URLs of their own.\n    </p>\n\n<pre>\nvar Notes = Backbone.Collection.extend({\n  url: '/notes'\n});\n\n// Or, something more sophisticated:\n\nvar Notes = Backbone.Collection.extend({\n  url: function() {\n    return this.document.url() + '/notes';\n  }\n});\n</pre>\n\n    <p id=\"Collection-parse\">\n      <b class=\"header\">parse</b><code>collection.parse(response, options)</code>\n      <br />\n      <b>parse</b> is called by Backbone whenever a collection's models are\n      returned by the server, in <a href=\"#Collection-fetch\">fetch</a>.\n      The function is passed the raw <tt>response</tt> object, and should return\n      the array of model attributes to be <a href=\"#Collection-add\">added</a>\n      to the collection. The default implementation is a no-op, simply passing\n      through the JSON response. Override this if you need to work with a\n      preexisting API, or better namespace your responses.\n    </p>\n\n<pre>\nvar Tweets = Backbone.Collection.extend({\n  // The Twitter Search API returns tweets under \"results\".\n  parse: function(response) {\n    return response.results;\n  }\n});\n</pre>\n\n    <p id=\"Collection-clone\">\n      <b class=\"header\">clone</b><code>collection.clone()</code>\n      <br />\n      Returns a new instance of the collection with an identical list of models.\n    </p>\n\n    <p id=\"Collection-fetch\">\n      <b class=\"header\">fetch</b><code>collection.fetch([options])</code>\n      <br />\n      Fetch the default set of models for this collection from the server,\n      <a href=\"#Collection-set\">setting</a> them on the collection when they arrive.\n      The <b>options</b> hash takes <tt>success</tt> and <tt>error</tt> callbacks\n      which will both be passed <tt>(collection, response, options)</tt> as arguments.\n      When the model data returns from the server, it uses <a href=\"#Collection-set\">set</a>\n      to (intelligently) merge the fetched models, unless you pass <tt>{reset: true}</tt>,\n      in which case the collection will be (efficiently) <a href=\"#Collection-reset\">reset</a>.\n      Delegates to <a href=\"#Sync\">Backbone.sync</a>\n      under the covers for custom persistence strategies and returns a\n      <a href=\"http://api.jquery.com/jQuery.ajax/#jqXHR\">jqXHR</a>.\n      The server handler for <b>fetch</b> requests should return a JSON array of\n      models.\n    </p>\n\n<pre class=\"runnable\">\nBackbone.sync = function(method, model) {\n  alert(method + \": \" + model.url);\n};\n\nvar accounts = new Backbone.Collection;\naccounts.url = '/accounts';\n\naccounts.fetch();\n</pre>\n\n    <p>\n      The behavior of <b>fetch</b> can be customized by using the available\n      <a href=\"#Collection-set\">set</a> options. For example, to fetch a\n      collection, getting an <tt>\"add\"</tt> event for every new model, and\n      a <tt>\"change\"</tt> event for every changed existing model, without\n      removing anything: <tt>collection.fetch({remove: false})</tt>\n    </p>\n\n    <p>\n      <b>jQuery.ajax</b> options can also be passed directly as <b>fetch</b> options,\n      so to fetch a specific page of a paginated collection:\n      <tt>Documents.fetch({data: {page: 3}})</tt>\n    </p>\n\n    <p>\n      Note that <b>fetch</b> should not be used to populate collections on\n      page load &mdash; all models needed at load time should already be\n      <a href=\"#FAQ-bootstrap\">bootstrapped</a> in to place. <b>fetch</b> is\n      intended for lazily-loading models for interfaces that are not needed\n      immediately: for example, documents with collections of notes that may be\n      toggled open and closed.\n    </p>\n\n    <p id=\"Collection-create\">\n      <b class=\"header\">create</b><code>collection.create(attributes, [options])</code>\n      <br />\n      Convenience to create a new instance of a model within a collection.\n      Equivalent to instantiating a model with a hash of attributes,\n      saving the model to the server, and adding the model to the set after being\n      successfully created. Returns the new model. If client-side validation\n      failed, the model will be unsaved, with validation errors.\n      In order for this to work, you should set the\n      <a href=\"#Collection-model\">model</a> property of the collection.\n      The <b>create</b> method can accept either an attributes hash and options to be\n      passed down during model instantiation or an existing, unsaved model object.\n    </p>\n\n    <p>\n      Creating a model will cause an immediate <tt>\"add\"</tt> event to be\n      triggered on the collection, a <tt>\"request\"</tt> event as the new model is\n      sent to the server, as well as a <tt>\"sync\"</tt> event, once the\n      server has responded with the successful creation of the model. Pass <tt>{wait: true}</tt>\n      if you'd like to wait for the server before adding the new model to the collection.\n    </p>\n\n<pre>\nvar Library = Backbone.Collection.extend({\n  model: Book\n});\n\nvar nypl = new Library;\n\nvar othello = nypl.create({\n  title: \"Othello\",\n  author: \"William Shakespeare\"\n});\n</pre>\n\n    <p id=\"Collection-mixin\">\n      <b class=\"header\">mixin</b><code>Backbone.Collection.mixin(properties)</code>\n      <br />\n      <code>mixin</code> provides a way to enhance the base <b>Backbone.Collection</b>\n      and any collections which extend it. This can be used to add generic methods\n      (e.g. additional <a href=\"#Collection-Underscore-Methods\"><b>Underscore Methods</b></a>).\n    </p>\n\n<pre>\nBackbone.Collection.mixin({\n  sum: function(models, iteratee) {\n    return _.reduce(models, function(s, m) {\n      return s + iteratee(m);\n    }, 0);\n  }\n});\n\nvar cart = new Backbone.Collection([\n  {price: 16, name: 'monopoly'},\n  {price: 5, name: 'deck of cards'},\n  {price: 20, name: 'chess'}\n]);\n\nvar cost = cart.sum('price');\n</pre>\n\n    <h2 id=\"Router\">Backbone.Router</h2>\n\n    <p>\n      Web applications often provide linkable, bookmarkable, shareable URLs for\n      important locations in the app. Until recently, hash fragments\n      (<tt>#page</tt>) were used to provide these permalinks, but with the\n      arrival of the History API, it's now possible to use standard URLs (<tt>/page</tt>).\n      <b>Backbone.Router</b> provides methods for routing client-side pages, and\n      connecting them to actions and events. For browsers which don't yet support\n      the History API, the Router handles graceful fallback and transparent\n      translation to the fragment version of the URL.\n    </p>\n\n    <p>\n      During page load, after your application has finished creating all of its routers,\n      be sure to call <tt>Backbone.history.start()</tt> or\n      <tt>Backbone.history.start({pushState: true})</tt> to route the initial URL.\n    </p>\n\n    <p id=\"Router-extend\">\n      <b class=\"header\">extend</b><code>Backbone.Router.extend(properties, [classProperties])</code>\n      <br />\n      Get started by creating a custom router class. Define action functions that are\n      triggered when certain URL fragments are\n      matched, and provide a <a href=\"#Router-routes\">routes</a> hash\n      that pairs routes to actions. Note that you'll want to avoid using a\n      leading slash in your route definitions:\n    </p>\n\n<pre>\nvar Workspace = Backbone.Router.extend({\n\n  routes: {\n    \"help\":                 \"help\",    // #help\n    \"search/:query\":        \"search\",  // #search/kiwis\n    \"search/:query/p:page\": \"search\"   // #search/kiwis/p7\n  },\n\n  help: function() {\n    ...\n  },\n\n  search: function(query, page) {\n    ...\n  }\n\n});\n</pre>\n\n    <p id=\"Router-routes\">\n      <b class=\"header\">routes</b><code>router.routes</code>\n      <br />\n      The routes hash maps URLs with parameters to functions on your router\n      (or just direct function definitions, if you prefer),\n      similar to the <a href=\"#View\">View</a>'s <a href=\"#View-delegateEvents\">events hash</a>.\n      Routes can contain parameter parts, <tt>:param</tt>, which match a single URL\n      component between slashes; and splat parts <tt>*splat</tt>, which can match\n      any number of URL components. Part of a route can be made optional by\n      surrounding it in parentheses <tt>(/:optional)</tt>.\n    </p>\n\n    <p>\n      For example, a route of <tt>\"search/:query/p:page\"</tt> will match\n      a fragment of <tt>#search/obama/p2</tt>, passing <tt>\"obama\"</tt>\n      and <tt>\"2\"</tt> to the action as positional arguments.\n    </p>\n\n    <p>\n      A route of <tt>\"file/*path\"</tt> will match\n      <tt>#file/folder/file.txt</tt>, passing\n      <tt>\"folder/file.txt\"</tt> to the action.\n    </p>\n\n    <p>\n      A route of <tt>\"docs/:section(/:subsection)\"</tt> will match\n      <tt>#docs/faq</tt> and <tt>#docs/faq/installing</tt>, passing\n      <tt>\"faq\"</tt> to the action in the first case, and passing <tt>\"faq\"</tt>\n      and <tt>\"installing\"</tt> to the action in the second.\n    </p>\n\n    <p>\n      A nested optional route of <tt>\"docs(/:section)(/:subsection)\"</tt> will match\n      <tt>#docs</tt>, <tt>#docs/faq</tt>, and <tt>#docs/faq/installing</tt>,\n      passing <tt>\"faq\"</tt> to the action in the second case, and passing <tt>\"faq\"</tt>\n      and <tt>\"installing\"</tt> to the action in the third.\n    </p>\n\n    <p>\n      Trailing slashes are treated as part of the URL, and (correctly) treated\n      as a unique route when accessed. <tt>docs</tt> and <tt>docs/</tt> will fire\n      different callbacks. If you can't avoid generating both types of URLs, you\n      can define a <tt>\"docs(/)\"</tt> matcher to capture both cases.\n    </p>\n\n    <p>\n      When the visitor presses the back button, or enters a URL, and a particular\n      route is matched, the name of the action will be fired as an\n      <a href=\"#Events\">event</a>, so that other objects can listen to the router,\n      and be notified. In the following example, visiting <tt>#help/uploading</tt>\n      will fire a <tt>route:help</tt> event from the router.\n    </p>\n\n<pre>\nroutes: {\n  \"help/:page\":         \"help\",\n  \"download/*path\":     \"download\",\n  \"folder/:name\":       \"openFolder\",\n  \"folder/:name-:mode\": \"openFolder\"\n}\n</pre>\n\n<pre>\nrouter.on(\"route:help\", function(page) {\n  ...\n});\n</pre>\n\n    <p id=\"Router-preinitialize\">\n      <b class=\"header\">preinitialize</b><code>new Backbone.Router([options])</code>\n      <br />\n      For use with routers as ES classes. If you define a <b>preinitialize</b>\n      method, it will be invoked when the Router is first created and before\n      any instantiation logic is run for the Router.\n    </p>\n\n<pre>\nclass Router extends Backbone.Router {\n  preinitialize() {\n    // Override execute method\n    this.execute = function(callback, args, name) {\n      if (!loggedIn) {\n        goToLogin();\n        return false;\n      }\n      args.push(parseQueryString(args.pop()));\n      if (callback) callback.apply(this, args);\n    }\n  }\n}\n</pre>\n\n    <p id=\"Router-constructor\">\n      <b class=\"header\">constructor / initialize</b><code>new Router([options])</code>\n      <br />\n      When creating a new router, you may pass its\n      <a href=\"#Router-routes\">routes</a> hash directly as an option, if you\n      choose. All <tt>options</tt> will also be passed to your <tt>initialize</tt>\n      function, if defined.\n    </p>\n\n    <p id=\"Router-route\">\n      <b class=\"header\">route</b><code>router.route(route, name, [callback])</code>\n      <br />\n      Manually create a route for the router, The <tt>route</tt> argument may\n      be a <a href=\"#Router-routes\">routing string</a> or regular expression.\n      Each matching capture from the route or regular expression will be passed as\n      an argument to the callback. The <tt>name</tt> argument will be triggered as\n      a <tt>\"route:name\"</tt> event whenever the route is matched.  If the\n      <tt>callback</tt> argument is omitted <tt>router[name]</tt> will be used\n      instead. Routes added later may override previously declared routes.\n    </p>\n\n<pre>\ninitialize: function(options) {\n\n  // Matches #page/10, passing \"10\"\n  this.route(\"page/:number\", \"page\", function(number){ ... });\n\n  // Matches /117-a/b/c/open, passing \"117-a/b/c\" to this.open\n  this.route(/^(.*?)\\/open$/, \"open\");\n\n},\n\nopen: function(id) { ... }\n</pre>\n\n    <p id=\"Router-navigate\">\n      <b class=\"header\">navigate</b><code>router.navigate(fragment, [options])</code>\n      <br />\n      Whenever you reach a point in your application that you'd like to save\n      as a URL, call <b>navigate</b> in order to update the URL.\n      If you also wish to call the route function, set the <b>trigger</b>\n      option to <tt>true</tt>.\n      To update the URL without creating an entry in the browser's history,\n      set the <b>replace</b> option to <tt>true</tt>.\n    </p>\n\n<pre>\nopenPage: function(pageNumber) {\n  this.document.pages.at(pageNumber).open();\n  this.navigate(\"page/\" + pageNumber);\n}\n\n# Or ...\n\napp.navigate(\"help/troubleshooting\", {trigger: true});\n\n# Or ...\n\napp.navigate(\"help/troubleshooting\", {trigger: true, replace: true});\n</pre>\n\n    <p id=\"Router-execute\">\n      <b class=\"header\">execute</b><code>router.execute(callback, args, name)</code>\n      <br />\n      This method is called internally within the router, whenever a route\n      matches and its corresponding <b>callback</b> is about to be executed.\n      Return <b>false</b> from execute to cancel the current transition.\n      Override it to perform custom parsing or wrapping of your routes, for\n      example, to parse query strings before handing them to your route\n      callback, like so:\n    </p>\n\n<pre>\nvar Router = Backbone.Router.extend({\n  execute: function(callback, args, name) {\n    if (!loggedIn) {\n      goToLogin();\n      return false;\n    }\n    args.push(parseQueryString(args.pop()));\n    if (callback) callback.apply(this, args);\n  }\n});\n</pre>\n\n    <h2 id=\"History\">Backbone.history</h2>\n\n    <p>\n      <b>History</b> serves as a global router (per frame) to handle <tt>hashchange</tt>\n      events or <tt>pushState</tt>, match the appropriate route, and trigger callbacks.\n      It forwards the <tt>\"route\"</tt> and <tt>\"route[name]\"</tt> events of the\n      matching router, or <tt>\"notfound\"</tt> when no route in any router\n      matches the current URL.\n      You shouldn't ever have to create one of these yourself since <tt>Backbone.history</tt>\n      already contains one.\n    </p>\n\n    <p>\n      <b>pushState</b> support exists on a purely opt-in basis in Backbone.\n      Older browsers that don't support <tt>pushState</tt> will continue to use\n      hash-based URL fragments, and if a hash URL is visited by a\n      <tt>pushState</tt>-capable browser, it will be transparently upgraded to\n      the true URL. Note that using real URLs requires your web server to be\n      able to correctly render those pages, so back-end changes are required\n      as well. For example, if you have a route of <tt>/documents/100</tt>,\n      your web server must be able to serve that page, if the browser\n      visits that URL directly. For full search-engine crawlability, it's best to\n      have the server generate the complete HTML for the page ... but if it's a web\n      application, just rendering the same content you would have for the root URL,\n      and filling in the rest with Backbone Views and JavaScript works fine.\n    </p>\n\n    <p id=\"History-start\">\n      <b class=\"header\">start</b><code>Backbone.history.start([options])</code>\n      <br />\n      When all of your <a href=\"#Router\">Routers</a> have been created,\n      and all of the routes are set up properly, call <tt>Backbone.history.start()</tt>\n      to begin monitoring <tt>hashchange</tt> events, and dispatching routes.\n      Subsequent calls to <tt>Backbone.history.start()</tt> will throw an error,\n      and <tt>Backbone.History.started</tt> is a boolean value indicating whether\n      it has already been called.\n    </p>\n\n    <p>\n      To indicate that you'd like to use HTML5 <tt>pushState</tt> support in\n      your application, use <tt>Backbone.history.start({pushState: true})</tt>.\n      If you'd like to use <tt>pushState</tt>, but have browsers that don't support\n      it natively use full page refreshes instead, you can add\n      <tt>{hashChange: false}</tt> to the options.\n    </p>\n\n    <p>\n      If your application is not being served from the root url <tt>/</tt> of your\n      domain, be sure to tell History where the root really is, as an option:\n      <tt>Backbone.history.start({pushState: true, root: \"/public/search/\"})</tt>.\n    </p>\n\n    <p>\n      The value provided for <tt>root</tt> will be normalized to include a leading\n      and trailing slash. When navigating to a route the default behavior is to\n      exclude the trailing slash from the URL (e.g., <tt>/public/search?query=...</tt>).\n      If you prefer to include the trailing slash (e.g., <tt>/public/search/?query=...</tt>)\n      use <tt>Backbone.history.start({trailingSlash: true})</tt>.\n      URLs will always contain a leading slash. When root is <tt>/</tt> URLs will\n      look like <tt>/?query=...</tt> regardless of the value of <tt>trailingSlash</tt>.\n    </p>\n\n    <p>\n      When called, if a route succeeds with a match for the current URL,\n      <tt>Backbone.history.start()</tt> returns <tt>true</tt> and\n      the <tt>\"route\"</tt> and <tt>\"route[name]\"</tt> events are triggered. If\n      no defined route matches the current URL, it returns <tt>false</tt>\n      and <tt>\"notfound\"</tt> is triggered instead.\n    </p>\n\n    <p>\n      If the server has already rendered the entire page, and you don't want the\n      initial route to trigger when starting History, pass <tt>silent: true</tt>.\n    </p>\n\n    <p>\n      Because hash-based history in Internet Explorer relies on an\n      <tt>&lt;iframe&gt;</tt>, be sure to call <tt>start()</tt> only after the DOM\n      is ready.\n    </p>\n\n<pre>\n$(function(){\n  new WorkspaceRouter();\n  new HelpPaneRouter();\n  Backbone.history.start({pushState: true});\n});\n</pre>\n\n    <h2 id=\"Sync\">Backbone.sync</h2>\n\n    <p>\n      <b>Backbone.sync</b> is the function that Backbone calls every time it\n      attempts to read or save a model to the server. By default, it uses\n      <tt>jQuery.ajax</tt> to make a RESTful JSON request and returns a\n      <a href=\"http://api.jquery.com/jQuery.ajax/#jqXHR\">jqXHR</a>. You can override\n      it in order to use a different persistence strategy, such as WebSockets,\n      XML transport, or Local Storage.\n    </p>\n\n    <p>\n      The method signature of <b>Backbone.sync</b> is <tt>sync(method, model, [options])</tt>\n    </p>\n\n    <ul>\n      <li><b>method</b> – the CRUD method (<tt>\"create\"</tt>, <tt>\"read\"</tt>, <tt>\"update\"</tt>, or <tt>\"delete\"</tt>)</li>\n      <li><b>model</b> – the model to be saved (or collection to be read)</li>\n      <li><b>options</b> – success and error callbacks, and all other jQuery request options</li>\n    </ul>\n\n    <p>\n      With the default implementation, when <b>Backbone.sync</b> sends up a request to save\n      a model, its attributes will be passed, serialized as JSON, and sent in the HTTP body\n      with content-type <tt>application/json</tt>. When returning a JSON response,\n      send down the attributes of the  model that have been changed by the server, and need\n      to be updated on the client. When responding to a <tt>\"read\"</tt> request from a collection\n      (<a href=\"#Collection-fetch\">Collection#fetch</a>), send down an array\n      of model attribute objects.\n    </p>\n\n    <p>\n      Whenever a model or collection begins a <b>sync</b> with the server, a\n      <tt>\"request\"</tt> event is emitted. If the request completes successfully\n      you'll get a <tt>\"sync\"</tt> event, and an <tt>\"error\"</tt> event if not.\n    </p>\n\n    <p>\n      The <b>sync</b> function may be overridden globally as <tt>Backbone.sync</tt>,\n      or at a finer-grained level, by adding a <tt>sync</tt> function to a Backbone\n      collection or to an individual model.\n    </p>\n\n    <p>\n      The default <b>sync</b> handler maps CRUD to REST like so:\n    </p>\n\n    <ul>\n      <li><b>create &rarr; POST &nbsp; </b><tt>/collection</tt></li>\n      <li><b>read &rarr; GET &nbsp; </b><tt>/collection[/id]</tt></li>\n      <li><b>update &rarr; PUT &nbsp; </b><tt>/collection/id</tt></li>\n      <li><b>patch &rarr; PATCH &nbsp; </b><tt>/collection/id</tt></li>\n      <li><b>delete &rarr; DELETE &nbsp; </b><tt>/collection/id</tt></li>\n    </ul>\n\n    <p>\n      As an example, a Rails 4 handler responding to an <tt>\"update\"</tt> call from\n      <tt>Backbone</tt> might look like this:\n    </p>\n\n<pre>\ndef update\n  account = Account.find params[:id]\n  permitted = params.require(:account).permit(:name, :otherparam)\n  account.update_attributes permitted\n  render :json => account\nend\n</pre>\n\n    <p>\n      One more tip for integrating Rails versions prior to 3.1 is to disable\n      the default namespacing for <tt>to_json</tt> calls on models by setting\n      <tt>ActiveRecord::Base.include_root_in_json = false</tt>\n    </p>\n\n    <p id=\"Sync-ajax\">\n      <b class=\"header\">ajax</b><code>Backbone.ajax = function(request) { ... };</code>\n      <br />\n      If you want to use a custom AJAX function, or your endpoint doesn't support\n      the <a href=\"http://api.jquery.com/jQuery.ajax/\">jQuery.ajax</a> API\n      and you need to tweak things, you can do so by setting <tt>Backbone.ajax</tt>.\n    </p>\n\n    <p id=\"Sync-emulateHTTP\">\n      <b class=\"header\">emulateHTTP</b><code>Backbone.emulateHTTP = true</code>\n      <br />\n      If you want to work with a legacy web server that doesn't support Backbone's\n      default REST/HTTP approach, you may choose to turn on <tt>Backbone.emulateHTTP</tt>.\n      Setting this option will fake <tt>PUT</tt>, <tt>PATCH</tt> and <tt>DELETE</tt> requests with\n      a HTTP <tt>POST</tt>, setting the <tt>X-HTTP-Method-Override</tt> header\n      with the true method. If <tt>emulateJSON</tt> is also on, the true method\n      will be passed as an additional <tt>_method</tt> parameter.\n    </p>\n\n<pre>\nBackbone.emulateHTTP = true;\n\nmodel.save();  // POST to \"/collection/id\", with \"_method=PUT\" + header.\n</pre>\n\n    <p id=\"Sync-emulateJSON\">\n      <b class=\"header\">emulateJSON</b><code>Backbone.emulateJSON = true</code>\n      <br />\n      If you're working with a legacy web server that can't handle requests\n      encoded as <tt>application/json</tt>, setting <tt>Backbone.emulateJSON = true;</tt>\n      will cause the JSON to be serialized under a <tt>model</tt> parameter, and\n      the request to be made with a <tt>application/x-www-form-urlencoded</tt>\n      MIME type, as if from an HTML form.\n    </p>\n\n    <h2 id=\"View\">Backbone.View</h2>\n\n    <p>\n      Backbone views are almost more convention than they are code &mdash; they\n      don't determine anything about your HTML or CSS for you, and can be used\n      with any JavaScript templating library.\n      The general idea is to organize your interface into logical views,\n      backed by models, each of which can be updated independently when the\n      model changes, without having to redraw the page. Instead of digging into\n      a JSON object, looking up an element in the DOM, and updating the HTML by hand,\n      you can bind your view's <tt>render</tt> function to the model's <tt>\"change\"</tt>\n      event &mdash; and now everywhere that\n      model data is displayed in the UI, it is always immediately up to date.\n    </p>\n\n    <p id=\"View-extend\">\n      <b class=\"header\">extend</b><code>Backbone.View.extend(properties, [classProperties])</code>\n      <br />\n      Get started with views by creating a custom view class. You'll want to\n      override the <a href=\"#View-render\">render</a> function, specify your\n      declarative <a href=\"#View-delegateEvents\">events</a>, and perhaps the\n      <tt>tagName</tt>, <tt>className</tt>, or <tt>id</tt> of the View's root\n      element.\n    </p>\n\n<pre>\nvar DocumentRow = Backbone.View.extend({\n\n  tagName: \"li\",\n\n  className: \"document-row\",\n\n  events: {\n    \"click .icon\":          \"open\",\n    \"click .button.edit\":   \"openEditDialog\",\n    \"click .button.delete\": \"destroy\"\n  },\n\n  initialize: function() {\n    this.listenTo(this.model, \"change\", this.render);\n  },\n\n  render: function() {\n    ...\n  }\n\n});\n</pre>\n\n    <p>\n      Properties like <tt>tagName</tt>, <tt>id</tt>, <tt>className</tt>,\n      <tt>el</tt>, and <tt>events</tt> may also be defined as a function, if\n      you want to wait to define them until runtime.\n    </p>\n\n    <p id=\"View-preinitialize\">\n      <b class=\"header\">preinitialize</b><code>new View([options])</code>\n      <br />\n      For use with views as ES classes. If you define a <b>preinitialize</b>\n      method, it will be invoked when the view is first created, before any\n      instantiation logic is run.\n    </p>\n\n<pre>\nclass Document extends Backbone.View {\n  preinitialize({autoRender}) {\n    this.autoRender = autoRender;\n  }\n\n  initialize() {\n    if (this.autoRender) {\n      this.listenTo(this.model, \"change\", this.render);\n    }\n  }\n}\n</pre>\n\n    <p id=\"View-constructor\">\n      <b class=\"header\">constructor / initialize</b><code>new View([options])</code>\n      <br />\n      There are several special\n      options that, if passed, will be attached directly to the view:\n      <tt>model</tt>, <tt>collection</tt>,\n      <tt>el</tt>, <tt>id</tt>, <tt>className</tt>, <tt>tagName</tt>, <tt>attributes</tt> and <tt>events</tt>.\n      If the view defines an <b>initialize</b> function, it will be called when\n      the view is first created. If you'd like to create a view that references\n      an element <i>already</i> in the DOM, pass in the element as an option:\n      <tt>new View({el: existingElement})</tt>\n    </p>\n\n<pre>\nvar doc = documents.first();\n\nnew DocumentRow({\n  model: doc,\n  id: \"document-row-\" + doc.id\n});\n</pre>\n\n    <p id=\"View-el\">\n      <b class=\"header\">el</b><code>view.el</code>\n      <br />\n      All views have a DOM element at all times (the <b>el</b> property),\n      whether they've already been inserted into the page or not. In this\n      fashion, views can be rendered at any time, and inserted into the DOM all\n      at once, in order to get high-performance UI rendering with as few\n      reflows and repaints as possible.\n    </p>\n\n    <p>\n      <tt>this.el</tt> can be resolved from a DOM selector string or an Element;\n      otherwise it will be created from the view's <tt>tagName</tt>, <tt>className</tt>,\n      <tt>id</tt> and <a href=\"#View-attributes\"><tt>attributes</tt></a> properties.\n      If none are set, <tt>this.el</tt> is an empty <tt>div</tt>, which is often just\n      fine. An <b>el</b> reference may also be passed in to the view's constructor.\n    </p>\n\n<pre class=\"runnable\">\nvar ItemView = Backbone.View.extend({\n  tagName: 'li'\n});\n\nvar BodyView = Backbone.View.extend({\n  el: 'body'\n});\n\nvar item = new ItemView();\nvar body = new BodyView();\n\nalert(item.el + ' ' + body.el);\n</pre>\n\n    <p id=\"View-$el\">\n      <b class=\"header\">$el</b><code>view.$el</code>\n      <br />\n      A cached jQuery object for the view's element. A handy\n      reference instead of re-wrapping the DOM element all the time.\n    </p>\n\n<pre>\nview.$el.show();\n\nlistView.$el.append(itemView.el);\n</pre>\n\n    <p id=\"View-setElement\">\n      <b class=\"header\">setElement</b><code>view.setElement(element)</code>\n      <br />\n      If you'd like to apply a Backbone view to a different DOM element, use\n      <b>setElement</b>, which will also create the cached <tt>$el</tt> reference\n      and move the view's delegated events from the old element to the new one.\n    </p>\n\n    <p id=\"View-attributes\">\n      <b class=\"header\">attributes</b><code>view.attributes</code>\n      <br />\n      A hash of attributes that will be set as HTML DOM element attributes on the\n      view's <tt>el</tt> (id, class, data-properties, etc.), or a function that\n      returns such a hash.\n    </p>\n\n    <p id=\"View-dollar\">\n      <b class=\"header\">$ (jQuery)</b><code>view.$(selector)</code>\n      <br />\n      If jQuery is included on the page, each view has a\n      <b>$</b> function that runs queries scoped within the view's element. If you use this\n      scoped jQuery function, you don't have to use model ids as part of your query\n      to pull out specific elements in a list, and can rely much more on HTML class\n      attributes. It's equivalent to running: <tt>view.$el.find(selector)</tt>\n    </p>\n\n<pre>\nui.Chapter = Backbone.View.extend({\n  serialize : function() {\n    return {\n      title: this.$(\".title\").text(),\n      start: this.$(\".start-page\").text(),\n      end:   this.$(\".end-page\").text()\n    };\n  }\n});\n</pre>\n\n    <p id=\"View-template\">\n      <b class=\"header\">template</b><code>view.template([data])</code>\n      <br />\n      While templating for a view isn't a function provided directly by Backbone,\n      it's often a nice convention to define a <b>template</b> function on your\n      views. In this way, when rendering your view, you have convenient access to\n      instance data.\n      For example, using Underscore templates:\n    </p>\n\n<pre>\nvar LibraryView = Backbone.View.extend({\n  template: _.template(...)\n});\n</pre>\n\n    <p id=\"View-render\">\n      <b class=\"header\">render</b><code>view.render()</code>\n      <br />\n      The default implementation of <b>render</b> is a no-op. Override this\n      function with your code that renders the view template from model data,\n      and updates <tt>this.el</tt> with the new HTML. A good\n      convention is to <tt>return this</tt> at the end of <b>render</b> to\n      enable chained calls.\n    </p>\n\n<pre>\nvar Bookmark = Backbone.View.extend({\n  template: _.template(...),\n  render: function() {\n    this.$el.html(this.template(this.model.attributes));\n    return this;\n  }\n});\n</pre>\n\n    <p>\n      Backbone is agnostic with respect to your preferred method of HTML templating.\n      Your <b>render</b> function could even munge together an HTML string, or use\n      <tt>document.createElement</tt> to generate a DOM tree. However, we suggest\n      choosing a nice JavaScript templating library.\n      <a href=\"http://github.com/janl/mustache.js\">Mustache.js</a>,\n      <a href=\"http://github.com/creationix/haml-js\">Haml-js</a>, and\n      <a href=\"http://github.com/sstephenson/eco\">Eco</a> are all fine alternatives.\n      Because <a href=\"http://underscorejs.org/\">Underscore.js</a> is already on the page,\n      <a href=\"http://underscorejs.org/#template\">_.template</a>\n      is available, and is an excellent choice if you prefer simple\n      interpolated-JavaScript style templates.\n    </p>\n\n    <p>\n      Whatever templating strategy you end up with, it's nice if you <i>never</i>\n      have to put strings of HTML in your JavaScript. At DocumentCloud, we\n      use <a href=\"http://documentcloud.github.com/jammit/\">Jammit</a> in order\n      to package up JavaScript templates stored in <tt>/app/views</tt> as part\n      of our main <tt>core.js</tt> asset package.\n    </p>\n\n    <p id=\"View-remove\">\n      <b class=\"header\">remove</b><code>view.remove()</code>\n      <br />\n      Removes a view and its <tt>el</tt> from the DOM, and calls\n      <a href=\"#Events-stopListening\">stopListening</a> to remove any bound\n      events that the view has <a href=\"#Events-listenTo\">listenTo</a>'d.\n    </p>\n\n    <p id=\"View-events\">\n      <b class=\"header\">events</b><code>view.events or view.events()</code>\n      <br />\n      The <b>events</b> hash (or method) can be used to specify a set of DOM\n      events that will be bound to methods on your View\n      through <a href=\"#View-delegateEvents\">delegateEvents</a>.\n    </p>\n\n    <p>\n      Backbone will automatically attach the event listeners at instantiation\n      time, right before invoking <a href=\"#View-constructor\">initialize</a>.\n    </p>\n\n<pre>\nvar ENTER_KEY = 13;\nvar InputView = Backbone.View.extend({\n\n  tagName: 'input',\n\n  events: {\n    \"keydown\" : \"keyAction\",\n  },\n\n  render: function() { ... },\n\n  keyAction: function(e) {\n    if (e.which === ENTER_KEY) {\n      this.collection.add({text: this.$el.val()});\n    }\n  }\n});\n</pre>\n\n    <p id=\"View-delegateEvents\">\n      <b class=\"header\">delegateEvents</b><code>delegateEvents([events])</code>\n      <br />\n      Uses jQuery's <tt>on</tt> function to provide declarative callbacks\n      for DOM events within a view.\n      If an <b>events</b> hash is not passed directly, uses <tt>this.events</tt>\n      as the source. Events are written in the format <tt>{\"event selector\": \"callback\"}</tt>.\n      The callback may be either the name of a method on the view, or a direct\n      function body.\n      Omitting the <tt>selector</tt> causes the event to be bound to the view's\n      root element (<tt>this.el</tt>). By default, <tt>delegateEvents</tt> is called\n      within the View's constructor for you, so if you have a simple <tt>events</tt>\n      hash, all of your DOM events will always already be connected, and you will\n      never have to call this function yourself.\n    </p>\n\n    <p>\n      The <tt>events</tt> property may also be defined as a function that returns\n      an <b>events</b> hash, to make it easier to programmatically define your\n      events, as well as inherit them from parent views.\n    </p>\n\n    <p>\n      Using <b>delegateEvents</b> provides a number of advantages over manually\n      using jQuery to bind events to child elements during <a href=\"#View-render\">render</a>. All attached\n      callbacks are bound to the view before being handed off to jQuery, so when\n      the callbacks are invoked, <tt>this</tt> continues to refer to the view object. When\n      <b>delegateEvents</b> is run again, perhaps with a different <tt>events</tt>\n      hash, all callbacks are removed and delegated afresh &mdash; useful for\n      views which need to behave differently when in different modes.\n    </p>\n\n    <p>\n      A single-event version of <b>delegateEvents</b> is available as <tt>delegate</tt>.\n      In fact, <b>delegateEvents</b> is simply a multi-event wrapper around <tt>delegate</tt>.\n      A counterpart to <tt>undelegateEvents</tt> is available as <tt>undelegate</tt>.\n    </p>\n\n    <p>\n      A view that displays a document in a search result might look\n      something like this:\n    </p>\n\n<pre>\nvar DocumentView = Backbone.View.extend({\n\n  events: {\n    \"dblclick\"                : \"open\",\n    \"click .icon.doc\"         : \"select\",\n    \"contextmenu .icon.doc\"   : \"showMenu\",\n    \"click .show_notes\"       : \"toggleNotes\",\n    \"click .title .lock\"      : \"editAccessLevel\",\n    \"mouseover .title .date\"  : \"showTooltip\"\n  },\n\n  render: function() {\n    this.$el.html(this.template(this.model.attributes));\n    return this;\n  },\n\n  open: function() {\n    window.open(this.model.get(\"viewer_url\"));\n  },\n\n  select: function() {\n    this.model.set({selected: true});\n  },\n\n  ...\n\n});\n</pre>\n\n    <p id=\"View-undelegateEvents\">\n      <b class=\"header\">undelegateEvents</b><code>undelegateEvents()</code>\n      <br />\n      Removes all of the view's delegated events. Useful if you want to disable\n      or remove a view from the DOM temporarily.\n    </p>\n\n    <h2 id=\"Utility\">Utility</h2>\n\n    <p id=\"Utility-Backbone-noConflict\">\n      <b class=\"header\">Backbone.noConflict</b><code>var backbone = Backbone.noConflict();</code>\n      <br />\n      Returns the <tt>Backbone</tt> object back to its original value. You can\n      use the return value of <tt>Backbone.noConflict()</tt> to keep a local\n      reference to Backbone. Useful for embedding Backbone on third-party\n      websites, where you don't want to clobber the existing Backbone.\n    </p>\n\n<pre>\nvar localBackbone = Backbone.noConflict();\nvar model = localBackbone.Model.extend(...);\n</pre>\n\n    <p id=\"Utility-Backbone-$\">\n      <b class=\"header\">Backbone.$</b><code>Backbone.$ = $;</code>\n      <br />\n      If you have multiple copies of <tt>jQuery</tt> on the page, or simply want\n      to tell Backbone to use a particular object as its DOM / Ajax library,\n      this is the property for you.\n    </p>\n\n<pre>\nBackbone.$ = require('jquery');\n</pre>\n\n    <p id=\"Utility-Backbone-debugInfo\">\n      <b class=\"header\">debugInfo</b><code>debugInfo();</code>\n      <br />\n      In the unfortunate event that you need to submit a\n      <a href=\"https://github.com/jashkenas/backbone/issues/new?template=Bugs.yml\">bug\n      report</a>, this function makes it easier to provide detailed information\n      about your setup. It prints a JSON object with version information about\n      Backbone and its dependencies through <tt>console.debug</tt>. It also\n      returns this object in case you want to inspect it in code.\n    </p>\n\n    <p>\n      <tt>debugInfo</tt> comes in a separate module that ships with\n      the <a href=\"#downloads\">edge version</a> and releases later than 1.5.0.\n      It is available in UMD format under the same prefix\n      as <tt>backbone.js</tt>, but with <tt>debug-info.js</tt> as the file name.\n      It is also experimentally available in ES module format\n      under <tt>backbone/modules/</tt>.\n    </p>\n\n<pre>\n  &lt;!-- browser embeds --&gt;\n  &lt;script src=\"some-path-or-url/backbone.js\"&gt;&lt;/script&gt;\n  &lt;script src=\"some-path-or-url/debug-info.js\"&gt;&lt;/script&gt;\n  &lt;script&gt;\n    Backbone.debugInfo();\n  &lt;/script&gt;\n\n  // CommonJS\n  require('backbone/debug-info.js')();\n\n  // ESM\n  import debugInfo from 'backbone/modules/debug-info.js';\n  debugInfo();\n</pre>\n\n    <h2 id=\"faq\">F.A.Q.</h2>\n\n    <p id=\"FAQ-why-backbone\">\n      <b class=\"header\">Why use Backbone, not [other framework X]?</b>\n      <br />\n      If your eye hasn't already been caught by the adaptability and elan on display\n      in the above <a href=\"#examples\">list of examples</a>, we can get more specific:\n      Backbone.js aims to provide the common foundation that data-rich web applications\n      with ambitious interfaces require &mdash; while very deliberately avoiding\n      painting you into a corner by making any decisions that you're\n      better equipped to make yourself.\n    </p>\n\n    <ul>\n      <li>\n        The focus is on supplying you with\n        <a href=\"#Collection-Underscore-Methods\">helpful methods to manipulate and\n        query your data</a>, not on HTML widgets or reinventing the JavaScript\n        object model.\n      </li>\n      <li>\n        Backbone does not force you to use a single template engine. Views can bind\n        to HTML constructed in\n        <a href=\"http://underscorejs.org/#template\">your</a>\n        <a href=\"http://guides.rubyonrails.org/layouts_and_rendering.html\">favorite</a>\n        <a href=\"http://mustache.github.com\">way</a>.\n      </li>\n      <li>\n        It's smaller. There are fewer kilobytes for your browser or phone to download,\n        and less <i>conceptual</i> surface area. You can read and understand\n        the source in an afternoon.\n      </li>\n      <li>\n        It doesn't depend on stuffing application logic into your HTML.\n        There's no embedded JavaScript, template logic, or binding hookup code in\n        <tt>data-</tt> or <tt>ng-</tt> attributes, and no need to invent your own HTML tags.\n      </li>\n      <li>\n        <a href=\"#Events\">Synchronous events</a> are used as the fundamental\n        building block, not a difficult-to-reason-about run loop, or by constantly\n        polling and traversing your data structures to hunt for changes. And if\n        you want a specific event to be asynchronous and aggregated,\n        <a href=\"http://underscorejs.org/#debounce\">no problem</a>.\n      </li>\n      <li>\n        Backbone scales well, from <a href=\"http://disqus.com\">embedded widgets</a>\n        to <a href=\"http://www.usatoday.com\">massive apps</a>.\n      </li>\n      <li>\n        Backbone is a library, not a framework, and plays well with others.\n        You can embed Backbone widgets in Dojo apps without trouble, or use Backbone\n        models as the data backing for D3 visualizations (to pick two entirely\n        random examples).\n      </li>\n      <li>\n        \"Two-way data-binding\" is avoided. While it certainly makes for a nifty\n        demo, and works for the most basic CRUD, it doesn't tend to be terribly\n        useful in your real-world app. Sometimes you want to update on\n        every keypress, sometimes on blur, sometimes when the panel is closed,\n        and sometimes when the \"save\" button is clicked. In almost all cases, simply\n        serializing the form to JSON is faster and easier. All that aside, if your\n        heart is set, <a href=\"http://rivetsjs.com\">go</a>\n        <a href=\"http://nytimes.github.com/backbone.stickit/\">for it</a>.\n      </li>\n      <li>\n        There's no built-in performance penalty for choosing to structure your\n        code with Backbone. And if you do want to optimize further, thin models and\n        templates with flexible granularity make it easy to squeeze every last\n        drop of potential performance out of, say, IE8.\n      </li>\n    </ul>\n\n    <p id=\"FAQ-tim-toady\">\n      <b class=\"header\">There's More Than One Way To Do It</b>\n      <br />\n      It's common for folks just getting started to treat the examples listed\n      on this page as some sort of gospel truth. In fact, Backbone.js is intended\n      to be fairly agnostic about many common patterns in client-side code.\n      For example...\n    </p>\n\n    <p>\n      <b>References between Models and Views</b> can be handled several ways.\n      Some people like to have direct pointers, where views correspond 1:1 with\n      models (<tt>model.view</tt> and <tt>view.model</tt>). Others prefer to have intermediate\n      \"controller\" objects that orchestrate the creation and organization of\n      views into a hierarchy. Others still prefer the evented approach, and always\n      fire events instead of calling methods directly. All of these styles work well.\n    </p>\n\n    <p>\n      <b>Batch operations</b> on Models are common, but often best handled differently\n      depending on your server-side setup. Some folks don't mind making individual\n      Ajax requests. Others create explicit resources for RESTful batch operations:\n      <tt>/notes/batch/destroy?ids=1,2,3,4</tt>. Others tunnel REST over JSON, with the\n      creation of \"changeset\" requests:\n    </p>\n\n<pre>\n  {\n    \"create\":  [array of models to create]\n    \"update\":  [array of models to update]\n    \"destroy\": [array of model ids to destroy]\n  }\n</pre>\n\n    <p>\n      <b>Feel free to define your own events.</b> <a href=\"#Events\">Backbone.Events</a>\n      is designed so that you can mix it in to any JavaScript object or prototype.\n      Since you can use any string as an event, it's often handy to bind\n      and trigger your own custom events: <tt>model.on(\"selected:true\")</tt> or\n      <tt>model.on(\"editing\")</tt>\n    </p>\n\n    <p>\n      <b>Render the UI</b> as you see fit. Backbone is agnostic as to whether you\n      use <a href=\"http://underscorejs.org/#template\">Underscore templates</a>,\n      <a href=\"https://github.com/janl/mustache.js\">Mustache.js</a>, direct DOM\n      manipulation, server-side rendered snippets of HTML, or\n      <a href=\"http://jqueryui.com/\">jQuery UI</a> in your <tt>render</tt> function.\n      Sometimes you'll create a view for each model ... sometimes you'll have a\n      view that renders thousands of models at once, in a tight loop. Both can be\n      appropriate in the same app, depending on the quantity of data involved,\n      and the complexity of the UI.\n    </p>\n\n    <p id=\"FAQ-nested\">\n      <b class=\"header\">Nested Models &amp; Collections</b>\n      <br />\n      It's common to nest collections inside of models with Backbone. For example,\n      consider a <tt>Mailbox</tt> model that contains many <tt>Message</tt> models.\n      One nice pattern for handling this is have a <tt>this.messages</tt> collection\n      for each mailbox, enabling the lazy-loading of messages, when the mailbox\n      is first opened ... perhaps with <tt>MessageList</tt> views listening for\n      <tt>\"add\"</tt> and <tt>\"remove\"</tt> events.\n    </p>\n\n<pre>\nvar Mailbox = Backbone.Model.extend({\n\n  initialize: function() {\n    this.messages = new Messages;\n    this.messages.url = '/mailbox/' + this.id + '/messages';\n    this.messages.on(\"reset\", this.updateCounts);\n  },\n\n  ...\n\n});\n\nvar inbox = new Mailbox;\n\n// And then, when the Inbox is opened:\n\ninbox.messages.fetch({reset: true});\n</pre>\n\n    <p>\n      If you're looking for something more opinionated, there are a number of\n      Backbone plugins that add sophisticated associations among models,\n      <a href=\"https://github.com/jashkenas/backbone/wiki/Extensions%2C-Plugins%2C-Resources\">available on the wiki</a>.\n    </p>\n\n    <p>\n      Backbone doesn't include direct support for nested models and collections\n      or \"has many\" associations because there are a number\n      of good patterns for modeling structured data on the client side, and\n      <i>Backbone should provide the foundation for implementing any of them.</i>\n      You may want to&hellip;\n    </p>\n\n    <ul>\n      <li>\n        Mirror an SQL database's structure, or the structure of a NoSQL database.\n      </li>\n      <li>\n        Use models with arrays of \"foreign key\" ids, and join to top level\n        collections (a-la tables).\n      </li>\n      <li>\n        For associations that are numerous, use a range of ids instead of an\n        explicit list.\n      </li>\n      <li>\n        Avoid ids, and use direct references, creating a partial object graph\n        representing your data set.\n      </li>\n      <li>\n        Lazily load joined models from the server, or lazily deserialize nested\n        models from JSON documents.\n      </li>\n    </ul>\n\n    <p id=\"FAQ-bootstrap\">\n      <b class=\"header\">Loading Bootstrapped Models</b>\n      <br />\n      When your app first loads, it's common to have a set of initial models that\n      you know you're going to need, in order to render the page. Instead of\n      firing an extra AJAX request to <a href=\"#Collection-fetch\">fetch</a> them,\n      a nicer pattern is to have their data already bootstrapped into the page.\n      You can then use <a href=\"#Collection-reset\">reset</a> to populate your\n      collections with the initial data. At DocumentCloud, in the\n      <a href=\"http://en.wikipedia.org/wiki/ERuby\">ERB</a> template for the\n      workspace, we do something along these lines:\n    </p>\n\n<pre>\n&lt;script&gt;\n  var accounts = new Backbone.Collection;\n  accounts.reset(&lt;%= @accounts.to_json %&gt;);\n  var projects = new Backbone.Collection;\n  projects.reset(&lt;%= @projects.to_json(:collaborators => true) %&gt;);\n&lt;/script&gt;\n</pre>\n\n    <p>You have to <a href=\"http://mathiasbynens.be/notes/etago\">escape</a>\n    <tt>&lt;/</tt> within the JSON string, to prevent JavaScript injection\n    attacks.\n\n    <p id=\"FAQ-extending\">\n      <b class=\"header\">Extending Backbone</b>\n      <br />\n      Many JavaScript libraries are meant to be insular and self-enclosed,\n      where you interact with them by calling their public API, but never peek\n      inside at the guts. Backbone.js is <i>not</i> that kind of library.\n    </p>\n\n    <p>\n      Because it serves as a foundation for your application, you're meant to\n      extend and enhance it in the ways you see fit &mdash; the entire source\n      code is <a href=\"docs/backbone.html\">annotated</a> to make this easier\n      for you. You'll find that there's very little there apart from core\n      functions, and most of those can be overridden or augmented should you find\n      the need. If you catch yourself adding methods to <tt>Backbone.Model.prototype</tt>,\n      or creating your own base subclass, don't worry &mdash; that's how things are\n      supposed to work.\n    </p>\n\n    <p id=\"FAQ-mvc\">\n      <b class=\"header\">How does Backbone relate to \"traditional\" MVC?</b>\n      <br />\n      Different implementations of the\n      <a href=\"http://en.wikipedia.org/wiki/Model–View–Controller\">Model-View-Controller</a>\n      pattern tend to disagree about the definition of a controller. If it helps any, in\n      Backbone, the <a href=\"#View\">View</a> class can also be thought of as a\n      kind of controller, dispatching events that originate from the UI, with\n      the HTML template serving as the true view. We call it a View because it\n      represents a logical chunk of UI, responsible for the contents of a single\n      DOM element.\n    </p>\n\n    <p>\n      Comparing the overall structure of Backbone to a server-side MVC framework\n      like <b>Rails</b>, the pieces line up like so:\n    </p>\n\n    <ul>\n      <li>\n        <b>Backbone.Model</b> &ndash; Like a Rails model minus the class\n        methods. Wraps a row of data in business logic.\n      </li>\n      <li>\n        <b>Backbone.Collection</b> &ndash; A group of models on the client-side,\n        with sorting/filtering/aggregation logic.\n      </li>\n      <li>\n        <b>Backbone.Router</b> &ndash; Rails <tt>routes.rb</tt> + Rails controller\n        actions. Maps URLs to functions.\n      </li>\n      <li>\n        <b>Backbone.View</b> &ndash; A logical, re-usable piece of UI. Often,\n        but not always, associated with a model.\n      </li>\n      <li>\n        <b>Client-side Templates</b> &ndash; Rails <tt>.html.erb</tt> views,\n        rendering a chunk of HTML.\n      </li>\n    </ul>\n\n    <p id=\"FAQ-this\">\n      <b class=\"header\">Binding \"this\"</b>\n      <br />\n      Perhaps the single most common JavaScript \"gotcha\" is the fact that when\n      you pass a function as a callback, its value for <tt>this</tt> is lost.\n      When dealing with <a href=\"#Events\">events</a> and callbacks in Backbone,\n      you'll often find it useful to rely on <a href=\"#Events-listenTo\">listenTo</a>\n      or the optional <tt>context</tt> argument that many of Underscore\n      and Backbone's methods use to specify the <tt>this</tt>\n      that will be used when the callback is later invoked. (See\n      <a href=\"http://underscorejs.org/#each\">_.each</a>,\n      <a href=\"http://underscorejs.org/#map\">_.map</a>, and\n      <a href=\"#Events-on\">object.on</a>, to name a few).\n      <a href=\"#View-delegateEvents\">View events</a> are automatically bound to\n      the view's context for you.\n      You may also find it helpful to use\n      <a href=\"http://underscorejs.org/#bind\">_.bind</a> and\n      <a href=\"http://underscorejs.org/#bindAll\">_.bindAll</a>\n      from Underscore.js.\n    </p>\n\n<pre>\nvar MessageList = Backbone.View.extend({\n\n  initialize: function() {\n    var messages = this.collection;\n    messages.on(\"reset\", this.render, this);\n    messages.on(\"add\", this.addMessage, this);\n    messages.on(\"remove\", this.removeMessage, this);\n\n    messsages.each(this.addMessage, this);\n  }\n\n});\n\n// Later, in the app...\n\nInbox.messages.add(newMessage);\n</pre>\n\n    <p id=\"FAQ-rails\">\n      <b class=\"header\">Working with Rails</b>\n      <br />\n      Backbone.js was originally extracted from\n      <a href=\"http://www.documentcloud.org\">a Rails application</a>; getting\n      your client-side (Backbone) Models to sync correctly with your server-side\n      (Rails) Models is painless, but there are still a few things to be aware of.\n    </p>\n\n    <p>\n      By default, Rails versions prior to 3.1 add an extra layer of wrapping\n      around the JSON representation of models. You can disable this wrapping\n      by setting:\n    </p>\n\n<pre>\nActiveRecord::Base.include_root_in_json = false\n</pre>\n\n    <p>\n      ... in your configuration. Otherwise, override\n      <a href=\"#Model-parse\">parse</a> to pull model attributes out of the\n      wrapper. Similarly, Backbone PUTs and POSTs direct JSON representations\n      of models, where by default Rails expects namespaced attributes. You can\n      have your controllers filter attributes directly from <tt>params</tt>, or\n      you can override <a href=\"#Model-toJSON\">toJSON</a> in Backbone to add\n      the extra wrapping Rails expects.\n    </p>\n\n    <h2 id=\"examples\">Examples</h2>\n\n    <p>\n      The list of examples that follows, while long, is not exhaustive — nor in\n      any way current. If you've worked on an app that uses Backbone, please\n      add it to the <a href=\"https://github.com/jashkenas/backbone/wiki/Projects-and-Companies-using-Backbone\">wiki page of Backbone apps</a>.\n    </p>\n\n    <p id=\"examples-todos\">\n      <a href=\"http://jgn.me/\">Jérôme Gravel-Niquet</a> has contributed a\n      <a href=\"examples/todos/index.html\">Todo List application</a>\n      that is bundled in the repository as Backbone example. If you're wondering\n      where to get started with Backbone in general, take a moment to\n      <a href=\"docs/examples/todos/todos.html\">read through the annotated source</a>. The app uses a\n      <a href=\"http://github.com/jeromegn/Backbone.localStorage\">LocalStorage adapter</a>\n      to transparently save all of your todos within your browser, instead of\n      sending them to a server. Jérôme also has a version hosted at\n      <a href=\"http://localtodos.com/\">localtodos.com</a>.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"examples/todos/index.html\">\n        <img width=\"400\" height=\"427\" data-original=\"docs/images/todos.jpg\" alt=\"Todos\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-documentcloud\">DocumentCloud</h2>\n\n    <p>\n      The <a href=\"http://www.documentcloud.org/public/#search/\">DocumentCloud workspace</a>\n      is built on Backbone.js, with <i>Documents</i>, <i>Projects</i>,\n      <i>Notes</i>, and <i>Accounts</i> all as Backbone models and collections.\n      If you're interested in history &mdash; both Underscore.js and Backbone.js\n      were originally extracted from the DocumentCloud codebase, and packaged\n      into standalone JS libraries.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.documentcloud.org/public/#search/\">\n        <img width=\"550\" height=\"453\" data-original=\"docs/images/dc-workspace.jpg\" alt=\"DocumentCloud Workspace\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-usa-today\">USA Today</h2>\n\n    <p>\n      <a href=\"http://usatoday.com\">USA Today</a> takes advantage of the modularity of\n      Backbone's data/model lifecycle &mdash; which makes it simple to create, inherit,\n      isolate, and link application objects &mdash; to keep the codebase both manageable and efficient.\n      The new website also makes heavy use of the Backbone Router to control the\n      page for both pushState-capable and legacy browsers.\n      Finally, the team took advantage of Backbone's Event module to create a\n      PubSub API that allows third parties and analytics packages to hook into the\n      heart of the app.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://usatoday.com\">\n        <img width=\"550\" height=\"532\" data-original=\"docs/images/usa-today.jpg\" alt=\"USA Today\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-rdio\">Rdio</h2>\n\n    <p>\n      <a href=\"http://rdio.com/new\">New Rdio</a> was developed from the ground\n      up with a component based framework based on Backbone.js. Every component\n      on the screen is dynamically loaded and rendered, with data provided by the\n      <a href=\"http://developer.rdio.com/\">Rdio API</a>. When changes are pushed,\n      every component can update itself without reloading the page or interrupting\n      the user's music. All of this relies on Backbone's views and models,\n      and all URL routing is handled by Backbone's Router. When data changes are\n      signaled in realtime, Backbone's Events notify the interested components\n      in the data changes. Backbone forms the core of the new, dynamic, realtime\n      Rdio web and <i>desktop</i> applications.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://rdio.com/new\">\n        <img width=\"550\" height=\"344\" data-original=\"docs/images/rdio.jpg\" alt=\"Rdio\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-hulu\">Hulu</h2>\n\n    <p>\n      <a href=\"http://hulu.com\">Hulu</a> used Backbone.js to build its next\n      generation online video experience. With Backbone as a foundation, the\n      web interface was rewritten from scratch so that all page content can\n      be loaded dynamically with smooth transitions as you navigate.\n      Backbone makes it easy to move through the app quickly without the\n      reloading of scripts and embedded videos, while also offering models and\n      collections for additional data manipulation support.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://hulu.com\">\n        <img width=\"550\" height=\"449\" data-original=\"docs/images/hulu.jpg\" alt=\"Hulu\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-quartz\">Quartz</h2>\n\n    <p>\n      <a href=\"http://qz.com\">Quartz</a> sees itself as a digitally native news\n      outlet for the new\n      global economy. Because Quartz believes in the future of open,\n      cross-platform web applications, they selected Backbone and Underscore\n      to fetch, sort, store, and display content from a custom WordPress\n      API. Although <a href=\"http://qz.com\">qz.com</a> uses responsive design\n      for phone, tablet, and\n      desktop browsers, it also takes advantage of Backbone events and views\n      to render device-specific templates in some cases.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://qz.com\">\n        <img width=\"510\" height=\"360\" data-original=\"docs/images/quartz.jpg\" alt=\"Quartz\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-earth\">Earth</h2>\n\n    <p>\n      <a href=\"http://earth.nullschool.net\">Earth.nullschool.net</a> displays real-time weather\n      conditions on an interactive animated globe, and Backbone provides the\n      foundation upon which all of the site's components are built. Despite the\n      presence of several other JavaScript libraries, Backbone's non-opinionated\n      design made it effortless to mix-in the <a href=\"#Events\">Events</a> functionality used for\n      distributing state changes throughout the page. When the decision was made\n      to switch to Backbone, large blocks of custom logic simply disappeared.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://earth.nullschool.net\">\n        <img width=\"545\" height=\"583\" data-original=\"docs/images/earth.jpg\" alt=\"Earth\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-vox\">Vox</h2>\n\n    <p>\n      Vox Media, the publisher of\n      <a href=\"http://www.sbnation.com/\">SB Nation</a>,\n      <a href=\"http://www.theverge.com/\">The Verge</a>,\n      <a href=\"http://www.polygon.com/\">Polygon</a>,\n      <a href=\"http://www.eater.com/\">Eater</a>,\n      <a href=\"http://www.racked.com/\">Racked</a>,\n      <a href=\"http://www.curbed.com/\">Curbed</a>, and\n      <a href=\"http://www.vox.com/\">Vox.com</a>, uses Backbone throughout\n      <a href=\"http://techcrunch.com/2012/05/07/a-closer-look-at-chorus-the-next-generation-publishing-platform-that-runs-vox-media/\">Chorus</a>,\n      its home-grown publishing platform. Backbone powers the\n      <a href=\"http://product.voxmedia.com/post/25113965826/introducing-syllabus-vox-medias-s3-powered-liveblog\">liveblogging platform</a>\n      and <a href=\"http://product.voxmedia.com/2013/11/11/5426878/using-backbone-js-for-sanity-and-stability\">commenting system</a>\n      used across all Vox Media properties; Coverage, an internal editorial coordination tool;\n      <a href=\"http://www.sbnation.com/college-basketball/2014/4/7/5592112/kentucky-vs-uconn-2014-ncaa-tournament-championship-live-chat\">SB Nation Live</a>,\n      a live event coverage and chat tool; and\n      <a href=\"http://www.vox.com/cards/ukraine-everything-you-need-to-know/what-is-the-ukraine-crisis\">Vox Cards</a>,\n      Vox.com's highlighter-and-index-card inspired app for providing context about the news.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://vox.com\">\n        <img width=\"550\" height=\"402\" data-original=\"docs/images/vox.jpg\" alt=\"Vox\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-gawker\">Gawker Media</h2>\n\n    <p>\n      <a href=\"http://kinja.com\">Kinja</a> is Gawker Media's publishing platform designed\n      to create great stories by breaking down the lines between the traditional\n      roles of content creators and consumers. Everyone — editors, readers,\n      marketers — have access to the same tools to engage in passionate discussion\n      and pursue the truth of the story. Sharing, recommending, and following within the\n      Kinja ecosystem allows for improved information discovery across all the sites.\n    </p>\n    <p>\n      Kinja is the platform behind\n      <a href=\"http://gawker.com/\">Gawker</a>,\n      <a href=\"http://gizmodo.com/\">Gizmodo</a>,\n      <a href=\"http://lifehacker.com/\">Lifehacker</a>,\n      <a href=\"http://io9.com/\">io9</a> and other Gawker Media\n      blogs. Backbone.js underlies the front-end application code that powers\n      everything from user authentication to post authoring, commenting, and even serving\n      ads. The JavaScript stack includes\n      <a href=\"http://underscorejs.org/\">Underscore.js</a> and\n      <a href=\"http://jquery.com/\">jQuery</a>, with some plugins,\n      all loaded with\n      <a href=\"http://requirejs.org/\">RequireJS</a>. Closure templates are shared between the\n      <a href=\"http://www.playframework.com/\">Play! Framework</a> based Scala application and Backbone views, and the responsive layout\n      is done with the\n      <a href=\"http://foundation.zurb.com/\">Foundation</a> framework using\n      <a href=\"http://sass-lang.com/\">SASS</a>.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://gawker.com\">\n        <img width=\"558\" height=\"473\" data-original=\"docs/images/gawker.jpg\" alt=\"Gawker\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-flow\">Flow</h2>\n\n    <p>\n      <a href=\"http://www.metalabdesign.com/\">MetaLab</a> used Backbone.js to create\n      <a href=\"http://www.getflow.com/\">Flow</a>, a task management app for teams. The\n      workspace relies on Backbone.js to construct task views, activities, accounts,\n      folders, projects, and tags. You can see the internals under <tt>window.Flow</tt>.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.getflow.com/\">\n        <img width=\"550\" height=\"416\" data-original=\"docs/images/flow.jpg\" alt=\"Flow\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-gilt\">Gilt Groupe</h2>\n\n    <p>\n      <a href=\"http://gilt.com\">Gilt Groupe</a> uses Backbone.js to build multiple\n      applications across their family of sites.\n      <a href=\"http://m.gilt.com\">Gilt's mobile website</a> uses Backbone and\n      <a href=\"http://zeptojs.com\">Zepto.js</a> to create a blazing-fast\n      shopping experience for users on-the-go, while\n      <a href=\"http://live.gilt.com\">Gilt Live</a> combines Backbone with\n      WebSockets to display the items that customers are buying in real-time. Gilt's search\n      functionality also uses Backbone to filter and sort products efficiently\n      by moving those actions to the client-side.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.gilt.com/\">\n        <img width=\"550\" height=\"444\" data-original=\"docs/images/gilt.jpg\" alt=\"Gilt Groupe\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-enigma\">Enigma</h2>\n\n    <p>\n      <a href=\"http://enigma.io\">Enigma</a> is a portal amassing the largest\n      collection of public data produced by governments, universities, companies,\n      and organizations. Enigma uses Backbone Models and Collections to represent\n      complex data structures; and Backbone's Router gives Enigma users unique URLs for\n      application states, allowing them to navigate quickly through the site while\n      maintaining the ability to bookmark pages and navigate forward and backward\n      through their session.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.enigma.io/\">\n        <img width=\"550\" height=\"409\" data-original=\"docs/images/enigma.jpg\" alt=\"Enigma\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-newsblur\">NewsBlur</h2>\n\n    <p>\n      <a href=\"http://www.newsblur.com\">NewsBlur</a> is an RSS feed reader and\n      social news network with a fast and responsive UI that feels like a\n      native desktop app. Backbone.js was selected for\n      <a href=\"http://www.ofbrooklyn.com/2012/11/13/backbonification-migrating-javascript-to-backbone/\">a major rewrite and transition from spaghetti code</a>\n      because of its powerful yet simple feature set, easy integration, and large\n      community. If you want to poke around under the hood, NewsBlur is also entirely\n      <a href=\"http://github.com/samuelclay/NewsBlur\">open-source</a>.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://newsblur.com\">\n        <img width=\"510\" height=\"340\" data-original=\"docs/images/newsblur.jpg\" alt=\"Newsblur\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-wordpress\">WordPress.com</h2>\n\n    <p>\n      <a href=\"http://wordpress.com/\">WordPress.com</a> is the software-as-a-service\n      version of <a href=\"http://wordpress.org\">WordPress</a>. It uses Backbone.js\n      Models, Collections, and Views in its\n      <a href=\"http://en.blog.wordpress.com/2012/05/25/notifications-refreshed/\">Notifications system</a>.  Backbone.js was selected\n      because it was easy to fit into the structure of the application, not the\n      other way around. <a href=\"http://automattic.com\">Automattic</a>\n      (the company behind WordPress.com) is integrating Backbone.js into the\n      Stats tab and other features throughout the homepage.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://wordpress.com/\">\n        <img width=\"550\" height=\"387\" data-original=\"docs/images/wpcom-notifications.jpg\" alt=\"WordPress.com Notifications\"\n    title=\"WordPress.com Notifications\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-foursquare\">Foursquare</h2>\n\n    <p>\n      Foursquare is a fun little startup that helps you meet up with friends,\n      discover new places, and save money. Backbone Models are heavily used in\n      the core JavaScript API layer and Views power many popular features like\n      the <a href=\"https://foursquare.com\">homepage map</a> and\n      <a href=\"https://foursquare.com/seriouseats/list/the-best-doughnuts-in-ny\">lists</a>.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://foursquare.com\">\n        <img width=\"550\" height=\"427\" data-original=\"docs/images/foursquare.jpg\" alt=\"Foursquare\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-bitbucket\">Bitbucket</h2>\n\n    <p>\n      <a href=\"http://www.bitbucket.org\">Bitbucket</a> is a free source code hosting\n      service for Git and Mercurial. Through its models and collections,\n      Backbone.js has proved valuable in supporting Bitbucket's\n      <a href=\"https://api.bitbucket.org\">REST API</a>, as well as newer\n      components such as in-line code comments and approvals for pull requests.\n      Mustache templates provide server and client-side rendering, while a custom\n      <a href=\"https://developers.google.com/closure/library/\">Google Closure</a>\n      inspired life-cycle for widgets allows Bitbucket to decorate existing DOM\n      trees and insert new ones.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.bitbucket.org\">\n        <img width=\"550\" height=\"356\" data-original=\"docs/images/bitbucket.jpg\" alt=\"Bitbucket\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-disqus\">Disqus</h2>\n\n    <p>\n      <a href=\"http://www.disqus.com\">Disqus</a> chose Backbone.js to power the\n      latest version of their commenting widget. Backbone&rsquo;s small\n      footprint and easy extensibility made it the right choice for Disqus&rsquo;\n      distributed web application, which is hosted entirely inside an iframe and\n      served on thousands of large web properties, including IGN, Wired, CNN, MLB, and more.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.disqus.com\">\n        <img width=\"550\" height=\"454\" data-original=\"docs/images/disqus.jpg\" alt=\"Disqus\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-delicious\">Delicious</h2>\n\n    <p>\n      <a href=\"https://delicious.com/\">Delicious</a> is a social bookmarking\n      platform making it easy to save, sort, and store bookmarks from across\n      the web. Delicious uses <a href=\"http://chaplinjs.org\">Chaplin.js</a>,\n      Backbone.js and AppCache to build a full-featured MVC web app.\n      The use of Backbone helped the website and\n      <a href=\"http://delicious.com/tools\">mobile apps</a> share a\n      single API service, and the reuse of the model tier made it significantly\n      easier to share code during the recent Delicious redesign.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.delicious.com\">\n        <img width=\"510\" height=\"321\" data-original=\"docs/images/delicious.jpg\" alt=\"Delicious\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-khan-academy\">Khan Academy</h2>\n\n    <p>\n      <a href=\"http://www.khanacademy.org\">Khan Academy</a> is on a mission to\n      provide a free world-class education to anyone anywhere. With thousands of\n      videos, hundreds of JavaScript-driven exercises, and big plans for the\n      future, Khan Academy uses Backbone to keep frontend code modular and organized.\n      User profiles and goal setting are implemented with Backbone,\n      <a href=\"http://jquery.com/\">jQuery</a> and\n      <a href=\"http://handlebarsjs.com/\">Handlebars</a>, and most new feature\n      work is being pushed to the client side, greatly increasing the quality of\n      <a href=\"https://github.com/Khan/khan-api/\">the API</a>.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.khanacademy.org\">\n        <img width=\"550\" height=\"454\" data-original=\"docs/images/khan-academy.jpg\" alt=\"Khan Academy\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-irccloud\">IRCCloud</h2>\n\n    <p>\n      <a href=\"http://irccloud.com/\">IRCCloud</a>\n      is an always-connected IRC client that you use in your\n      browser &mdash; often leaving it open all day in a tab.\n      The sleek web interface communicates with an\n      Erlang backend via websockets and the\n      <a href=\"https://github.com/irccloud/irccloud-tools/wiki/API-Overview\">IRCCloud API</a>.\n      It makes heavy use of Backbone.js events, models, views and routing to keep\n      your IRC conversations flowing in real time.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://irccloud.com/\">\n        <img width=\"550\" height=\"392\" data-original=\"docs/images/irccloud.png\" alt=\"IRCCloud\" class=\"example_image\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-pitchfork\">Pitchfork</h2>\n\n    <p>\n      <a href=\"http://pitchfork.com/\">Pitchfork</a> uses Backbone.js to power\n      its site-wide audio player, <a href=\"http://pitchfork.com/tv/\">Pitchfork.tv</a>,\n      location routing, a write-thru page fragment cache, and more. Backbone.js\n      (and <a href=\"http://underscorejs.org/\">Underscore.js</a>) helps the team\n      create clean and modular components,\n      move very quickly, and focus on the site, not the spaghetti.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://pitchfork.com/\">\n        <img width=\"550\" height=\"428\" data-original=\"docs/images/pitchfork.jpg\" alt=\"Pitchfork\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-spin\">Spin</h2>\n\n    <p>\n      <a href=\"http://spin.com/\">Spin</a> pulls in the\n      <a href=\"http://www.spin.com/news\">latest news stories</a> from\n      their internal API onto their site using Backbone models and collections, and a\n      custom <tt>sync</tt> method. Because the music should never stop playing,\n      even as you click through to different \"pages\", Spin uses a Backbone router\n      for navigation within the site.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://spin.com/\">\n        <img width=\"550\" height=\"543\" data-original=\"docs/images/spin.jpg\" alt=\"Spin\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-zocdoc\">ZocDoc</h2>\n\n    <p>\n      <a href=\"http://www.zocdoc.com\">ZocDoc</a> helps patients\n      find local, in-network doctors and dentists, see their real-time\n      availability, and instantly book appointments.\n      On the public side, the webapp uses Backbone.js to handle client-side state and rendering in\n      <a href=\"http://www.zocdoc.com/primary-care-doctors/los-angeles-13122pm\">search pages</a>\n      and <a href=\"http://www.zocdoc.com/doctor/nathan-hashimoto-md-58078\">doctor profiles</a>.\n      In addition, the new version of the doctor-facing part of the website is a\n      large single-page application that\n      benefits from Backbone's structure and modularity. ZocDoc's Backbone\n      classes are tested with\n      <a href=\"https://jasmine.github.io/\">Jasmine</a>, and delivered\n      to the end user with\n      <a href=\"http://getcassette.net/\">Cassette</a>.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.zocdoc.com\">\n        <img width=\"510\" height=\"464\" data-original=\"docs/images/zocdoc.jpg\" alt=\"ZocDoc\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-walmart\">Walmart Mobile</h2>\n\n    <p>\n      <a href=\"http://www.walmart.com/\">Walmart</a> used Backbone.js to create the new version\n      of <a href=\"http://mobile.walmart.com/\">their mobile web application</a> and\n      created two new frameworks in the process.\n      <a href=\"http://walmartlabs.github.com/thorax/\">Thorax</a> provides mixins, inheritable\n      events, as well as model and collection view bindings that integrate directly with\n      <a href=\"http://handlebarsjs.com/\">Handlebars</a> templates.\n      <a href=\"http://walmartlabs.github.com/lumbar/\">Lumbar</a> allows the application to be\n      split into modules which can be loaded on demand, and creates platform specific builds\n      for the portions of the web application that are embedded in Walmart's native Android\n      and iOS applications.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://mobile.walmart.com/r/phoenix\">\n        <img width=\"256\" height=\"534\" data-original=\"docs/images/walmart-mobile.png\" alt=\"Walmart Mobile\" class=\"example_image\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-groupon\">Groupon Now!</h2>\n\n    <p>\n      <a href=\"http://www.groupon.com/now\">Groupon Now!</a> helps you find\n      local deals that you can buy and use right now. When first developing\n      the product, the team decided it would be AJAX heavy with smooth transitions\n      between sections instead of full refreshes, but still needed to be fully\n      linkable and shareable. Despite never having used Backbone before, the\n      learning curve was incredibly quick &mdash; a prototype was hacked out in an\n      afternoon, and the team was able to ship the product in two weeks.\n      Because the source is minimal and understandable, it was easy to\n      add several Backbone extensions for Groupon Now!: changing the router\n      to handle URLs with querystring parameters, and adding a simple\n      in-memory store for caching repeated requests for the same data.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.groupon.com/now\">\n        <img width=\"550\" height=\"466\" data-original=\"docs/images/groupon.jpg\" alt=\"Groupon Now!\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-basecamp\">Basecamp</h2>\n\n    <p>\n      <a href=\"http://37signals.com/\">37Signals</a> chose Backbone.js to create\n      the <a href=\"http://basecamp.com/calendar\">calendar feature</a> of its\n      popular project management software <a href=\"http://basecamp.com/\">Basecamp</a>.\n      The Basecamp Calendar uses Backbone.js models and views in conjunction with the\n      <a href=\"https://github.com/sstephenson/eco\">Eco</a> templating system to\n      present a polished, highly interactive group scheduling interface.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://basecamp.com/calendar\">\n        <img width=\"530\" height=\"380\" data-original=\"docs/images/basecamp-calendar.jpg\" alt=\"Basecamp Calendar\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-slavery-footprint\">Slavery Footprint</h2>\n\n    <p>\n      <a href=\"http://slaveryfootprint.org/survey\">Slavery Footprint</a>\n      allows consumers to visualize how their consumption habits are\n      connected to modern-day slavery and provides them with an opportunity\n      to have a deeper conversation with the companies that manufacture the\n      goods they purchased.\n      Based in Oakland, California, the Slavery Footprint team works to engage\n      individuals, groups, and businesses to build awareness for and create\n      deployable action against forced labor, human trafficking, and modern-day\n      slavery through online tools, as well as off-line community education and\n      mobilization programs.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://slaveryfootprint.org/survey\">\n        <img width=\"550\" height=\"394\" data-original=\"docs/images/slavery-footprint.jpg\" alt=\"Slavery Footprint\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-stripe\">Stripe</h2>\n\n    <p>\n      <a href=\"https://stripe.com\">Stripe</a> provides an API for accepting\n      credit cards on the web. Stripe's\n      <a href=\"https://manage.stripe.com\">management interface</a> was recently\n      rewritten from scratch in CoffeeScript using Backbone.js as the primary\n      framework, <a href=\"https://github.com/sstephenson/eco\">Eco</a> for templates, <a href=\"http://sass-lang.com/\">Sass</a> for stylesheets, and <a href=\"https://github.com/sstephenson/stitch\">Stitch</a> to package\n      everything together as <a href=\"http://commonjs.org/\">CommonJS</a> modules. The new app uses\n      <a href=\"https://stripe.com/docs/api\">Stripe's API</a> directly for the\n      majority of its actions; Backbone.js models made it simple to map\n      client-side models to their corresponding RESTful resources.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"https://stripe.com\">\n        <img width=\"555\" height=\"372\" data-original=\"docs/images/stripe.png\" alt=\"Stripe\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-airbnb\">Airbnb</h2>\n\n    <p>\n      <a href=\"http://airbnb.com\">Airbnb</a> uses Backbone in many of its products.\n      It started with <a href=\"http://m.airbnb.com\">Airbnb Mobile Web</a>\n      (built in six weeks by a team of three) and has since grown to\n      <a href=\"https://www.airbnb.com/wishlists/popular\">Wish Lists</a>,\n      <a href=\"http://www.airbnb.com/match\">Match</a>,\n      <a href=\"http://www.airbnb.com/s/\">Search</a>, Communities, Payments, and\n      Internal Tools.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://m.airbnb.com/\">\n        <img width=\"500\" height=\"489\" data-original=\"docs/images/airbnb.png\" alt=\"Airbnb\" class=\"example_image\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-soundcloud\">SoundCloud Mobile</h2>\n\n    <p>\n      <a href=\"http://soundcloud.com\">SoundCloud</a> is the leading sound sharing\n      platform on the internet, and Backbone.js provides the foundation for\n      <a href=\"http://m.soundcloud.com\">SoundCloud Mobile</a>. The project uses\n      the public SoundCloud <a href=\"http://soundcloud.com/developers\">API</a>\n      as a data source (channeled through a nginx proxy),\n      <a href=\"https://github.com/BorisMoore/jquery-tmpl\">jQuery templates</a>\n      for the rendering, <a href=\"http://docs.jquery.com/Qunit\">Qunit\n      </a> and <a href=\"http://www.phantomjs.org/\">PhantomJS</a> for\n      the testing suite. The JS code, templates and CSS are built for the\n      production deployment with various Node.js tools like\n      <a href=\"https://github.com/dsimard/ready.js\">ready.js</a>,\n      <a href=\"https://github.com/mde/jake\">Jake</a>,\n      <a href=\"https://github.com/tmpvar/jsdom\">jsdom</a>.\n      The <b>Backbone.History</b> was modified to support the HTML5 <tt>history.pushState</tt>.\n      <b>Backbone.sync</b> was extended with an additional SessionStorage based cache\n      layer.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://m.soundcloud.com\">\n        <img width=\"266\" height=\"555\" data-original=\"docs/images/soundcloud.png\" alt=\"SoundCloud\" class=\"example_image\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-artsy\">Art.sy</h2>\n\n    <p>\n      <a href=\"http://artsy.net\">Art.sy</a> is a place to discover art you'll\n      love. Art.sy is built on Rails, using\n      <a href=\"https://github.com/intridea/grape\">Grape</a> to serve a robust\n      <a href=\"http://artsy.net/api\">JSON API</a>. The main site is a single page\n      app written in CoffeeScript and uses Backbone to provide structure around\n      this API. An admin panel and partner CMS have also been extracted into\n      their own API-consuming Backbone projects.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://artsy.net\">\n        <img width=\"550\" height=\"550\" data-original=\"docs/images/artsy.jpg\" alt=\"Art.sy\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-pandora\">Pandora</h2>\n\n    <p>\n      When <a href=\"http://www.pandora.com/newpandora\">Pandora</a> redesigned\n      their site in HTML5, they chose Backbone.js to help\n      manage the user interface and interactions. For example, there's a model\n      that represents the \"currently playing track\", and multiple views that\n      automatically update when the current track changes. The station list is a\n      collection, so that when stations are added or changed, the UI stays up to date.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.pandora.com/newpandora\">\n        <img width=\"476\" height=\"359\" data-original=\"docs/images/pandora.jpg\" alt=\"Pandora\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-inkling\">Inkling</h2>\n\n    <p>\n      <a href=\"http://inkling.com/\">Inkling</a> is a cross-platform way to\n      publish interactive learning content.\n      <a href=\"https://www.inkling.com/read/\">Inkling for Web</a> uses Backbone.js\n      to make hundreds of complex books — from student textbooks to travel guides and\n      programming manuals — engaging and accessible on the web. Inkling supports\n      WebGL-enabled 3D graphics, interactive assessments, social sharing,\n      and a system for running practice code right\n      in the book, all within a single page Backbone-driven app. Early on, the\n      team decided to keep the site lightweight by using only Backbone.js and\n      raw JavaScript. The result? Complete source code weighing in at a mere\n      350kb with feature-parity across the iPad, iPhone and web clients.\n      Give it a try with\n      <a href=\"https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-4/function-definition-expressions\">this excerpt from JavaScript: The Definitive Guide</a>.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://inkling.com\">\n        <img width=\"550\" height=\"361\" data-original=\"docs/images/inkling.jpg\" alt=\"Inkling\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-code-school\">Code School</h2>\n\n    <p>\n      <a href=\"http://www.codeschool.com\">Code School</a> courses teach people\n      about various programming topics like <a href=\"http://coffeescript.org\">CoffeeScript</a>, CSS, Ruby on Rails,\n      and more. The new Code School course\n      <a href=\"http://coffeescript.codeschool.com/levels/1/challenges/1\">challenge page</a>\n      is built from the ground up on Backbone.js, using\n      everything it has to offer: the router, collections, models, and complex\n      event handling. Before, the page was a mess of <a href=\"http://jquery.com/\">jQuery</a> DOM manipulation\n      and manual Ajax calls. Backbone.js helped introduce a new way to\n      think about developing an organized front-end application in JavaScript.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.codeschool.com\">\n        <img width=\"550\" height=\"482\" data-original=\"docs/images/code-school.jpg\" alt=\"Code School\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-cloudapp\">CloudApp</h2>\n\n    <p>\n      <a href=\"http://getcloudapp.com\">CloudApp</a> is simple file and link\n      sharing for the Mac. Backbone.js powers the web tools\n      which consume the <a href=\"http://developer.getcloudapp.com\">documented API</a>\n      to manage Drops. Data is either pulled manually or pushed by\n      <a href=\"http://pusher.com\">Pusher</a> and fed to\n      <a href=\"http://github.com/janl/mustache.js\">Mustache</a> templates for\n      rendering. Check out the <a href=\"http://cloudapp.github.com/engine\">annotated source code</a>\n      to see the magic.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://getcloudapp.com\">\n        <img width=\"550\" height=\"426\" data-original=\"docs/images/cloudapp.jpg\" alt=\"CloudApp\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-seatgeek\">SeatGeek</h2>\n\n    <p>\n      <a href=\"http://seatgeek.com\">SeatGeek</a>'s stadium ticket maps were originally\n      developed with <a href=\"http://prototypejs.org/\">Prototype.js</a>. Moving to Backbone.js and <a href=\"http://jquery.com/\">jQuery</a> helped organize\n      a lot of the UI code, and the increased structure has made adding features\n      a lot easier. SeatGeek is also in the process of building a mobile\n      interface that will be Backbone.js from top to bottom.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://seatgeek.com\">\n        <img width=\"550\" height=\"455\" data-original=\"docs/images/seatgeek.jpg\" alt=\"SeatGeek\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-easel\">Easel</h2>\n\n    <p>\n      <a href=\"http://easel.io\">Easel</a> is an in-browser, high fidelity web\n      design tool that integrates with your design and development\n      process. The Easel team uses CoffeeScript, Underscore.js and Backbone.js for\n      their <a href=\"http://easel.io/demo\">rich visual editor</a> as well as other\n      management functions throughout the site. The structure of Backbone allowed\n      the team to break the complex problem of building a visual editor into\n      manageable components and still move quickly.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://easel.io\">\n        <img width=\"550\" height=\"395\" data-original=\"docs/images/easel.jpg\" alt=\"Easel\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-jolicloud\">Jolicloud</h2>\n\n    <p>\n      <a href=\"http://www.jolicloud.com/\">Jolicloud</a> is an open and independent\n      platform and <a href=\"http://www.jolicloud.com/jolios\">operating system</a>\n      that provides music playback, video streaming, photo browsing and\n      document editing &mdash; transforming low cost computers into beautiful cloud devices.\n      The <a href=\"https://my.jolicloud.com/\">new Jolicloud HTML5 app</a> was built\n      from the ground up using Backbone and talks to the\n      <a href=\"http://developers.jolicloud.com\">Jolicloud Platform</a>, which is\n      based on Node.js. Jolicloud works offline using the HTML5 AppCache, extends\n      Backbone.sync to store data in IndexedDB or localStorage, and communicates\n      with the <a href=\"http://www.jolicloud.com/jolios\">Joli OS</a> via WebSockets.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://jolicloud.com/\">\n        <img width=\"510\" height=\"384\" data-original=\"docs/images/jolicloud.jpg\" alt=\"Jolicloud\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-salon\">Salon.io</h2>\n\n    <p>\n      <a href=\"http://salon.io\">Salon.io</a> provides a space where photographers,\n      artists and designers freely arrange their visual art on virtual walls.\n      <a href=\"http://salon.io\">Salon.io</a> runs on <a href=\"http://rubyonrails.org/\">Rails</a>, but does not use\n      much of the traditional stack, as the entire frontend is designed as a\n      single page web app, using Backbone.js, <a href=\"http://brunch.io/\">Brunch</a> and\n      <a href=\"http://coffeescript.org\">CoffeeScript</a>.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://salon.io\">\n        <img width=\"550\" height=\"483\" data-original=\"docs/images/salon.jpg\" alt=\"Salon.io\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-tilemill\">TileMill</h2>\n\n    <p>\n      Our fellow\n      <a href=\"http://www.newschallenge.org/\">Knight Foundation News Challenge</a>\n      winners, <a href=\"http://mapbox.com/\">MapBox</a>, created an open-source\n      map design studio with Backbone.js:\n      <a href=\"https://www.mapbox.com/tilemill/\">TileMill</a>.\n      TileMill lets you manage map layers based on shapefiles and rasters, and\n      edit their appearance directly in the browser with the\n      <a href=\"https://github.com/mapbox/carto\">Carto styling language</a>.\n      Note that the gorgeous <a href=\"http://mapbox.com/\">MapBox</a> homepage\n      is also a Backbone.js app.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"https://www.mapbox.com/tilemill/\">\n        <img width=\"544\" height=\"375\" data-original=\"docs/images/tilemill.jpg\" alt=\"TileMill\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-blossom\">Blossom</h2>\n\n    <p>\n      <a href=\"http://blossom.io\">Blossom</a> is a lightweight project management\n      tool for lean teams. Backbone.js is heavily used in combination with\n      <a href=\"http://coffeescript.org\">CoffeeScript</a> to provide a smooth\n      interaction experience. The app is packaged with <a href=\"http://brunch.io\">Brunch</a>.\n      The RESTful backend is built with <a href=\"http://flask.pocoo.org/\">Flask</a> on Google App Engine.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://blossom.io\">\n        <img width=\"550\" height=\"367\" data-original=\"docs/images/blossom.jpg\" alt=\"Blossom\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-trello\">Trello</h2>\n\n    <p>\n      <a href=\"http://trello.com\">Trello</a> is a collaboration tool that\n      organizes your projects into boards. A Trello board holds many lists of\n      cards, which can contain checklists, files and conversations, and may be\n      voted on and organized with labels. Updates on the board happen in\n      real time. The site was built ground up using Backbone.js for all the\n      models, views, and routes.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://trello.com\">\n        <img width=\"550\" height=\"416\" data-original=\"docs/images/trello.jpg\" alt=\"Trello\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"examples-tzigla\">Tzigla</h2>\n\n    <p>\n      <a href=\"http://twitter.com/evilchelu\">Cristi Balan</a> and\n      <a href=\"http://dira.ro\">Irina Dumitrascu</a> created\n      <a href=\"http://tzigla.com\">Tzigla</a>, a collaborative drawing\n      application where artists make tiles that connect to each other to\n      create <a href=\"http://tzigla.com/boards/1\">surreal drawings</a>.\n      Backbone models help organize the code, routers provide\n      <a href=\"http://tzigla.com/boards/1#!/tiles/2-2\">bookmarkable deep links</a>,\n      and the views are rendered with\n      <a href=\"https://github.com/creationix/haml-js\">haml.js</a> and\n      <a href=\"http://zeptojs.com/\">Zepto</a>.\n      Tzigla is written in Ruby (<a href=\"http://rubyonrails.org/\">Rails</a>) on the backend, and\n      <a href=\"http://coffeescript.org\">CoffeeScript</a> on the frontend, with\n      <a href=\"http://documentcloud.github.com/jammit/\">Jammit</a>\n      prepackaging the static assets.\n    </p>\n\n    <div style=\"text-align: center;\">\n      <a href=\"http://www.tzigla.com/\">\n        <img width=\"550\" height=\"376\" data-original=\"docs/images/tzigla.jpg\" alt=\"Tzigla\" class=\"example_retina\" />\n      </a>\n    </div>\n\n    <h2 id=\"changelog\">Change Log</h2>\n\n    <b class=\"header\" id=\"1.6.1\">1.6.1</b> &mdash; <small><i>Apr. 1, 2025</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.6.0...1.6.1\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.6.1/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Fixed a bug where the <tt>changeId</tt> event would sometimes fire even\n        though the id of a model did not change.\n      </li>\n      <li>\n        Several small changes in the test infrastructure.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.6.0\">1.6.0</b> &mdash; <small><i>Feb. 5, 2024</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.5.0...1.6.0\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.6.0/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Added a <tt>notfound</tt> event to <tt>Backbone.history</tt> for when no\n        router matches the current URL.\n      </li>\n      <li>\n        Added the <tt>debugInfo</tt> function to make bug reports easier.\n      </li>\n      <li>\n        Fixed a corner case where a collection would forward <tt>error</tt> events twice if the model was first added through the <tt>create</tt> method with <tt>wait: true</tt>.\n      </li>\n      <li>\n        Added issue templates and other documentation improvements.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.5.0\">1.5.0</b> &mdash; <small><i>Jul. 28, 2023</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.4.1...1.5.0\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.5.0/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Added a <tt>trailingSlash</tt> option to the\n        <tt>Backbone.history.start</tt> method. When this option is\n        <tt>true</tt>, the trailing slash of the <tt>root</tt> is always\n        retained in the route, even if the path segment of the current URL is\n        empty.\n      </li>\n      <li>\n        Fixed a bug that caused collection <tt>add</tt> events to include an\n        irrelevant <tt>options.index</tt> if other models were removed during\n        the same call to <tt>Collection.set</tt>.\n      </li>\n      <li>\n        Fixed a corner case where a collection would not forward\n        the <tt>error</tt> event if <tt>Collection.create</tt> was invoked\n        with <tt>{wait: true}</tt>.\n      </li>\n      <li>\n        Adapted CoffeeScript Model test to CoffeeScript version 2.\n      </li>\n      <li>\n        Added a security policy and a code of conduct.\n      </li>\n      <li>\n        Added a <tt>.editorconfig</tt> to the project root in order to promote\n        consistent whitespace handling across editors.\n      </li>\n      <li>\n        Many clarifications, corrections and refinements to the documentation,\n        as well as some code comments.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.4.1\">1.4.1</b> &mdash; <small><i>Feb. 26, 2022</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.4.0...1.4.1\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.4.1/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Improved support for polymorphic collections in which two or more model\n        types might have different <tt>idAttribute</tt>s.\n        <tt>Collection.modelId()</tt> overrides can now exploit the fact that\n        internal methods pass the <tt>idAttribute</tt> as a second argument to\n        <tt>modelId</tt>.\n      </li>\n      <li>\n        Fixed a temporary inconsistency in a collection's internal\n        administration during model <tt>change</tt> events. Models (and by\n        extension, collections) now emit a specialized <tt>changeId</tt> event\n        when the id changes.\n      </li>\n      <li>\n        Fixed an issue where an ES6 class or object method could not be used as\n        the <tt>model</tt> for a collection due to the lack of a\n        <tt>prototype</tt>.\n      </li>\n      <li>\n        Restored continuous integration using GitHub Actions and cross-browser\n        testing using Sauce Labs.\n      </li>\n      <li>\n        Several improvements to the online documentation.\n      </li>\n      <li>\n        Due to upgraded development tools, the annotated sources of the example\n        code as well as the sourcemap of the minified bundle have changed\n        filenames. Aliases and redirects in the old locations are kept for\n        backwards compatibility.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.4.0\">1.4.0</b> &mdash; <small><i>Feb. 19, 2019</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.3.3...1.4.0\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.4.0/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Collections now support the <a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols\">Javascript Iterator Protocol!</a>\n      </li>\n      <li>\n        <tt>listenTo</tt> uses the listened object's public <tt>on</tt> method.\n        This helps maintain interoperability between Backbone and other event\n        libraries (including Node.js).\n      </li>\n      <li>\n        Added support for setting instance properties before the constructor in\n        <tt>ES2015 classes</tt> with a <tt>preinitialize</tt> method.\n      </li>\n      <li>\n        <tt>Collection.get</tt> now checks if obj is a <tt>Model</tt> to allow\n        retrieving models with an `attributes` key.\n      </li>\n      <li>\n        Fixed several issues with Router's URL hashing and parsing.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.3.3\">1.3.3</b> &mdash; <small><i>Apr. 5, 2016</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.2.3...1.3.3\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.3.3/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Added <tt>findIndex</tt> and <tt>findLastIndex</tt> Underscore methods to\n        <tt>Collection</tt>.\n      </li>\n      <li>\n        Added <tt>options.changes</tt> to <tt>Collection</tt> \"update\" event which\n        includes added, merged, and removed models.\n      </li>\n      <li>\n        Added support for <tt>Collection#mixin</tt> and <tt>Model#mixin</tt>.\n      </li>\n      <li>\n        Ensured <tt>Collection#reduce</tt> and <tt>Collection#reduceRight</tt>\n        work without an initial <tt>accumulator</tt> value.\n      </li>\n      <li>\n        Ensured <tt>Collection#_removeModels</tt> always returns an array.\n      </li>\n      <li>\n        Fixed a bug where <tt>Events.once</tt> with object syntax failed to bind\n        context.\n      </li>\n      <li>\n        Fixed <tt>Collection#_onModelEvent</tt> regression where triggering a\n        <tt>change</tt> event without a <tt>model</tt> would error.\n      </li>\n      <li>\n        Fixed <tt>Collection#set</tt> regression when <tt>parse</tt> returns a\n        falsy value.\n      </li>\n      <li>\n        Fixed <tt>Model#id</tt> regression where <tt>id</tt> would be\n        unintentionally <tt>undefined</tt>.\n      </li>\n      <li>\n        Fixed <tt>_removeModels</tt> regression which could cause an infinite loop\n        under certain conditions.\n      </li>\n      <li>\n        Removed <tt>component</tt> package support.\n      </li>\n      <li>\n        Note that 1.3.3 fixes several bugs in versions 1.3.0 to 1.3.2. Please upgrade\n        immediately if you are on one of those versions.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.2.3\">1.2.3</b> &mdash; <small><i>Sept. 3, 2015</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.2.2...1.2.3\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.2.3/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Fixed a minor regression in 1.2.2 that would cause an error when adding\n        a model to a collection <tt>at</tt> an out of bounds index.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.2.2\">1.2.2</b> &mdash; <small><i>Aug. 19, 2015</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.2.1...1.2.2\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.2.2/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Collection methods <tt>find</tt>, <tt>filter</tt>, <tt>reject</tt>, <tt>every</tt>,\n        <tt>some</tt>, and <tt>partition</tt> can now take a model-attributes-style predicate:\n        <tt>this.collection.reject({user: 'guybrush'})</tt>.\n      </li>\n      <li>\n        Backbone Events once again supports multiple-event maps\n        (<tt>obj.on({'error change': action})</tt>). This was a previously\n        undocumented feature inadvertently removed in 1.2.0.\n      </li>\n      <li>\n        Added <tt>Collection#includes</tt> as an alias of <tt>Collection#contains</tt>\n        and as a replacement for <tt>Collection#include</tt> in Underscore.js >= 1.8.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.2.1\">1.2.1</b> &mdash; <small><i>Jun. 4, 2015</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.2.0...1.2.1\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.2.1/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        <tt>Collection#add</tt> now avoids trying to parse a model instance when passed <tt>parse: false</tt>.\n      </li>\n      <li>\n        Bug fix in <tt>Collection#remove</tt>. The removed models are now actually returned.\n      </li>\n      <li>\n        <tt>Model#fetch</tt> no longer parses the response when passing <tt>parse: false</tt>.\n      </li>\n      <li>\n        Bug fix for iframe-based History when used with JSDOM.\n      </li>\n      <li>\n        Bug fix where <tt>Collection#invoke</tt> was not taking additional arguments.\n      </li>\n      <li>\n        When using <tt>on</tt> with an event map, you can now pass the context as the\n        second argument. This was a previously undocumented feature inadvertently\n        removed in 1.2.0.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.2.0\">1.2.0</b> &mdash; <small><i>May 13, 2015</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.1.2...1.2.0\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.2.0/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Added new hooks to Views to allow them to work without jQuery. See the\n        <a href=\"https://github.com/jashkenas/backbone/wiki/Using-Backbone-without-jQuery\">wiki page</a>\n        for more info.\n      </li>\n      <li>\n        As a neat side effect, Backbone.History no longer uses jQuery's\n        event methods for <tt>pushState</tt> and <tt>hashChange</tt> listeners.\n        We're native all the way.\n      </li>\n      <li>\n        Also on the subject of jQuery, if you're using Backbone with CommonJS (node, browserify, webpack)\n        Backbone will automatically try to load jQuery for you.\n      </li>\n      <li>\n        Views now always delegate their events in <a href=\"#View-setElement\">setElement</a>.\n        You can no longer modify the events hash or your view's <tt>el</tt> property in\n        <tt>initialize</tt>.\n      </li>\n      <li>\n        Added an <tt>\"update\"</tt> event that triggers after any amount of\n        models are added or removed from a collection. Handy to re-render lists\n        of things without debouncing.\n      </li>\n      <li>\n        <tt>Collection#at</tt> can take a negative index.\n      </li>\n      <li>\n        Added <tt>modelId</tt> to Collection for generating unique ids on\n        polymorphic collections. Handy for cases when your model ids would\n        otherwise collide.\n      </li>\n      <li>\n        Added an overridable <tt>_isModel</tt> for more advanced\n        control of what's considered a model by your Collection.\n      </li>\n      <li>\n        The <tt>success</tt> callback passed to <tt>Model#destroy</tt> is always\n        called asynchronously now.\n      </li>\n      <li>\n        <tt>Router#execute</tt> passes back the route name as its third argument.\n      </li>\n      <li>\n        Cancel the current Router transition by returning <tt>false</tt> in\n        <tt>Router#execute</tt>. Great for checking logged-in status or other\n        prerequisites.\n      </li>\n      <li>\n        Added <tt>getSearch</tt> and <tt>getPath</tt> methods to Backbone.History as\n        cross-browser and overridable ways of slicing up the URL.\n      </li>\n      <li>\n        Added <tt>delegate</tt> and <tt>undelegate</tt> as finer-grained versions\n        of <tt>delegateEvents</tt> and <tt>undelegateEvents</tt>. Useful for plugin\n        authors to use a consistent events interface in Backbone.\n      </li>\n      <li>\n        A collection will only fire a \"sort\" event if its order was actually\n        updated, not on every <tt>set</tt>.\n      </li>\n      <li>\n        Any passed <tt>options.attrs</tt> are now respected when saving a model with\n        <tt>patch: true</tt>.\n      </li>\n      <li>\n        <tt>Collection#clone</tt> now sets the <tt>model</tt> and <tt>comparator</tt>\n        functions of the cloned collection to the new one.\n      </li>\n      <li>\n        Adding models to your Collection when specifying an <tt>at</tt> position\n        now sends the actual position of your model in the <tt>add</tt>\n        event, not just the one you've passed in.\n      </li>\n      <li>\n        <tt>Collection#remove</tt> will now only return a list of models that\n        have actually been removed from the collection.\n      </li>\n      <li>\n        Fixed loading Backbone.js in strict ES2015 module loaders.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.1.2\">1.1.2</b> &mdash; <small><i>Feb. 20, 2014</i></small>\n    &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.1.1...1.1.2\">Diff</a>\n    &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.1.2/index.html\">Docs</a>\n    <br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Backbone no longer tries to require jQuery in Node/CommonJS environments,\n        for better compatibility with folks using Browserify.\n        If you'd like to have Backbone use jQuery from Node, assign it like so:\n        <tt>Backbone.$ = require('jquery');</tt>\n      </li>\n      <li>\n        Bugfix for route parameters with newlines in them.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.1.1\">1.1.1</b> &mdash; <small><i>Feb. 13, 2014</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.1.0...1.1.1\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.1.1/index.html\">Docs</a><br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Backbone now registers itself for AMD (Require.js), Bower and Component,\n        as well as being a CommonJS module and a regular (Java)Script. Whew.\n      </li>\n      <li>\n        Added an <tt>execute</tt> hook to the Router, which allows you to hook\n        in and custom-parse route arguments, like query strings, for example.\n      </li>\n      <li>\n        Performance fine-tuning for Backbone Events.\n      </li>\n      <li>\n        Better matching for Unicode in routes, in old browsers.\n      </li>\n      <li>\n        Backbone Routers now handle query params in route fragments, passing\n        them into the handler as the last argument.  Routes specified as\n        strings should no longer include the query string\n        (<tt>'foo?:query'</tt> should be <tt>'foo'</tt>).\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.1.0\">1.1.0</b> &mdash; <small><i>Oct. 10, 2013</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/1.0.0...1.1.0\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.1.0/index.html\">Docs</a><br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Made the return values of Collection's <tt>set</tt>, <tt>add</tt>,\n        <tt>remove</tt>, and <tt>reset</tt> more useful. Instead of returning\n        <tt>this</tt>, they now return the changed (added, removed or updated)\n        model or list of models.\n      </li>\n      <li>\n        Backbone Views no longer automatically attach options passed to the constructor as\n        <tt>this.options</tt> and Backbone Models no longer attach <tt>url</tt> and\n        <tt>urlRoot</tt> options, but you can do it yourself if you prefer.\n      </li>\n      <li>\n        All <tt>\"invalid\"</tt> events now pass consistent arguments. First the\n        model in question, then the error object, then options.\n      </li>\n      <li>\n        You are no longer permitted to change the <b>id</b> of your model during\n        <tt>parse</tt>. Use <tt>idAttribute</tt> instead.\n      </li>\n      <li>\n        On the other hand, <tt>parse</tt> is now an excellent place to extract\n        and vivify incoming nested JSON into associated submodels.\n      </li>\n      <li>\n        Many tweaks, optimizations and bugfixes relating to Backbone 1.0,\n        including URL overrides, mutation of options, bulk ordering, trailing\n        slashes, edge-case listener leaks, nested model parsing...\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"1.0.0\">1.0.0</b> &mdash; <small><i>March 20, 2013</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.9.10...1.0.0\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/1.0.0/index.html\">Docs</a><br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Renamed Collection's \"update\" to <a href=\"#Collection-set\">set</a>, for\n        parallelism with the similar <tt>model.set()</tt>, and contrast with\n        <a href=\"#Collection-reset\">reset</a>. It's now the default\n        updating mechanism after a <a href=\"#Collection-fetch\">fetch</a>. If you'd\n        like to continue using \"reset\", pass <tt>{reset: true}</tt>.\n      </li>\n      <li>\n        Your route handlers will now receive their URL parameters pre-decoded.\n      </li>\n      <li>\n        Added <a href=\"#Events-listenToOnce\">listenToOnce</a> as the analogue of\n        <a href=\"#Events-once\">once</a>.\n      </li>\n      <li>\n        Added the <a href=\"#Collection-findWhere\">findWhere</a> method to Collections,\n        similar to <a href=\"#Collection-where\">where</a>.\n      </li>\n      <li>\n        Added the <tt>keys</tt>, <tt>values</tt>, <tt>pairs</tt>, <tt>invert</tt>,\n        <tt>pick</tt>, and <tt>omit</tt> Underscore.js methods to Backbone Models.\n      </li>\n      <li>\n        The routes in a Router's route map may now be function literals,\n        instead of references to methods, if you like.\n      </li>\n      <li>\n        <tt>url</tt> and <tt>urlRoot</tt> properties may now be passed as options\n        when instantiating a new Model.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"0.9.10\">0.9.10</b> &mdash; <small><i>Jan. 15, 2013</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.9.9...0.9.10\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.9.10/index.html\">Docs</a><br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        A <tt>\"route\"</tt> event is triggered on the router in addition\n        to being fired on <tt>Backbone.history</tt>.\n      </li>\n      <li>\n        Model validation is now only enforced by default in\n        <tt>Model#save</tt> and no longer enforced by default upon\n        construction or in <tt>Model#set</tt>, unless the <tt>{validate:true}</tt>\n        option is passed.\n      </li>\n      <li>\n        <tt>View#make</tt> has been removed. You'll need to use <tt>$</tt> directly to\n        construct DOM elements now.\n      </li>\n      <li>\n        Passing <tt>{silent:true}</tt> on change will no longer delay individual\n        <tt>\"change:attr\"</tt> events, instead they are silenced entirely.\n      </li>\n      <li>\n        The <tt>Model#change</tt> method has been removed, as delayed attribute\n        changes are no longer available.\n      </li>\n      <li>\n        Bug fix on <tt>change</tt> where attribute comparison uses <tt>!==</tt>\n        instead of <tt>_.isEqual</tt>.\n      </li>\n      <li>\n        Bug fix where an empty response from the server on save would not call\n        the success function.\n      </li>\n      <li>\n        <tt>parse</tt> now receives <tt>options</tt> as its second argument.\n      </li>\n      <li>\n        Model validation now fires <tt>invalid</tt> event instead of\n        <tt>error</tt>.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"0.9.9\">0.9.9</b> &mdash; <small><i>Dec. 13, 2012</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.9.2...0.9.9\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.9.9/index.html\">Docs</a><br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Added <a href=\"#Events-listenTo\">listenTo</a>\n        and <a href=\"#Events-stopListening\">stopListening</a> to Events. They\n        can be used as inversion-of-control flavors of <tt>on</tt> and <tt>off</tt>,\n        for convenient unbinding of all events an object is currently listening to.\n        <tt>view.remove()</tt> automatically calls <tt>view.stopListening()</tt>.\n      </li>\n      <li>\n        When using <tt>add</tt> on a collection, passing <tt>{merge: true}</tt>\n        will now cause duplicate models to have their attributes merged in to\n        the existing models, instead of being ignored.\n      </li>\n      <li>\n        Added <a href=\"#Collection-update\">update</a> (which is also available as\n        an option to <tt>fetch</tt>) for \"smart\" updating of sets of models.\n      </li>\n      <li>\n        HTTP <tt>PATCH</tt> support in <a href=\"#Model-save\">save</a> by passing\n        <tt>{patch: true}</tt>.\n      </li>\n      <li>\n        The <tt>Backbone</tt> object now extends <tt>Events</tt> so that you can\n        use it as a global event bus, if you like.\n      </li>\n      <li>\n        Added a <tt>\"request\"</tt> event to <a href=\"#Sync\">Backbone.sync</a>,\n        which triggers whenever a request begins to be made to the server.\n        The natural complement to the <tt>\"sync\"</tt> event.\n      </li>\n      <li>\n        Router URLs now support optional parts via parentheses, without having\n        to use a regex.\n      </li>\n      <li>\n        Backbone events now supports <tt>once</tt>, similar to Node's <tt>once</tt>,\n        or jQuery's <tt>one</tt>.\n      </li>\n      <li>\n        Backbone events now support jQuery-style event maps <tt>obj.on({click: action})</tt>.\n      </li>\n      <li>\n        While listening to a <tt>reset</tt> event, the list of previous models\n        is now available in <tt>options.previousModels</tt>, for convenience.\n      </li>\n      <li>\n        <a href=\"#Model-validate\">Validation</a> now occurs even during \"silent\"\n        changes. This change means that the <tt>isValid</tt> method has\n        been removed. Failed validations also trigger an error, even if an error\n        callback is specified in the options.\n      </li>\n      <li>\n        Consolidated <tt>\"sync\"</tt> and <tt>\"error\"</tt> events within\n        <a href=\"#Sync\">Backbone.sync</a>. They are now triggered regardless\n        of the existence of <tt>success</tt> or <tt>error</tt> callbacks.\n      </li>\n      <li>\n        For mixed-mode APIs, <tt>Backbone.sync</tt> now accepts\n        <tt>emulateHTTP</tt> and <tt>emulateJSON</tt> as inline options.\n      </li>\n      <li>\n        Collections now also proxy Underscore method name aliases (collect,\n        inject, foldl, foldr, head, tail, take, and so on...)\n      </li>\n      <li>\n        Removed <tt>getByCid</tt> from Collections. <tt>collection.get</tt> now\n        supports lookup by both <tt>id</tt> and <tt>cid</tt>.\n      </li>\n      <li>\n        After fetching a model or a collection, <i>all</i> defined <tt>parse</tt>\n        functions will now be run. So fetching a collection and getting back new\n        models could cause both the collection to parse the list, and then each model\n        to be parsed in turn, if you have both functions defined.\n      </li>\n      <li>\n        Bugfix for normalizing leading and trailing slashes in the Router\n        definitions. Their presence (or absence) should not affect behavior.\n      </li>\n      <li>\n        When declaring a View, <tt>options</tt>, <tt>el</tt>, <tt>tagName</tt>,\n        <tt>id</tt> and <tt>className</tt> may now be defined as functions, if\n        you want their values to be determined at runtime.\n      </li>\n      <li>\n        Added a <tt>Backbone.ajax</tt> hook for more convenient overriding of\n        the default use of <tt>$.ajax</tt>. If AJAX is too passé, set it to your\n        preferred method for server communication.\n      </li>\n      <li>\n        <tt>Collection#sort</tt> now triggers a <tt>sort</tt> event, instead\n        of a <tt>reset</tt> event.\n      </li>\n      <li>\n        Calling <tt>destroy</tt> on a Model will now return <tt>false</tt> if\n        the model <tt>isNew</tt>.\n      </li>\n      <li>\n        To set what library Backbone uses for DOM manipulation and Ajax calls,\n        use <tt>Backbone.$ = ...</tt> instead of <tt>setDomLibrary</tt>.\n      </li>\n      <li>\n        Removed the <tt>Backbone.wrapError</tt> helper method. Overriding\n        <tt>sync</tt> should work better for those particular use cases.\n      </li>\n      <li>\n        To improve the performance of <tt>add</tt>, <tt>options.index</tt>\n        will no longer be set in the <tt>add</tt> event callback.\n        <tt>collection.indexOf(model)</tt> can be used to retrieve the index\n        of a model as necessary.\n      </li>\n      <li>\n        For semantic and cross browser reasons, routes will now ignore search\n        parameters.  Routes like <tt>search?query=…&amp;page=3</tt> should become\n        <tt>search/…/3</tt>.\n      </li>\n      <li>\n        <tt>Model#set</tt> no longer accepts another model as an argument.  This leads\n        to subtle problems and is easily replaced with <tt>model.set(other.attributes)</tt>.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"0.9.2\">0.9.2</b> &mdash; <small><i>March 21, 2012</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.9.1...0.9.2\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.9.2/index.html\">Docs</a><br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Instead of throwing an error when adding duplicate models to a collection,\n        Backbone will now silently skip them instead.\n      </li>\n      <li>\n        Added <a href=\"#Collection-push\">push</a>,\n        <a href=\"#Collection-pop\">pop</a>,\n        <a href=\"#Collection-unshift\">unshift</a>, and\n        <a href=\"#Collection-shift\">shift</a> to collections.\n      </li>\n      <li>\n        A model's <a href=\"#Model-changed\">changed</a> hash is now exposed for\n        easy reading of the changed attribute delta, since the model's last\n        <tt>\"change\"</tt> event.\n      </li>\n      <li>\n        Added <a href=\"#Collection-where\">where</a> to collections for simple\n        filtering.\n      </li>\n      <li>\n        You can now use a single <a href=\"#Events-off\">off</a> call\n        to remove all callbacks bound to a specific object.\n      </li>\n      <li>\n        Bug fixes for nested individual change events, some of which may be\n        \"silent\".\n      </li>\n      <li>\n        Bug fixes for URL encoding in <tt>location.hash</tt> fragments.\n      </li>\n      <li>\n        Bug fix for client-side validation in advance of a <tt>save</tt> call\n        with <tt>{wait: true}</tt>.\n      </li>\n      <li>\n        Updated / refreshed the example\n        <a href=\"examples/todos/index.html\">Todo List</a> app.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"0.9.1\">0.9.1</b> &mdash; <small><i>Feb. 2, 2012</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.9.0...0.9.1\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.9.1/index.html\">Docs</a><br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Reverted to 0.5.3-esque behavior for validating models. Silent changes\n        no longer trigger validation (making it easier to work with forms).\n        Added an <tt>isValid</tt> function that you can use to check if a model\n        is currently in a valid state.\n      </li>\n      <li>\n        If you have multiple versions of jQuery on the page, you can now tell\n        Backbone which one to use with <tt>Backbone.setDomLibrary</tt>.\n      </li>\n      <li>\n        Fixes regressions in <b>0.9.0</b> for routing with \"root\", saving with\n        both \"wait\" and \"validate\", and the order of nested \"change\" events.\n      </li>\n    </ul>\n\n    <b class=\"header\" id=\"0.9.0\">0.9.0</b> &mdash; <small><i>Jan. 30, 2012</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.5.3...0.9.0\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.9.0/index.html\">Docs</a><br />\n    <ul style=\"margin-top: 5px;\">\n      <li>\n        Creating and destroying models with <tt>create</tt> and <tt>destroy</tt>\n        are now optimistic by default. Pass <tt>{wait: true}</tt> as an option\n        if you'd like them to wait for a successful server response to proceed.\n      </li>\n      <li>\n        Two new properties on views: <tt>$el</tt> &mdash; a cached jQuery (or Zepto)\n        reference to the view's element, and <tt>setElement</tt>, which should\n        be used instead of manually setting a view's <tt>el</tt>. It will\n        both set <tt>view.el</tt> and <tt>view.$el</tt> correctly, as well as\n        re-delegating events on the new DOM element.\n      </li>\n      <li>\n        You can now bind and trigger multiple spaced-delimited events at once.\n        For example: <tt>model.on(\"change:name change:age\", ...)</tt>\n      </li>\n      <li>\n        When you don't know the key in advance, you may now call\n        <tt>model.set(key, value)</tt> as well as <tt>save</tt>.\n      </li>\n      <li>\n        Multiple models with the same <tt>id</tt> are no longer allowed in a\n        single collection.\n      </li>\n      <li>\n        Added a <tt>\"sync\"</tt> event, which triggers whenever a model's state\n        has been successfully synced with the server (create, save, destroy).\n      </li>\n      <li>\n        <tt>bind</tt> and <tt>unbind</tt> have been renamed to <tt>on</tt>\n        and <tt>off</tt> for clarity, following jQuery's lead.\n        The old names are also still supported.\n      </li>\n      <li>\n        A Backbone collection's <tt>comparator</tt> function may now behave\n        either like a <a href=\"http://underscorejs.org/#sortBy\">sortBy</a>\n        (pass a function that takes a single argument),\n        or like a <a href=\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">sort</a>\n        (pass a comparator function that expects two arguments). The comparator\n        function is also now bound by default to the collection &mdash; so you\n        can refer to <tt>this</tt> within it.\n      </li>\n      <li>\n        A view's <tt>events</tt> hash may now also contain direct function\n        values as well as the string names of existing view methods.\n      </li>\n      <li>\n        Validation has gotten an overhaul &mdash; a model's <tt>validate</tt> function\n        will now be run even for silent changes, and you can no longer create\n        a model in an initially invalid state.\n      </li>\n      <li>\n        Added <tt>shuffle</tt> and <tt>initial</tt> to collections, proxied\n        from Underscore.\n      </li>\n      <li>\n        <tt>Model#urlRoot</tt> may now be defined as a function as well as a\n        value.\n      </li>\n      <li>\n        <tt>View#attributes</tt> may now be defined as a function as well as a\n        value.\n      </li>\n      <li>\n        Calling <tt>fetch</tt> on a collection will now cause all fetched JSON\n        to be run through the collection's model's <tt>parse</tt> function, if\n        one is defined.\n      </li>\n      <li>\n        You may now tell a router to <tt>navigate(fragment, {replace: true})</tt>,\n        which will either use <tt>history.replaceState</tt> or\n        <tt>location.hash.replace</tt>, in order to change the URL without adding\n        a history entry.\n      </li>\n      <li>\n        Within a collection's <tt>add</tt> and <tt>remove</tt> events, the index\n        of the model being added or removed is now available as <tt>options.index</tt>.\n      </li>\n      <li>\n        Added an <tt>undelegateEvents</tt> to views, allowing you to manually\n        remove all configured event delegations.\n      </li>\n      <li>\n        Although you shouldn't be writing your routes with them in any case &mdash;\n        leading slashes (<tt>/</tt>) are now stripped from routes.\n      </li>\n      <li>\n        Calling <tt>clone</tt> on a model now only passes the attributes\n        for duplication, not a reference to the model itself.\n      </li>\n      <li>\n        Calling <tt>clear</tt> on a model now removes the <tt>id</tt> attribute.\n      </li>\n    </ul>\n\n    <p>\n      <b class=\"header\" id=\"0.5.3\">0.5.3</b> &mdash; <small><i>August 9, 2011</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.5.2...0.5.3\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.5.3/index.html\">Docs</a><br />\n      A View's <tt>events</tt> property may now be defined as a function, as well\n      as an object literal, making it easier to programmatically define and inherit\n      events. <tt>groupBy</tt> is now proxied from Underscore as a method on Collections.\n      If the server has already rendered everything on page load, pass\n      <tt>Backbone.history.start({silent: true})</tt> to prevent the initial route\n      from triggering. Bugfix for pushState with encoded URLs.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.5.2\">0.5.2</b> &mdash; <small><i>July 26, 2011</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.5.1...0.5.2\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.5.2/index.html\">Docs</a><br />\n      The <tt>bind</tt> function, can now take an optional third argument, to specify\n      the <tt>this</tt> of the callback function.\n      Multiple models with the same <tt>id</tt> are now allowed in a collection.\n      Fixed a bug where calling <tt>.fetch(jQueryOptions)</tt> could cause an\n      incorrect URL to be serialized.\n      Fixed a brief extra route fire before redirect, when degrading from\n      <tt>pushState</tt>.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.5.1\">0.5.1</b> &mdash; <small><i>July 5, 2011</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.5.0...0.5.1\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.5.1/index.html\">Docs</a><br />\n      Cleanups from the 0.5.0 release, to wit: improved transparent upgrades from\n      hash-based URLs to pushState, and vice-versa. Fixed inconsistency with\n      non-modified attributes being passed to <tt>Model#initialize</tt>. Reverted\n      a <b>0.5.0</b> change that would strip leading hashbangs from routes.\n      Added <tt>contains</tt> as an alias for <tt>includes</tt>.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.5.0\">0.5.0</b> &mdash; <small><i>July 1, 2011</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.3.3...0.5.0\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.5.0/index.html\">Docs</a><br />\n      A large number of tiny tweaks and micro bugfixes, best viewed by looking\n      at <a href=\"https://github.com/jashkenas/backbone/compare/0.3.3...0.5.0\">the commit diff</a>.\n      HTML5 <tt>pushState</tt> support, enabled by opting-in with:\n      <tt>Backbone.history.start({pushState: true})</tt>.\n      <tt>Controller</tt> was renamed to <tt>Router</tt>, for clarity.\n      <tt>Collection#refresh</tt> was renamed to <tt>Collection#reset</tt> to emphasize\n      its ability to both reset the collection with new models, as well as empty\n      out the collection when used with no parameters.\n      <tt>saveLocation</tt> was replaced with <tt>navigate</tt>.\n      RESTful persistence methods (save, fetch, etc.) now return the jQuery deferred\n      object for further success/error chaining and general convenience.\n      Improved XSS escaping for <tt>Model#escape</tt>.\n      Added a <tt>urlRoot</tt> option to allow specifying RESTful urls without\n      the use of a collection.\n      An error is thrown if <tt>Backbone.history.start</tt> is called multiple times.\n      <tt>Collection#create</tt> now validates before initializing the new model.\n      <tt>view.el</tt> can now be a jQuery string lookup.\n      Backbone Views can now also take an <tt>attributes</tt> parameter.\n      <tt>Model#defaults</tt> can now be a function as well as a literal attributes\n      object.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.3.3\">0.3.3</b> &mdash; <small><i>Dec 1, 2010</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.3.2...0.3.3\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.3.3/index.html\">Docs</a><br />\n      Backbone.js now supports <a href=\"http://zeptojs.com\">Zepto</a>, alongside\n      jQuery, as a framework for DOM manipulation and Ajax support.\n      Implemented <a href=\"#Model-escape\">Model#escape</a>, to efficiently handle\n      attributes intended for HTML interpolation. When trying to persist a model,\n      failed requests will now trigger an <tt>\"error\"</tt> event. The\n      ubiquitous <tt>options</tt> argument is now passed as the final argument\n      to all <tt>\"change\"</tt> events.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.3.2\">0.3.2</b> &mdash; <small><i>Nov 23, 2010</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.3.1...0.3.2\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.3.2/index.html\">Docs</a><br />\n      Bugfix for IE7 + iframe-based \"hashchange\" events. <tt>sync</tt> may now be\n      overridden on a per-model, or per-collection basis. Fixed recursion error\n      when calling <tt>save</tt> with no changed attributes, within a\n      <tt>\"change\"</tt> event.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.3.1\">0.3.1</b> &mdash; <small><i>Nov 15, 2010</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.3.0...0.3.1\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.3.1/index.html\">Docs</a><br />\n      All <tt>\"add\"</tt> and <tt>\"remove\"</tt> events are now sent through the\n      model, so that views can listen for them without having to know about the\n      collection. Added a <tt>remove</tt> method to <a href=\"#View\">Backbone.View</a>.\n      <tt>toJSON</tt> is no longer called at all for <tt>'read'</tt> and <tt>'delete'</tt> requests.\n      Backbone routes are now able to load empty URL fragments.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.3.0\">0.3.0</b> &mdash; <small><i>Nov 9, 2010</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.2.0...0.3.0\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.3.0/index.html\">Docs</a><br />\n      Backbone now has <a href=\"#Controller\">Controllers</a> and\n      <a href=\"#History\">History</a>, for doing client-side routing based on\n      URL fragments.\n      Added <tt>emulateHTTP</tt> to provide support for legacy servers that don't\n      do <tt>PUT</tt> and <tt>DELETE</tt>.\n      Added <tt>emulateJSON</tt> for servers that can't accept <tt>application/json</tt>\n      encoded requests.\n      Added <a href=\"#Model-clear\">Model#clear</a>, which removes all attributes\n      from a model.\n      All Backbone classes may now be seamlessly inherited by CoffeeScript classes.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.2.0\">0.2.0</b> &mdash; <small><i>Oct 25, 2010</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.1.2...0.2.0\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.2.0/index.html\">Docs</a><br />\n      Instead of requiring server responses to be namespaced under a <tt>model</tt>\n      key, now you can define your own <a href=\"#Model-parse\">parse</a> method\n      to convert responses into attributes for Models and Collections.\n      The old <tt>handleEvents</tt> function is now named\n      <a href=\"#View-delegateEvents\">delegateEvents</a>, and is automatically\n      called as part of the View's constructor.\n      Added a <a href=\"#Collection-toJSON\">toJSON</a> function to Collections.\n      Added <a href=\"#Collection-chain\">Underscore's chain</a> to Collections.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.1.2\">0.1.2</b> &mdash; <small><i>Oct 19, 2010</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.1.1...0.1.2\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.1.2/index.html\">Docs</a><br />\n      Added a <a href=\"#Model-fetch\">Model#fetch</a> method for refreshing the\n      attributes of single model from the server.\n      An <tt>error</tt> callback may now be passed to <tt>set</tt> and <tt>save</tt>\n      as an option, which will be invoked if validation fails, overriding the\n      <tt>\"error\"</tt> event.\n      You can now tell backbone to use the <tt>_method</tt> hack instead of HTTP\n      methods by setting <tt>Backbone.emulateHTTP = true</tt>.\n      Existing Model and Collection data is no longer sent up unnecessarily with\n      <tt>GET</tt> and <tt>DELETE</tt> requests. Added a <tt>rake lint</tt> task.\n      Backbone is now published as an <a href=\"http://npmjs.org\">NPM</a> module.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.1.1\">0.1.1</b> &mdash; <small><i>Oct 14, 2010</i></small> &mdash; <a href=\"https://github.com/jashkenas/backbone/compare/0.1.0...0.1.1\">Diff</a> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.1.1/index.html\">Docs</a><br />\n      Added a convention for <tt>initialize</tt> functions to be called\n      upon instance construction, if defined. Documentation tweaks.\n    </p>\n\n    <p>\n      <b class=\"header\" id=\"0.1.0\">0.1.0</b> &mdash; <small><i>Oct 13, 2010</i></small> &mdash; <a href=\"https://cdn.statically.io/gh/jashkenas/backbone/0.1.0/index.html\">Docs</a><br />\n      Initial Backbone release.\n    </p>\n\n    <p>\n      <br />\n      <a href=\"http://documentcloud.org/\" title=\"A DocumentCloud Project\" style=\"background:none;\">\n        <img src=\"http://jashkenas.s3.amazonaws.com/images/a_documentcloud_project.png\" alt=\"A DocumentCloud Project\" style=\"position:relative;left:-10px;\" />\n      </a>\n    </p>\n\n  </div>\n\n  <script src=\"test/vendor/underscore.js\"></script>\n  <script src=\"test/vendor/jquery.js\"></script>\n  <script src=\"docs/js/jquery.lazyload.js\"></script>\n  <script src=\"test/vendor/json2.js\"></script>\n  <script src=\"backbone.js\"></script>\n  <script src=\"docs/search.js\"></script>\n\n  <script>\n    // Set up the \"play\" buttons for each runnable code example.\n    $(function() {\n      $('.runnable').each(function() {\n        var code = this;\n        var button = '<div class=\"run\" title=\"Run\"></div>';\n        $(button).insertBefore(code).bind('click', function(){\n          eval($(code).text());\n        });\n      });\n      $('[data-original]').lazyload();\n    });\n  </script>\n\n</body>\n</html>\n"
  },
  {
    "path": "karma.conf-sauce.js",
    "content": "var _ = require('underscore');\n\n// Browsers to run on Sauce Labs platforms\nvar sauceBrowsers = _.reduce([\n  ['firefox', 'latest'],\n  ['firefox', '60'],\n  ['firefox', '40'],\n  // TODO: find a way to get testing on old Firefox to work. (#4253)\n  // ['firefox', '11'],\n\n  ['chrome', 'latest'],\n  ['chrome', '60'],\n  // TODO: these versions of Chrome fail with a mysterious\n  // \"_T_ is not defined\" (#4253)\n  // ['chrome', '40'],\n  // ['chrome', '26'],\n\n  // latest Edge as well as pre-Blink versions\n  ['microsoftedge', 'latest', 'Windows 11'],\n  ['microsoftedge', '18', 'Windows 10'],\n  ['microsoftedge', '13', 'Windows 10'],\n\n  ['internet explorer', 'latest', 'Windows 10'],\n  // TODO: these versions of IE run 50 out of 425 tests, then hang for unknown\n  // reasons. (#4253)\n  // ['internet explorer', '10', 'Windows 8'],\n  // ['internet explorer', '9', 'Windows 7'],\n  // Older versions of IE no longer supported by Sauce Labs\n\n  ['safari', 'latest', 'macOS 12'],\n  ['safari', '12', 'macOS 10.14'],\n  ['safari', '11', 'macOS 10.13'],\n  ['safari', '8', 'OS X 10.10'],\n\n], function(memo, platform) {\n  // internet explorer -> ie\n  var label = platform[0].split(' ');\n  if (label.length > 1) {\n    label = _.invoke(label, 'charAt', 0);\n  }\n  label = (label.join('') + '_v' + platform[1]).replace(' ', '_').toUpperCase();\n  memo[label] = _.pick({\n    base: 'SauceLabs',\n    browserName: platform[0],\n    version: platform[1],\n    platform: platform[2]\n  }, Boolean);\n  return memo;\n}, {});\n\nmodule.exports = function(config) {\n  if ( !process.env.SAUCE_USERNAME || !process.env.SAUCE_ACCESS_KEY ) {\n    // eslint-disable-next-line no-console\n    console.log('Sauce environments not set --- Skipping');\n    return process.exit(0);\n  }\n\n  config.set({\n    basePath: '',\n    frameworks: ['qunit'],\n    singleRun: true,\n    browserDisconnectTimeout: 60000,\n    browserDisconnectTolerance: 2,\n    browserNoActivityTimeout: 60000,\n\n    // list of files / patterns to load in the browser\n    files: [\n      'test/vendor/jquery.js',\n      'test/vendor/json2.js',\n      'test/vendor/underscore.js',\n      'backbone.js',\n      'debug-info.js',\n      'test/setup/*.js',\n      'test/*.js'\n    ],\n\n    // Number of sauce tests to start in parallel\n    concurrency: 4,\n\n    // test results reporter to use\n    reporters: ['dots', 'saucelabs'],\n    port: 9876,\n    colors: true,\n    logLevel: config.LOG_INFO,\n    sauceLabs: {\n      build: 'GH #' + process.env.BUILD_NUMBER + ' (' + process.env.BUILD_ID + ')',\n      startConnect: true,\n      tunnelIdentifier: process.env.JOB_NUMBER,\n      region: 'eu'\n    },\n\n    captureTimeout: 60000,\n    customLaunchers: sauceBrowsers,\n\n    // Browsers to launch, commented out to prevent karma from starting\n    // too many concurrent browsers and timing sauce out.\n    browsers: _.keys(sauceBrowsers)\n  });\n};\n"
  },
  {
    "path": "karma.conf.js",
    "content": "// Note some browser launchers should be installed before using karma start.\n// For example:\n// npm install karma-firefox-launcher\n// karma start --browsers=Firefox\nmodule.exports = function(config) {\n  config.set({\n    basePath: '',\n    frameworks: ['qunit'],\n\n    // list of files / patterns to load in the browser\n    files: [\n        'test/vendor/jquery.js',\n        'test/vendor/json2.js',\n        'test/vendor/underscore.js',\n        'backbone.js',\n        'debug-info.js',\n        'test/setup/*.js',\n        'test/*.js'\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    // web server port\n    port: 9877,\n\n    // enable / disable colors in the output (reporters and logs)\n    colors: true,\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    // enable / disable watching file and executing tests whenever any file changes\n    autoWatch: false,\n\n    // start these browsers\n    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher\n    browsers: [],\n\n    // Continuous Integration mode\n    // if true, Karma captures browsers, runs the tests and exits\n    singleRun: true,\n\n    // See http://stackoverflow.com/a/27873086/1517919\n    customLaunchers: {\n        Chrome_sandbox: {\n            base: 'Chrome',\n            flags: ['--no-sandbox']\n        }\n    }\n  });\n};\n"
  },
  {
    "path": "modules/.eslintrc",
    "content": "{\n  \"parserOptions\": {\n    \"ecmaVersion\": 6,\n    \"sourceType\": \"module\",\n  },\n  \"plugins\": [\n    \"import\"\n  ],\n  \"extends\": [\n    \"plugin:import/errors\"\n  ],\n  \"rules\": {\n    \"import/no-unresolved\": 0\n  }\n}\n"
  },
  {
    "path": "modules/debug-info.js",
    "content": "import Backbone from 'backbone';\n\n// Provide useful information when things go wrong.\nexport default function() {\n  // Introspect Backbone.\n  var $ = Backbone.$, _b = Backbone._debug(), _ = _b._, root = _b.root;\n  // Use the `partialRight` function as a Lodash indicator. It was never in\n  // Underscore, has been in Lodash at least since version 1.3.1, and is\n  // unlikely to be mixed into Underscore since nobody needs it.\n  var lodash = !!_.partialRight;\n  var info = {\n    backbone: Backbone.VERSION,\n    // Is this the exact released version, or a later development version?\n    /* This is automatically temporarily replaced when publishing a release,\n       so please don't edit this. */\n    distribution: 'MARK_DEVELOPMENT',\n    _: (lodash ? 'lodash ' : '') + _.VERSION,\n    $: !$ ? false : $.fn && $.fn.jquery ? $.fn.jquery :\n      $.zepto ? 'zepto' : $.ender ? 'ender' : true\n  };\n  if (typeof root.Deno !== 'undefined') {\n    info.deno = _.pick(root.Deno, 'version', 'build');\n  } else if (typeof root.process !== 'undefined') {\n    info.process = _.pick(root.process, 'version', 'platform', 'arch');\n  } else if (typeof root.navigator !== 'undefined') {\n    info.navigator = _.pick(root.navigator, 'userAgent', 'platform', 'webdriver');\n  }\n  /* eslint-disable-next-line no-console */\n  console.debug('Backbone debug info: ', JSON.stringify(info, null, 4));\n  return info;\n}\n"
  },
  {
    "path": "modules/package.json",
    "content": "{\"type\":\"module\",\"version\":\"1.4.1\"}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"backbone\",\n  \"description\": \"Give your JS App some Backbone with Models, Views, Collections, and Events.\",\n  \"url\": \"http://backbonejs.org\",\n  \"keywords\": [\n    \"model\",\n    \"view\",\n    \"controller\",\n    \"router\",\n    \"server\",\n    \"client\",\n    \"browser\"\n  ],\n  \"author\": \"Jeremy Ashkenas\",\n  \"dependencies\": {\n    \"underscore\": \">=1.8.3\"\n  },\n  \"devDependencies\": {\n    \"coffeescript\": \"^2.7.0\",\n    \"cpy-cli\": \"^5.0.0\",\n    \"docco\": \"^0.9.1\",\n    \"eslint\": \"^8.7.0\",\n    \"eslint-plugin-import\": \"^2.28.1\",\n    \"karma\": \"^6.3.11\",\n    \"karma-qunit\": \"^4.1.2\",\n    \"qunit\": \"^2.17.2\",\n    \"replace-in-file\": \"^7.0.1\",\n    \"rollup\": \"^3.28.1\",\n    \"uglify-js\": \"^3.14.5\"\n  },\n  \"scripts\": {\n    \"test\": \"karma start && coffee test/model.coffee && npm run lint\",\n    \"build\": \"uglifyjs backbone.js --mangle --source-map url=backbone-min.js.map -o backbone-min.js\",\n    \"build-debug\": \"npx rollup -e backbone -f umd -g backbone:Backbone -n Backbone.debugInfo -o debug-info.js --no-strict modules/debug-info.js\",\n    \"alias-sourcemap\": \"cpy --rename=backbone-min.map backbone-min.js.map .\",\n    \"doc\": \"docco backbone.js && docco examples/todos/todos.js examples/backbone.localStorage.js\",\n    \"lint\": \"eslint backbone.js test/*.js modules/*.js\",\n    \"mark-release\": \"replace-in-file MARK_DEVELOPMENT MARK_RELEASE modules/debug-info.js && npm run build-debug\",\n    \"mark-develop\": \"replace-in-file MARK_RELEASE MARK_DEVELOPMENT modules/debug-info.js && npm run build-debug\",\n    \"prepublishOnly\": \"npm run test && npm run mark-release && npm run build && npm run alias-sourcemap && npm run doc && git add -u && npm run mark-develop\"\n  },\n  \"main\": \"backbone.js\",\n  \"version\": \"1.6.1\",\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/jashkenas/backbone.git\"\n  },\n  \"files\": [\n    \"backbone.js\",\n    \"backbone-min.js\",\n    \"backbone-min.js.map\",\n    \"backbone-min.map\",\n    \"debug-info.js\",\n    \"LICENSE\",\n    \"modules/debug-info.js\",\n    \"modules/package.json\"\n  ]\n}\n"
  },
  {
    "path": "test/.eslintrc",
    "content": "{\n  \"env\": {\n    \"browser\": true\n  },\n  \"globals\": {\n    \"QUnit\": false,\n    \"Backbone\": true,\n    \"_\": true,\n    \"$\": true\n  },\n  \"rules\": {\n    \"no-throw-literal\": 0,\n    \"no-undefined\": 0\n  }\n}\n"
  },
  {
    "path": "test/collection.js",
    "content": "(function(QUnit) {\n\n  var a, b, c, d, e, col, otherCol;\n\n  QUnit.module('Backbone.Collection', {\n\n    beforeEach: function(assert) {\n      a         = new Backbone.Model({id: 3, label: 'a'});\n      b         = new Backbone.Model({id: 2, label: 'b'});\n      c         = new Backbone.Model({id: 1, label: 'c'});\n      d         = new Backbone.Model({id: 0, label: 'd'});\n      e         = null;\n      col       = new Backbone.Collection([a, b, c, d]);\n      otherCol  = new Backbone.Collection();\n    }\n\n  });\n\n  QUnit.test('new and sort', function(assert) {\n    assert.expect(6);\n    var counter = 0;\n    col.on('sort', function(){ counter++; });\n    assert.deepEqual(col.pluck('label'), ['a', 'b', 'c', 'd']);\n    col.comparator = function(m1, m2) {\n      return m1.id > m2.id ? -1 : 1;\n    };\n    col.sort();\n    assert.equal(counter, 1);\n    assert.deepEqual(col.pluck('label'), ['a', 'b', 'c', 'd']);\n    col.comparator = function(model) { return model.id; };\n    col.sort();\n    assert.equal(counter, 2);\n    assert.deepEqual(col.pluck('label'), ['d', 'c', 'b', 'a']);\n    assert.equal(col.length, 4);\n  });\n\n  QUnit.test('String comparator.', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([\n      {id: 3},\n      {id: 1},\n      {id: 2}\n    ], {comparator: 'id'});\n    assert.deepEqual(collection.pluck('id'), [1, 2, 3]);\n  });\n\n  QUnit.test('new and parse', function(assert) {\n    assert.expect(3);\n    var Collection = Backbone.Collection.extend({\n      parse: function(data) {\n        return _.filter(data, function(datum) {\n          return datum.a % 2 === 0;\n        });\n      }\n    });\n    var models = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];\n    var collection = new Collection(models, {parse: true});\n    assert.strictEqual(collection.length, 2);\n    assert.strictEqual(collection.first().get('a'), 2);\n    assert.strictEqual(collection.last().get('a'), 4);\n  });\n\n  QUnit.test('clone preserves model and comparator', function(assert) {\n    assert.expect(3);\n    var Model = Backbone.Model.extend();\n    var comparator = function(model){ return model.id; };\n\n    var collection = new Backbone.Collection([{id: 1}], {\n      model: Model,\n      comparator: comparator\n    }).clone();\n    collection.add({id: 2});\n    assert.ok(collection.at(0) instanceof Model);\n    assert.ok(collection.at(1) instanceof Model);\n    assert.strictEqual(collection.comparator, comparator);\n  });\n\n  QUnit.test('get', function(assert) {\n    assert.expect(6);\n    assert.equal(col.get(0), d);\n    assert.equal(col.get(d.clone()), d);\n    assert.equal(col.get(2), b);\n    assert.equal(col.get({id: 1}), c);\n    assert.equal(col.get(c.clone()), c);\n    assert.equal(col.get(col.first().cid), col.first());\n  });\n\n  QUnit.test('get with non-default ids', function(assert) {\n    assert.expect(5);\n    var MongoModel = Backbone.Model.extend({idAttribute: '_id'});\n    var model = new MongoModel({_id: 100});\n    var collection = new Backbone.Collection([model], {model: MongoModel});\n    assert.equal(collection.get(100), model);\n    assert.equal(collection.get(model.cid), model);\n    assert.equal(collection.get(model), model);\n    assert.equal(collection.get(101), void 0);\n\n    var collection2 = new Backbone.Collection();\n    collection2.model = MongoModel;\n    collection2.add(model.attributes);\n    assert.equal(collection2.get(model.clone()), collection2.first());\n  });\n\n  QUnit.test('has', function(assert) {\n    assert.expect(15);\n    assert.ok(col.has(a));\n    assert.ok(col.has(b));\n    assert.ok(col.has(c));\n    assert.ok(col.has(d));\n    assert.ok(col.has(a.id));\n    assert.ok(col.has(b.id));\n    assert.ok(col.has(c.id));\n    assert.ok(col.has(d.id));\n    assert.ok(col.has(a.cid));\n    assert.ok(col.has(b.cid));\n    assert.ok(col.has(c.cid));\n    assert.ok(col.has(d.cid));\n    var outsider = new Backbone.Model({id: 4});\n    assert.notOk(col.has(outsider));\n    assert.notOk(col.has(outsider.id));\n    assert.notOk(col.has(outsider.cid));\n  });\n\n  QUnit.test('update index when id changes', function(assert) {\n    assert.expect(6);\n    var collection = new Backbone.Collection();\n    collection.add([\n      {id: 0, name: 'one'},\n      {id: 1, name: 'two'}\n    ]);\n    var one = collection.get(0);\n    assert.equal(one.get('name'), 'one');\n    collection.on('change:name', function(model) {\n      assert.ok(this.get(model));\n      assert.equal(model, this.get(101));\n      assert.equal(this.get(0), null);\n    });\n    one.set({name: 'dalmatians', id: 101});\n    assert.equal(collection.get(0), null);\n    assert.equal(collection.get(101).get('name'), 'dalmatians');\n  });\n\n  QUnit.test('at', function(assert) {\n    assert.expect(2);\n    assert.equal(col.at(2), c);\n    assert.equal(col.at(-2), c);\n  });\n\n  QUnit.test('pluck', function(assert) {\n    assert.expect(1);\n    assert.equal(col.pluck('label').join(' '), 'a b c d');\n  });\n\n  QUnit.test('add', function(assert) {\n    assert.expect(14);\n    var added, opts, secondAdded;\n    added = opts = secondAdded = null;\n    e = new Backbone.Model({id: 10, label: 'e'});\n    otherCol.add(e);\n    otherCol.on('add', function() {\n      secondAdded = true;\n    });\n    col.on('add', function(model, collection, options){\n      added = model.get('label');\n      opts = options;\n    });\n    col.add(e, {amazing: true});\n    assert.equal(added, 'e');\n    assert.equal(col.length, 5);\n    assert.equal(col.last(), e);\n    assert.equal(otherCol.length, 1);\n    assert.equal(secondAdded, null);\n    assert.ok(opts.amazing);\n\n    var f = new Backbone.Model({id: 20, label: 'f'});\n    var g = new Backbone.Model({id: 21, label: 'g'});\n    var h = new Backbone.Model({id: 22, label: 'h'});\n    var atCol = new Backbone.Collection([f, g, h]);\n    assert.equal(atCol.length, 3);\n    atCol.add(e, {at: 1});\n    assert.equal(atCol.length, 4);\n    assert.equal(atCol.at(1), e);\n    assert.equal(atCol.last(), h);\n\n    var coll = new Backbone.Collection(new Array(2));\n    var addCount = 0;\n    coll.on('add', function(){\n      addCount += 1;\n    });\n    coll.add([undefined, f, g]);\n    assert.equal(coll.length, 5);\n    assert.equal(addCount, 3);\n    coll.add(new Array(4));\n    assert.equal(coll.length, 9);\n    assert.equal(addCount, 7);\n  });\n\n  QUnit.test('add multiple models', function(assert) {\n    assert.expect(6);\n    var collection = new Backbone.Collection([{at: 0}, {at: 1}, {at: 9}]);\n    collection.add([{at: 2}, {at: 3}, {at: 4}, {at: 5}, {at: 6}, {at: 7}, {at: 8}], {at: 2});\n    for (var i = 0; i <= 5; i++) {\n      assert.equal(collection.at(i).get('at'), i);\n    }\n  });\n\n  QUnit.test('add; at should have preference over comparator', function(assert) {\n    assert.expect(1);\n    var Col = Backbone.Collection.extend({\n      comparator: function(m1, m2) {\n        return m1.id > m2.id ? -1 : 1;\n      }\n    });\n\n    var collection = new Col([{id: 2}, {id: 3}]);\n    collection.add(new Backbone.Model({id: 1}), {at: 1});\n\n    assert.equal(collection.pluck('id').join(' '), '3 1 2');\n  });\n\n  QUnit.test('add; at should add to the end if the index is out of bounds', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([{id: 2}, {id: 3}]);\n    collection.add(new Backbone.Model({id: 1}), {at: 5});\n\n    assert.equal(collection.pluck('id').join(' '), '2 3 1');\n  });\n\n  QUnit.test(\"can't add model to collection twice\", function(assert) {\n    var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 1}, {id: 2}, {id: 3}]);\n    assert.equal(collection.pluck('id').join(' '), '1 2 3');\n  });\n\n  QUnit.test(\"can't add different model with same id to collection twice\", function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection;\n    collection.unshift({id: 101});\n    collection.add({id: 101});\n    assert.equal(collection.length, 1);\n  });\n\n  QUnit.test('merge in duplicate models with {merge: true}', function(assert) {\n    assert.expect(3);\n    var collection = new Backbone.Collection;\n    collection.add([{id: 1, name: 'Moe'}, {id: 2, name: 'Curly'}, {id: 3, name: 'Larry'}]);\n    collection.add({id: 1, name: 'Moses'});\n    assert.equal(collection.first().get('name'), 'Moe');\n    collection.add({id: 1, name: 'Moses'}, {merge: true});\n    assert.equal(collection.first().get('name'), 'Moses');\n    collection.add({id: 1, name: 'Tim'}, {merge: true, silent: true});\n    assert.equal(collection.first().get('name'), 'Tim');\n  });\n\n  QUnit.test('add model to multiple collections', function(assert) {\n    assert.expect(10);\n    var counter = 0;\n    var m = new Backbone.Model({id: 10, label: 'm'});\n    m.on('add', function(model, collection) {\n      counter++;\n      assert.equal(m, model);\n      if (counter > 1) {\n        assert.equal(collection, col2);\n      } else {\n        assert.equal(collection, col1);\n      }\n    });\n    var col1 = new Backbone.Collection([]);\n    col1.on('add', function(model, collection) {\n      assert.equal(m, model);\n      assert.equal(col1, collection);\n    });\n    var col2 = new Backbone.Collection([]);\n    col2.on('add', function(model, collection) {\n      assert.equal(m, model);\n      assert.equal(col2, collection);\n    });\n    col1.add(m);\n    assert.equal(m.collection, col1);\n    col2.add(m);\n    assert.equal(m.collection, col1);\n  });\n\n  QUnit.test('add model with parse', function(assert) {\n    assert.expect(1);\n    var Model = Backbone.Model.extend({\n      parse: function(obj) {\n        obj.value += 1;\n        return obj;\n      }\n    });\n\n    var Col = Backbone.Collection.extend({model: Model});\n    var collection = new Col;\n    collection.add({value: 1}, {parse: true});\n    assert.equal(collection.at(0).get('value'), 2);\n  });\n\n  QUnit.test('add with parse and merge', function(assert) {\n    var collection = new Backbone.Collection();\n    collection.parse = function(attrs) {\n      return _.map(attrs, function(model) {\n        if (model.model) return model.model;\n        return model;\n      });\n    };\n    collection.add({id: 1});\n    collection.add({model: {id: 1, name: 'Alf'}}, {parse: true, merge: true});\n    assert.equal(collection.first().get('name'), 'Alf');\n  });\n\n  QUnit.test('add model to collection with sort()-style comparator', function(assert) {\n    assert.expect(3);\n    var collection = new Backbone.Collection;\n    collection.comparator = function(m1, m2) {\n      return m1.get('name') < m2.get('name') ? -1 : 1;\n    };\n    var tom = new Backbone.Model({name: 'Tom'});\n    var rob = new Backbone.Model({name: 'Rob'});\n    var tim = new Backbone.Model({name: 'Tim'});\n    collection.add(tom);\n    collection.add(rob);\n    collection.add(tim);\n    assert.equal(collection.indexOf(rob), 0);\n    assert.equal(collection.indexOf(tim), 1);\n    assert.equal(collection.indexOf(tom), 2);\n  });\n\n  QUnit.test('comparator that depends on `this`', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection;\n    collection.negative = function(num) {\n      return -num;\n    };\n    collection.comparator = function(model) {\n      return this.negative(model.id);\n    };\n    collection.add([{id: 1}, {id: 2}, {id: 3}]);\n    assert.deepEqual(collection.pluck('id'), [3, 2, 1]);\n    collection.comparator = function(m1, m2) {\n      return this.negative(m2.id) - this.negative(m1.id);\n    };\n    collection.sort();\n    assert.deepEqual(collection.pluck('id'), [1, 2, 3]);\n  });\n\n  QUnit.test('remove', function(assert) {\n    assert.expect(12);\n    var removed = null;\n    var result = null;\n    col.on('remove', function(model, collection, options) {\n      removed = model.get('label');\n      assert.equal(options.index, 3);\n      assert.equal(collection.get(model), undefined, '#3693: model cannot be fetched from collection');\n    });\n    result = col.remove(d);\n    assert.equal(removed, 'd');\n    assert.strictEqual(result, d);\n    //if we try to remove d again, it's not going to actually get removed\n    result = col.remove(d);\n    assert.strictEqual(result, undefined);\n    assert.equal(col.length, 3);\n    assert.equal(col.first(), a);\n    col.off();\n    result = col.remove([c, d]);\n    assert.equal(result.length, 1, 'only returns removed models');\n    assert.equal(result[0], c, 'only returns removed models');\n    result = col.remove([c, b]);\n    assert.equal(result.length, 1, 'only returns removed models');\n    assert.equal(result[0], b, 'only returns removed models');\n    result = col.remove([]);\n    assert.deepEqual(result, [], 'returns empty array when nothing removed');\n  });\n\n  QUnit.test('add and remove return values', function(assert) {\n    assert.expect(13);\n    var Even = Backbone.Model.extend({\n      validate: function(attrs) {\n        if (attrs.id % 2 !== 0) return 'odd';\n      }\n    });\n    var collection = new Backbone.Collection;\n    collection.model = Even;\n\n    var list = collection.add([{id: 2}, {id: 4}], {validate: true});\n    assert.equal(list.length, 2);\n    assert.ok(list[0] instanceof Backbone.Model);\n    assert.equal(list[1], collection.last());\n    assert.equal(list[1].get('id'), 4);\n\n    list = collection.add([{id: 3}, {id: 6}], {validate: true});\n    assert.equal(collection.length, 3);\n    assert.equal(list[0], false);\n    assert.equal(list[1].get('id'), 6);\n\n    var result = collection.add({id: 6});\n    assert.equal(result.cid, list[1].cid);\n\n    result = collection.remove({id: 6});\n    assert.equal(collection.length, 2);\n    assert.equal(result.id, 6);\n\n    list = collection.remove([{id: 2}, {id: 8}]);\n    assert.equal(collection.length, 1);\n    assert.equal(list[0].get('id'), 2);\n    assert.equal(list[1], null);\n  });\n\n  QUnit.test('shift and pop', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);\n    assert.equal(collection.shift().get('a'), 'a');\n    assert.equal(collection.pop().get('c'), 'c');\n  });\n\n  QUnit.test('slice', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);\n    var array = collection.slice(1, 3);\n    assert.equal(array.length, 2);\n    assert.equal(array[0].get('b'), 'b');\n  });\n\n  QUnit.test('events are unbound on remove', function(assert) {\n    assert.expect(3);\n    var counter = 0;\n    var dj = new Backbone.Model();\n    var emcees = new Backbone.Collection([dj]);\n    emcees.on('change', function(){ counter++; });\n    dj.set({name: 'Kool'});\n    assert.equal(counter, 1);\n    emcees.reset([]);\n    assert.equal(dj.collection, undefined);\n    dj.set({name: 'Shadow'});\n    assert.equal(counter, 1);\n  });\n\n  QUnit.test('remove in multiple collections', function(assert) {\n    assert.expect(7);\n    var modelData = {\n      id: 5,\n      title: 'Othello'\n    };\n    var passed = false;\n    var m1 = new Backbone.Model(modelData);\n    var m2 = new Backbone.Model(modelData);\n    m2.on('remove', function() {\n      passed = true;\n    });\n    var col1 = new Backbone.Collection([m1]);\n    var col2 = new Backbone.Collection([m2]);\n    assert.notEqual(m1, m2);\n    assert.ok(col1.length === 1);\n    assert.ok(col2.length === 1);\n    col1.remove(m1);\n    assert.equal(passed, false);\n    assert.ok(col1.length === 0);\n    col2.remove(m1);\n    assert.ok(col2.length === 0);\n    assert.equal(passed, true);\n  });\n\n  QUnit.test('remove same model in multiple collection', function(assert) {\n    assert.expect(16);\n    var counter = 0;\n    var m = new Backbone.Model({id: 5, title: 'Othello'});\n    m.on('remove', function(model, collection) {\n      counter++;\n      assert.equal(m, model);\n      if (counter > 1) {\n        assert.equal(collection, col1);\n      } else {\n        assert.equal(collection, col2);\n      }\n    });\n    var col1 = new Backbone.Collection([m]);\n    col1.on('remove', function(model, collection) {\n      assert.equal(m, model);\n      assert.equal(col1, collection);\n    });\n    var col2 = new Backbone.Collection([m]);\n    col2.on('remove', function(model, collection) {\n      assert.equal(m, model);\n      assert.equal(col2, collection);\n    });\n    assert.equal(col1, m.collection);\n    col2.remove(m);\n    assert.ok(col2.length === 0);\n    assert.ok(col1.length === 1);\n    assert.equal(counter, 1);\n    assert.equal(col1, m.collection);\n    col1.remove(m);\n    assert.equal(null, m.collection);\n    assert.ok(col1.length === 0);\n    assert.equal(counter, 2);\n  });\n\n  QUnit.test('model destroy removes from all collections', function(assert) {\n    assert.expect(3);\n    var m = new Backbone.Model({id: 5, title: 'Othello'});\n    m.sync = function(method, model, options) { options.success(); };\n    var col1 = new Backbone.Collection([m]);\n    var col2 = new Backbone.Collection([m]);\n    m.destroy();\n    assert.ok(col1.length === 0);\n    assert.ok(col2.length === 0);\n    assert.equal(undefined, m.collection);\n  });\n\n  QUnit.test('Collection: non-persisted model destroy removes from all collections', function(assert) {\n    assert.expect(3);\n    var m = new Backbone.Model({title: 'Othello'});\n    m.sync = function(method, model, options) { throw 'should not be called'; };\n    var col1 = new Backbone.Collection([m]);\n    var col2 = new Backbone.Collection([m]);\n    m.destroy();\n    assert.ok(col1.length === 0);\n    assert.ok(col2.length === 0);\n    assert.equal(undefined, m.collection);\n  });\n\n  QUnit.test('fetch', function(assert) {\n    assert.expect(4);\n    var collection = new Backbone.Collection;\n    collection.url = '/test';\n    collection.fetch();\n    assert.equal(this.syncArgs.method, 'read');\n    assert.equal(this.syncArgs.model, collection);\n    assert.equal(this.syncArgs.options.parse, true);\n\n    collection.fetch({parse: false});\n    assert.equal(this.syncArgs.options.parse, false);\n  });\n\n  QUnit.test('fetch with an error response triggers an error event', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection();\n    collection.on('error', function() {\n      assert.ok(true);\n    });\n    collection.sync = function(method, model, options) { options.error(); };\n    collection.fetch();\n  });\n\n  QUnit.test('#3283 - fetch with an error response calls error with context', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection();\n    var obj = {};\n    var options = {\n      context: obj,\n      error: function() {\n        assert.equal(this, obj);\n      }\n    };\n    collection.sync = function(method, model, opts) {\n      opts.error.call(opts.context);\n    };\n    collection.fetch(options);\n  });\n\n  QUnit.test('ensure fetch only parses once', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection;\n    var counter = 0;\n    collection.parse = function(models) {\n      counter++;\n      return models;\n    };\n    collection.url = '/test';\n    collection.fetch();\n    this.syncArgs.options.success([]);\n    assert.equal(counter, 1);\n  });\n\n  QUnit.test('create', function(assert) {\n    assert.expect(4);\n    var collection = new Backbone.Collection;\n    collection.url = '/test';\n    var model = collection.create({label: 'f'}, {wait: true});\n    assert.equal(this.syncArgs.method, 'create');\n    assert.equal(this.syncArgs.model, model);\n    assert.equal(model.get('label'), 'f');\n    assert.equal(model.collection, collection);\n  });\n\n  QUnit.test('create with validate:true enforces validation', function(assert) {\n    assert.expect(3);\n    var ValidatingModel = Backbone.Model.extend({\n      validate: function(attrs) {\n        return 'fail';\n      }\n    });\n    var ValidatingCollection = Backbone.Collection.extend({\n      model: ValidatingModel\n    });\n    var collection = new ValidatingCollection();\n    collection.on('invalid', function(coll, error, options) {\n      assert.equal(error, 'fail');\n      assert.equal(options.validationError, 'fail');\n    });\n    assert.equal(collection.create({foo: 'bar'}, {validate: true}), false);\n  });\n\n  QUnit.test('create will pass extra options to success callback', function(assert) {\n    assert.expect(1);\n    var Model = Backbone.Model.extend({\n      sync: function(method, model, options) {\n        _.extend(options, {specialSync: true});\n        return Backbone.Model.prototype.sync.call(this, method, model, options);\n      }\n    });\n\n    var Collection = Backbone.Collection.extend({\n      model: Model,\n      url: '/test'\n    });\n\n    var collection = new Collection;\n\n    var success = function(model, response, options) {\n      assert.ok(options.specialSync, 'Options were passed correctly to callback');\n    };\n\n    collection.create({}, {success: success});\n    this.ajaxSettings.success();\n  });\n\n  QUnit.test('create with wait:true should not call collection.parse', function(assert) {\n    assert.expect(0);\n    var Collection = Backbone.Collection.extend({\n      url: '/test',\n      parse: function() {\n        assert.ok(false);\n      }\n    });\n\n    var collection = new Collection;\n\n    collection.create({}, {wait: true});\n    this.ajaxSettings.success();\n  });\n\n  QUnit.test('a failing create returns model with errors', function(assert) {\n    var ValidatingModel = Backbone.Model.extend({\n      validate: function(attrs) {\n        return 'fail';\n      }\n    });\n    var ValidatingCollection = Backbone.Collection.extend({\n      model: ValidatingModel\n    });\n    var collection = new ValidatingCollection();\n    var m = collection.create({foo: 'bar'});\n    assert.equal(m.validationError, 'fail');\n    assert.equal(collection.length, 1);\n  });\n\n  QUnit.test('failing create with wait:true triggers error event (#4262)', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection;\n    collection.url = '/test';\n    collection.on('error', function() { assert.ok(true); });\n    var model = collection.create({id: '1'}, {wait: true});\n    model.on('error', function() { assert.ok(true); });\n    this.ajaxSettings.error();\n  });\n\n  QUnit.test('successful create with wait:true triggers success event (#4262)', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection;\n    collection.url = '/test';\n    collection.on('sync', function() { assert.ok(true); });\n    var model = collection.create({id: '1'}, {wait: true});\n    model.on('sync', function() { assert.ok(true); });\n    this.ajaxSettings.success();\n  });\n\n  QUnit.test('successful create with wait:true drops special error listener (#4284)', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection;\n    collection.url = '/test';\n    collection.on('error', function() { assert.ok(true); });\n    var model = collection.create({id: '1'}, {wait: true});\n    this.ajaxSettings.success();\n    model.trigger('error');\n  });\n\n  QUnit.test('failing create pre-existing with wait:true triggers once (#4262)', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model;\n    var collection = new Backbone.Collection([model]);\n    collection.url = '/test';\n    collection.on('error', function() { assert.ok(true); });\n    collection.create(model, {wait: true});\n    this.ajaxSettings.error();\n  });\n\n  QUnit.test('successful create pre-existing with wait:true preserves other error bindings (#4262)', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model;\n    var collection = new Backbone.Collection([model]);\n    collection.url = '/test';\n    model.on('error', function() { assert.ok(true); });\n    collection.create(model, {wait: true});\n    this.ajaxSettings.success();\n    model.trigger('error');\n  });\n\n  QUnit.test('initialize', function(assert) {\n    assert.expect(1);\n    var Collection = Backbone.Collection.extend({\n      initialize: function() {\n        this.one = 1;\n      }\n    });\n    var coll = new Collection;\n    assert.equal(coll.one, 1);\n  });\n\n  QUnit.test('preinitialize', function(assert) {\n    assert.expect(1);\n    var Collection = Backbone.Collection.extend({\n      preinitialize: function() {\n        this.one = 1;\n      }\n    });\n    var coll = new Collection;\n    assert.equal(coll.one, 1);\n  });\n\n  QUnit.test('preinitialize occurs before the collection is set up', function(assert) {\n    assert.expect(2);\n    var Collection = Backbone.Collection.extend({\n      preinitialize: function() {\n        assert.notEqual(this.model, FooModel);\n      }\n    });\n    var FooModel = Backbone.Model.extend({id: 'foo'});\n    var coll = new Collection({}, {\n      model: FooModel\n    });\n    assert.equal(coll.model, FooModel);\n  });\n\n  QUnit.test('toJSON', function(assert) {\n    assert.expect(1);\n    assert.equal(JSON.stringify(col), '[{\"id\":3,\"label\":\"a\"},{\"id\":2,\"label\":\"b\"},{\"id\":1,\"label\":\"c\"},{\"id\":0,\"label\":\"d\"}]');\n  });\n\n  QUnit.test('where and findWhere', function(assert) {\n    assert.expect(8);\n    var model = new Backbone.Model({a: 1});\n    var coll = new Backbone.Collection([\n      model,\n      {a: 1},\n      {a: 1, b: 2},\n      {a: 2, b: 2},\n      {a: 3}\n    ]);\n    assert.equal(coll.where({a: 1}).length, 3);\n    assert.equal(coll.where({a: 2}).length, 1);\n    assert.equal(coll.where({a: 3}).length, 1);\n    assert.equal(coll.where({b: 1}).length, 0);\n    assert.equal(coll.where({b: 2}).length, 2);\n    assert.equal(coll.where({a: 1, b: 2}).length, 1);\n    assert.equal(coll.findWhere({a: 1}), model);\n    assert.equal(coll.findWhere({a: 4}), void 0);\n  });\n\n  QUnit.test('mixin', function(assert) {\n    Backbone.Collection.mixin({\n      sum: function(models, iteratee) {\n        return _.reduce(models, function(s, m) {\n          return s + iteratee(m);\n        }, 0);\n      }\n    });\n\n    var coll = new Backbone.Collection([\n      {a: 1},\n      {a: 1, b: 2},\n      {a: 2, b: 2},\n      {a: 3}\n    ]);\n\n    assert.equal(coll.sum(function(m) {\n      return m.get('a');\n    }), 7);\n  });\n\n  QUnit.test('Underscore methods', function(assert) {\n    assert.expect(21);\n    assert.equal(col.map(function(model){ return model.get('label'); }).join(' '), 'a b c d');\n    assert.equal(col.some(function(model){ return model.id === 100; }), false);\n    assert.equal(col.some(function(model){ return model.id === 0; }), true);\n    assert.equal(col.reduce(function(m1, m2) {return m1.id > m2.id ? m1 : m2;}).id, 3);\n    assert.equal(col.reduceRight(function(m1, m2) {return m1.id > m2.id ? m1 : m2;}).id, 3);\n    assert.equal(col.indexOf(b), 1);\n    assert.equal(col.size(), 4);\n    assert.equal(col.rest().length, 3);\n    assert.ok(!_.includes(col.rest(), a));\n    assert.ok(_.includes(col.rest(), d));\n    assert.ok(!col.isEmpty());\n    assert.ok(!_.includes(col.without(d), d));\n\n    var wrapped = col.chain();\n    assert.equal(wrapped.map('id').max().value(), 3);\n    assert.equal(wrapped.map('id').min().value(), 0);\n    assert.deepEqual(\n      wrapped\n      .filter(function(o){ return o.id % 2 === 0; })\n      .map(function(o){ return o.id * 2; })\n      .value(),\n      [4, 0]\n    );\n    assert.deepEqual(col.difference([c, d]), [a, b]);\n    assert.ok(col.includes(col.sample()));\n\n    var first = col.first();\n    assert.deepEqual(col.groupBy(function(model){ return model.id; })[first.id], [first]);\n    assert.deepEqual(col.countBy(function(model){ return model.id; }), {0: 1, 1: 1, 2: 1, 3: 1});\n    assert.deepEqual(col.sortBy(function(model){ return model.id; })[0], col.at(3));\n    assert.ok(col.indexBy('id')[first.id] === first);\n  });\n\n  QUnit.test('Underscore methods with object-style and property-style iteratee', function(assert) {\n    assert.expect(26);\n    var model = new Backbone.Model({a: 4, b: 1, e: 3});\n    var coll = new Backbone.Collection([\n      {a: 1, b: 1},\n      {a: 2, b: 1, c: 1},\n      {a: 3, b: 1},\n      model\n    ]);\n    assert.equal(coll.find({a: 0}), undefined);\n    assert.deepEqual(coll.find({a: 4}), model);\n    assert.equal(coll.find('d'), undefined);\n    assert.deepEqual(coll.find('e'), model);\n    assert.equal(coll.filter({a: 0}), false);\n    assert.deepEqual(coll.filter({a: 4}), [model]);\n    assert.equal(coll.some({a: 0}), false);\n    assert.equal(coll.some({a: 1}), true);\n    assert.equal(coll.reject({a: 0}).length, 4);\n    assert.deepEqual(coll.reject({a: 4}), _.without(coll.models, model));\n    assert.equal(coll.every({a: 0}), false);\n    assert.equal(coll.every({b: 1}), true);\n    assert.deepEqual(coll.partition({a: 0})[0], []);\n    assert.deepEqual(coll.partition({a: 0})[1], coll.models);\n    assert.deepEqual(coll.partition({a: 4})[0], [model]);\n    assert.deepEqual(coll.partition({a: 4})[1], _.without(coll.models, model));\n    assert.deepEqual(coll.map({a: 2}), [false, true, false, false]);\n    assert.deepEqual(coll.map('a'), [1, 2, 3, 4]);\n    assert.deepEqual(coll.sortBy('a')[3], model);\n    assert.deepEqual(coll.sortBy('e')[0], model);\n    assert.deepEqual(coll.countBy({a: 4}), {'false': 3, 'true': 1});\n    assert.deepEqual(coll.countBy('d'), {undefined: 4});\n    assert.equal(coll.findIndex({b: 1}), 0);\n    assert.equal(coll.findIndex({b: 9}), -1);\n    assert.equal(coll.findLastIndex({b: 1}), 3);\n    assert.equal(coll.findLastIndex({b: 9}), -1);\n  });\n\n  QUnit.test('reset', function(assert) {\n    assert.expect(16);\n\n    var resetCount = 0;\n    var models = col.models;\n    col.on('reset', function() { resetCount += 1; });\n    col.reset([]);\n    assert.equal(resetCount, 1);\n    assert.equal(col.length, 0);\n    assert.equal(col.last(), null);\n    col.reset(models);\n    assert.equal(resetCount, 2);\n    assert.equal(col.length, 4);\n    assert.equal(col.last(), d);\n    col.reset(_.map(models, function(m){ return m.attributes; }));\n    assert.equal(resetCount, 3);\n    assert.equal(col.length, 4);\n    assert.ok(col.last() !== d);\n    assert.ok(_.isEqual(col.last().attributes, d.attributes));\n    col.reset();\n    assert.equal(col.length, 0);\n    assert.equal(resetCount, 4);\n\n    var f = new Backbone.Model({id: 20, label: 'f'});\n    col.reset([undefined, f]);\n    assert.equal(col.length, 2);\n    assert.equal(resetCount, 5);\n\n    col.reset(new Array(4));\n    assert.equal(col.length, 4);\n    assert.equal(resetCount, 6);\n  });\n\n  QUnit.test('reset with different values', function(assert) {\n    var collection = new Backbone.Collection({id: 1});\n    collection.reset({id: 1, a: 1});\n    assert.equal(collection.get(1).get('a'), 1);\n  });\n\n  QUnit.test('same references in reset', function(assert) {\n    var model = new Backbone.Model({id: 1});\n    var collection = new Backbone.Collection({id: 1});\n    collection.reset(model);\n    assert.equal(collection.get(1), model);\n  });\n\n  QUnit.test('reset passes caller options', function(assert) {\n    assert.expect(3);\n    var Model = Backbone.Model.extend({\n      initialize: function(attrs, options) {\n        this.modelParameter = options.modelParameter;\n      }\n    });\n    var collection = new (Backbone.Collection.extend({model: Model}))();\n    collection.reset([{astring: 'green', anumber: 1}, {astring: 'blue', anumber: 2}], {modelParameter: 'model parameter'});\n    assert.equal(collection.length, 2);\n    collection.each(function(model) {\n      assert.equal(model.modelParameter, 'model parameter');\n    });\n  });\n\n  QUnit.test('reset does not alter options by reference', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection([{id: 1}]);\n    var origOpts = {};\n    collection.on('reset', function(coll, opts){\n      assert.equal(origOpts.previousModels, undefined);\n      assert.equal(opts.previousModels[0].id, 1);\n    });\n    collection.reset([], origOpts);\n  });\n\n  QUnit.test('trigger custom events on models', function(assert) {\n    assert.expect(1);\n    var fired = null;\n    a.on('custom', function() { fired = true; });\n    a.trigger('custom');\n    assert.equal(fired, true);\n  });\n\n  QUnit.test('add does not alter arguments', function(assert) {\n    assert.expect(2);\n    var attrs = {};\n    var models = [attrs];\n    new Backbone.Collection().add(models);\n    assert.equal(models.length, 1);\n    assert.ok(attrs === models[0]);\n  });\n\n  QUnit.test('#714: access `model.collection` in a brand new model.', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection;\n    collection.url = '/test';\n    var Model = Backbone.Model.extend({\n      set: function(attrs) {\n        assert.equal(attrs.prop, 'value');\n        assert.equal(this.collection, collection);\n        return this;\n      }\n    });\n    collection.model = Model;\n    collection.create({prop: 'value'});\n  });\n\n  QUnit.test('#574, remove its own reference to the .models array.', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection([\n      {id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}\n    ]);\n    assert.equal(collection.length, 6);\n    collection.remove(collection.models);\n    assert.equal(collection.length, 0);\n  });\n\n  QUnit.test('#861, adding models to a collection which do not pass validation, with validate:true', function(assert) {\n    assert.expect(2);\n    var Model = Backbone.Model.extend({\n      validate: function(attrs) {\n        if (attrs.id === 3) return \"id can't be 3\";\n      }\n    });\n\n    var Collection = Backbone.Collection.extend({\n      model: Model\n    });\n\n    var collection = new Collection;\n    collection.on('invalid', function() { assert.ok(true); });\n\n    collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}], {validate: true});\n    assert.deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);\n  });\n\n  QUnit.test('Invalid models are discarded with validate:true.', function(assert) {\n    assert.expect(5);\n    var collection = new Backbone.Collection;\n    collection.on('test', function() { assert.ok(true); });\n    collection.model = Backbone.Model.extend({\n      validate: function(attrs){ if (!attrs.valid) return 'invalid'; }\n    });\n    var model = new collection.model({id: 1, valid: true});\n    collection.add([model, {id: 2}], {validate: true});\n    model.trigger('test');\n    assert.ok(collection.get(model.cid));\n    assert.ok(collection.get(1));\n    assert.ok(!collection.get(2));\n    assert.equal(collection.length, 1);\n  });\n\n  QUnit.test('multiple copies of the same model', function(assert) {\n    assert.expect(3);\n    var collection = new Backbone.Collection();\n    var model = new Backbone.Model();\n    collection.add([model, model]);\n    assert.equal(collection.length, 1);\n    collection.add([{id: 1}, {id: 1}]);\n    assert.equal(collection.length, 2);\n    assert.equal(collection.last().id, 1);\n  });\n\n  QUnit.test('#964 - collection.get return inconsistent', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection();\n    assert.ok(collection.get(null) === undefined);\n    assert.ok(collection.get() === undefined);\n  });\n\n  QUnit.test('#1112 - passing options.model sets collection.model', function(assert) {\n    assert.expect(2);\n    var Model = Backbone.Model.extend({});\n    var collection = new Backbone.Collection([{id: 1}], {model: Model});\n    assert.ok(collection.model === Model);\n    assert.ok(collection.at(0) instanceof Model);\n  });\n\n  QUnit.test('null and undefined are invalid ids.', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model({id: 1});\n    var collection = new Backbone.Collection([model]);\n    model.set({id: null});\n    assert.ok(!collection.get('null'));\n    model.set({id: 1});\n    model.set({id: undefined});\n    assert.ok(!collection.get('undefined'));\n  });\n\n  QUnit.test('falsy comparator', function(assert) {\n    assert.expect(4);\n    var Col = Backbone.Collection.extend({\n      comparator: function(model){ return model.id; }\n    });\n    var collection = new Col();\n    var colFalse = new Col(null, {comparator: false});\n    var colNull = new Col(null, {comparator: null});\n    var colUndefined = new Col(null, {comparator: undefined});\n    assert.ok(collection.comparator);\n    assert.ok(!colFalse.comparator);\n    assert.ok(!colNull.comparator);\n    assert.ok(colUndefined.comparator);\n  });\n\n  QUnit.test('#1355 - `options` is passed to success callbacks', function(assert) {\n    assert.expect(2);\n    var m = new Backbone.Model({x: 1});\n    var collection = new Backbone.Collection();\n    var opts = {\n      opts: true,\n      success: function(coll, resp, options) {\n        assert.ok(options.opts);\n      }\n    };\n    collection.sync = m.sync = function( method, coll, options ){\n      options.success({});\n    };\n    collection.fetch(opts);\n    collection.create(m, opts);\n  });\n\n  QUnit.test(\"#1412 - Trigger 'request' and 'sync' events.\", function(assert) {\n    assert.expect(4);\n    var collection = new Backbone.Collection;\n    collection.url = '/test';\n    Backbone.ajax = function(settings){ settings.success(); };\n\n    collection.on('request', function(obj, xhr, options) {\n      assert.ok(obj === collection, \"collection has correct 'request' event after fetching\");\n    });\n    collection.on('sync', function(obj, response, options) {\n      assert.ok(obj === collection, \"collection has correct 'sync' event after fetching\");\n    });\n    collection.fetch();\n    collection.off();\n\n    collection.on('request', function(obj, xhr, options) {\n      assert.ok(obj === collection.get(1), \"collection has correct 'request' event after one of its models save\");\n    });\n    collection.on('sync', function(obj, response, options) {\n      assert.ok(obj === collection.get(1), \"collection has correct 'sync' event after one of its models save\");\n    });\n    collection.create({id: 1});\n    collection.off();\n  });\n\n  QUnit.test('#3283 - fetch, create calls success with context', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection;\n    collection.url = '/test';\n    Backbone.ajax = function(settings) {\n      settings.success.call(settings.context);\n    };\n    var obj = {};\n    var options = {\n      context: obj,\n      success: function() {\n        assert.equal(this, obj);\n      }\n    };\n\n    collection.fetch(options);\n    collection.create({id: 1}, options);\n  });\n\n  QUnit.test('#1447 - create with wait adds model.', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection;\n    var model = new Backbone.Model;\n    model.sync = function(method, m, options){ options.success(); };\n    collection.on('add', function(){ assert.ok(true); });\n    collection.create(model, {wait: true});\n  });\n\n  QUnit.test('#1448 - add sorts collection after merge.', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([\n      {id: 1, x: 1},\n      {id: 2, x: 2}\n    ]);\n    collection.comparator = function(model){ return model.get('x'); };\n    collection.add({id: 1, x: 3}, {merge: true});\n    assert.deepEqual(collection.pluck('id'), [2, 1]);\n  });\n\n  QUnit.test('#1655 - groupBy can be used with a string argument.', function(assert) {\n    assert.expect(3);\n    var collection = new Backbone.Collection([{x: 1}, {x: 2}]);\n    var grouped = collection.groupBy('x');\n    assert.strictEqual(_.keys(grouped).length, 2);\n    assert.strictEqual(grouped[1][0].get('x'), 1);\n    assert.strictEqual(grouped[2][0].get('x'), 2);\n  });\n\n  QUnit.test('#1655 - sortBy can be used with a string argument.', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([{x: 3}, {x: 1}, {x: 2}]);\n    var values = _.map(collection.sortBy('x'), function(model) {\n      return model.get('x');\n    });\n    assert.deepEqual(values, [1, 2, 3]);\n  });\n\n  QUnit.test('#1604 - Removal during iteration.', function(assert) {\n    assert.expect(0);\n    var collection = new Backbone.Collection([{}, {}]);\n    collection.on('add', function() {\n      collection.at(0).destroy();\n    });\n    collection.add({}, {at: 0});\n  });\n\n  QUnit.test('#1638 - `sort` during `add` triggers correctly.', function(assert) {\n    var collection = new Backbone.Collection;\n    collection.comparator = function(model) { return model.get('x'); };\n    var added = [];\n    collection.on('add', function(model) {\n      model.set({x: 3});\n      collection.sort();\n      added.push(model.id);\n    });\n    collection.add([{id: 1, x: 1}, {id: 2, x: 2}]);\n    assert.deepEqual(added, [1, 2]);\n  });\n\n  QUnit.test('fetch parses models by default', function(assert) {\n    assert.expect(1);\n    var model = {};\n    var Collection = Backbone.Collection.extend({\n      url: 'test',\n      model: Backbone.Model.extend({\n        parse: function(resp) {\n          assert.strictEqual(resp, model);\n        }\n      })\n    });\n    new Collection().fetch();\n    this.ajaxSettings.success([model]);\n  });\n\n  QUnit.test(\"`sort` shouldn't always fire on `add`\", function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}], {\n      comparator: 'id'\n    });\n    collection.sort = function(){ assert.ok(true); };\n    collection.add([]);\n    collection.add({id: 1});\n    collection.add([{id: 2}, {id: 3}]);\n    collection.add({id: 4});\n  });\n\n  QUnit.test('#1407 parse option on constructor parses collection and models', function(assert) {\n    assert.expect(2);\n    var model = {\n      namespace: [{id: 1}, {id: 2}]\n    };\n    var Collection = Backbone.Collection.extend({\n      model: Backbone.Model.extend({\n        parse: function(m) {\n          m.name = 'test';\n          return m;\n        }\n      }),\n      parse: function(m) {\n        return m.namespace;\n      }\n    });\n    var collection = new Collection(model, {parse: true});\n\n    assert.equal(collection.length, 2);\n    assert.equal(collection.at(0).get('name'), 'test');\n  });\n\n  QUnit.test('#1407 parse option on reset parses collection and models', function(assert) {\n    assert.expect(2);\n    var model = {\n      namespace: [{id: 1}, {id: 2}]\n    };\n    var Collection = Backbone.Collection.extend({\n      model: Backbone.Model.extend({\n        parse: function(m) {\n          m.name = 'test';\n          return m;\n        }\n      }),\n      parse: function(m) {\n        return m.namespace;\n      }\n    });\n    var collection = new Collection();\n    collection.reset(model, {parse: true});\n\n    assert.equal(collection.length, 2);\n    assert.equal(collection.at(0).get('name'), 'test');\n  });\n\n\n  QUnit.test('Reset includes previous models in triggered event.', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    var collection = new Backbone.Collection([model]);\n    collection.on('reset', function(coll, options) {\n      assert.deepEqual(options.previousModels, [model]);\n    });\n    collection.reset([]);\n  });\n\n  QUnit.test('set', function(assert) {\n    var m1 = new Backbone.Model();\n    var m2 = new Backbone.Model({id: 2});\n    var m3 = new Backbone.Model();\n    var collection = new Backbone.Collection([m1, m2]);\n\n    // Test add/change/remove events\n    collection.on('add', function(model) {\n      assert.strictEqual(model, m3);\n    });\n    collection.on('change', function(model) {\n      assert.strictEqual(model, m2);\n    });\n    collection.on('remove', function(model) {\n      assert.strictEqual(model, m1);\n    });\n\n    // remove: false doesn't remove any models\n    collection.set([], {remove: false});\n    assert.strictEqual(collection.length, 2);\n\n    // add: false doesn't add any models\n    collection.set([m1, m2, m3], {add: false});\n    assert.strictEqual(collection.length, 2);\n\n    // merge: false doesn't change any models\n    collection.set([m1, {id: 2, a: 1}], {merge: false});\n    assert.strictEqual(m2.get('a'), void 0);\n\n    // add: false, remove: false only merges existing models\n    collection.set([m1, {id: 2, a: 0}, m3, {id: 4}], {add: false, remove: false});\n    assert.strictEqual(collection.length, 2);\n    assert.strictEqual(m2.get('a'), 0);\n\n    // default options add/remove/merge as appropriate\n    collection.set([{id: 2, a: 1}, m3]);\n    assert.strictEqual(collection.length, 2);\n    assert.strictEqual(m2.get('a'), 1);\n\n    // Test removing models not passing an argument\n    collection.off('remove').on('remove', function(model) {\n      assert.ok(model === m2 || model === m3);\n    });\n    collection.set([]);\n    assert.strictEqual(collection.length, 0);\n\n    // Test null models on set doesn't clear collection\n    collection.off();\n    collection.set([{id: 1}]);\n    collection.set();\n    assert.strictEqual(collection.length, 1);\n  });\n\n  QUnit.test('set with only cids', function(assert) {\n    assert.expect(3);\n    var m1 = new Backbone.Model;\n    var m2 = new Backbone.Model;\n    var collection = new Backbone.Collection;\n    collection.set([m1, m2]);\n    assert.equal(collection.length, 2);\n    collection.set([m1]);\n    assert.equal(collection.length, 1);\n    collection.set([m1, m1, m1, m2, m2], {remove: false});\n    assert.equal(collection.length, 2);\n  });\n\n  QUnit.test('set with only idAttribute', function(assert) {\n    assert.expect(3);\n    var m1 = {_id: 1};\n    var m2 = {_id: 2};\n    var Col = Backbone.Collection.extend({\n      model: Backbone.Model.extend({\n        idAttribute: '_id'\n      })\n    });\n    var collection = new Col;\n    collection.set([m1, m2]);\n    assert.equal(collection.length, 2);\n    collection.set([m1]);\n    assert.equal(collection.length, 1);\n    collection.set([m1, m1, m1, m2, m2], {remove: false});\n    assert.equal(collection.length, 2);\n  });\n\n  QUnit.test('set + merge with default values defined', function(assert) {\n    var Model = Backbone.Model.extend({\n      defaults: {\n        key: 'value'\n      }\n    });\n    var m = new Model({id: 1});\n    var collection = new Backbone.Collection([m], {model: Model});\n    assert.equal(collection.first().get('key'), 'value');\n\n    collection.set({id: 1, key: 'other'});\n    assert.equal(collection.first().get('key'), 'other');\n\n    collection.set({id: 1, other: 'value'});\n    assert.equal(collection.first().get('key'), 'other');\n    assert.equal(collection.length, 1);\n  });\n\n  QUnit.test('merge without mutation', function(assert) {\n    var Model = Backbone.Model.extend({\n      initialize: function(attrs, options) {\n        if (attrs.child) {\n          this.set('child', new Model(attrs.child, options), options);\n        }\n      }\n    });\n    var Collection = Backbone.Collection.extend({model: Model});\n    var data = [{id: 1, child: {id: 2}}];\n    var collection = new Collection(data);\n    assert.equal(collection.first().id, 1);\n    collection.set(data);\n    assert.equal(collection.first().id, 1);\n    collection.set([{id: 2, child: {id: 2}}].concat(data));\n    assert.deepEqual(collection.pluck('id'), [2, 1]);\n  });\n\n  QUnit.test('`set` and model level `parse`', function(assert) {\n    var Model = Backbone.Model.extend({});\n    var Collection = Backbone.Collection.extend({\n      model: Model,\n      parse: function(res) { return _.map(res.models, 'model'); }\n    });\n    var model = new Model({id: 1});\n    var collection = new Collection(model);\n    collection.set({models: [\n      {model: {id: 1}},\n      {model: {id: 2}}\n    ]}, {parse: true});\n    assert.equal(collection.first(), model);\n  });\n\n  QUnit.test('`set` data is only parsed once', function(assert) {\n    var collection = new Backbone.Collection();\n    collection.model = Backbone.Model.extend({\n      parse: function(data) {\n        assert.equal(data.parsed, void 0);\n        data.parsed = true;\n        return data;\n      }\n    });\n    collection.set({}, {parse: true});\n  });\n\n  QUnit.test('`set` matches input order in the absence of a comparator', function(assert) {\n    var one = new Backbone.Model({id: 1});\n    var two = new Backbone.Model({id: 2});\n    var three = new Backbone.Model({id: 3});\n    var collection = new Backbone.Collection([one, two, three]);\n    collection.set([{id: 3}, {id: 2}, {id: 1}]);\n    assert.deepEqual(collection.models, [three, two, one]);\n    collection.set([{id: 1}, {id: 2}]);\n    assert.deepEqual(collection.models, [one, two]);\n    collection.set([two, three, one]);\n    assert.deepEqual(collection.models, [two, three, one]);\n    collection.set([{id: 1}, {id: 2}], {remove: false});\n    assert.deepEqual(collection.models, [two, three, one]);\n    collection.set([{id: 1}, {id: 2}, {id: 3}], {merge: false});\n    assert.deepEqual(collection.models, [one, two, three]);\n    collection.set([three, two, one, {id: 4}], {add: false});\n    assert.deepEqual(collection.models, [one, two, three]);\n  });\n\n  QUnit.test('#1894 - Push should not trigger a sort', function(assert) {\n    assert.expect(0);\n    var Collection = Backbone.Collection.extend({\n      comparator: 'id',\n      sort: function() { assert.ok(false); }\n    });\n    new Collection().push({id: 1});\n  });\n\n  QUnit.test('#2428 - push duplicate models, return the correct one', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection;\n    var model1 = collection.push({id: 101});\n    var model2 = collection.push({id: 101});\n    assert.ok(model2.cid === model1.cid);\n  });\n\n  QUnit.test('`set` with non-normal id', function(assert) {\n    var Collection = Backbone.Collection.extend({\n      model: Backbone.Model.extend({idAttribute: '_id'})\n    });\n    var collection = new Collection({_id: 1});\n    collection.set([{_id: 1, a: 1}], {add: false});\n    assert.equal(collection.first().get('a'), 1);\n  });\n\n  QUnit.test('#1894 - `sort` can optionally be turned off', function(assert) {\n    assert.expect(0);\n    var Collection = Backbone.Collection.extend({\n      comparator: 'id',\n      sort: function() { assert.ok(false); }\n    });\n    new Collection().add({id: 1}, {sort: false});\n  });\n\n  QUnit.test('#1915 - `parse` data in the right order in `set`', function(assert) {\n    var collection = new (Backbone.Collection.extend({\n      parse: function(data) {\n        assert.strictEqual(data.status, 'ok');\n        return data.data;\n      }\n    }));\n    var res = {status: 'ok', data: [{id: 1}]};\n    collection.set(res, {parse: true});\n  });\n\n  QUnit.test('#1939 - `parse` is passed `options`', function(assert) {\n    var done = assert.async();\n    assert.expect(1);\n    var collection = new (Backbone.Collection.extend({\n      url: '/',\n      parse: function(data, options) {\n        assert.strictEqual(options.xhr.someHeader, 'headerValue');\n        return data;\n      }\n    }));\n    var ajax = Backbone.ajax;\n    Backbone.ajax = function(params) {\n      _.defer(params.success, []);\n      return {someHeader: 'headerValue'};\n    };\n    collection.fetch({\n      success: function() { done(); }\n    });\n    Backbone.ajax = ajax;\n  });\n\n  QUnit.test('fetch will pass extra options to success callback', function(assert) {\n    assert.expect(1);\n    var SpecialSyncCollection = Backbone.Collection.extend({\n      url: '/test',\n      sync: function(method, collection, options) {\n        _.extend(options, {specialSync: true});\n        return Backbone.Collection.prototype.sync.call(this, method, collection, options);\n      }\n    });\n\n    var collection = new SpecialSyncCollection();\n\n    var onSuccess = function(coll, resp, options) {\n      assert.ok(options.specialSync, 'Options were passed correctly to callback');\n    };\n\n    collection.fetch({success: onSuccess});\n    this.ajaxSettings.success();\n  });\n\n  QUnit.test('`add` only `sort`s when necessary', function(assert) {\n    assert.expect(2);\n    var collection = new (Backbone.Collection.extend({\n      comparator: 'a'\n    }))([{id: 1}, {id: 2}, {id: 3}]);\n    collection.on('sort', function() { assert.ok(true); });\n    collection.add({id: 4}); // do sort, new model\n    collection.add({id: 1, a: 1}, {merge: true}); // do sort, comparator change\n    collection.add({id: 1, b: 1}, {merge: true}); // don't sort, no comparator change\n    collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no comparator change\n    collection.add(collection.models); // don't sort, nothing new\n    collection.add(collection.models, {merge: true}); // don't sort\n  });\n\n  QUnit.test('`add` only `sort`s when necessary with comparator function', function(assert) {\n    assert.expect(3);\n    var collection = new (Backbone.Collection.extend({\n      comparator: function(m1, m2) {\n        return m1.get('a') > m2.get('a') ? 1 : m1.get('a') < m2.get('a') ? -1 : 0;\n      }\n    }))([{id: 1}, {id: 2}, {id: 3}]);\n    collection.on('sort', function() { assert.ok(true); });\n    collection.add({id: 4}); // do sort, new model\n    collection.add({id: 1, a: 1}, {merge: true}); // do sort, model change\n    collection.add({id: 1, b: 1}, {merge: true}); // do sort, model change\n    collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no model change\n    collection.add(collection.models); // don't sort, nothing new\n    collection.add(collection.models, {merge: true}); // don't sort\n  });\n\n  QUnit.test('Attach options to collection.', function(assert) {\n    assert.expect(2);\n    var Model = Backbone.Model;\n    var comparator = function(){};\n\n    var collection = new Backbone.Collection([], {\n      model: Model,\n      comparator: comparator\n    });\n\n    assert.ok(collection.model === Model);\n    assert.ok(collection.comparator === comparator);\n  });\n\n  QUnit.test('Pass falsey for `models` for empty Col with `options`', function(assert) {\n    assert.expect(9);\n    var opts = {a: 1, b: 2};\n    _.forEach([undefined, null, false], function(falsey) {\n      var Collection = Backbone.Collection.extend({\n        initialize: function(models, options) {\n          assert.strictEqual(models, falsey);\n          assert.strictEqual(options, opts);\n        }\n      });\n\n      var collection = new Collection(falsey, opts);\n      assert.strictEqual(collection.length, 0);\n    });\n  });\n\n  QUnit.test('`add` overrides `set` flags', function(assert) {\n    var collection = new Backbone.Collection();\n    collection.once('add', function(model, coll, options) {\n      coll.add({id: 2}, options);\n    });\n    collection.set({id: 1});\n    assert.equal(collection.length, 2);\n  });\n\n  QUnit.test('#2606 - Collection#create, success arguments', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection;\n    collection.url = 'test';\n    collection.create({}, {\n      success: function(model, resp, options) {\n        assert.strictEqual(resp, 'response');\n      }\n    });\n    this.ajaxSettings.success('response');\n  });\n\n  QUnit.test('#2612 - nested `parse` works with `Collection#set`', function(assert) {\n\n    var Job = Backbone.Model.extend({\n      constructor: function() {\n        this.items = new Items();\n        Backbone.Model.apply(this, arguments);\n      },\n      parse: function(attrs) {\n        this.items.set(attrs.items, {parse: true});\n        return _.omit(attrs, 'items');\n      }\n    });\n\n    var Item = Backbone.Model.extend({\n      constructor: function() {\n        this.subItems = new Backbone.Collection();\n        Backbone.Model.apply(this, arguments);\n      },\n      parse: function(attrs) {\n        this.subItems.set(attrs.subItems, {parse: true});\n        return _.omit(attrs, 'subItems');\n      }\n    });\n\n    var Items = Backbone.Collection.extend({\n      model: Item\n    });\n\n    var data = {\n      name: 'JobName',\n      id: 1,\n      items: [{\n        id: 1,\n        name: 'Sub1',\n        subItems: [\n          {id: 1, subName: 'One'},\n          {id: 2, subName: 'Two'}\n        ]\n      }, {\n        id: 2,\n        name: 'Sub2',\n        subItems: [\n          {id: 3, subName: 'Three'},\n          {id: 4, subName: 'Four'}\n        ]\n      }]\n    };\n\n    var newData = {\n      name: 'NewJobName',\n      id: 1,\n      items: [{\n        id: 1,\n        name: 'NewSub1',\n        subItems: [\n          {id: 1, subName: 'NewOne'},\n          {id: 2, subName: 'NewTwo'}\n        ]\n      }, {\n        id: 2,\n        name: 'NewSub2',\n        subItems: [\n          {id: 3, subName: 'NewThree'},\n          {id: 4, subName: 'NewFour'}\n        ]\n      }]\n    };\n\n    var job = new Job(data, {parse: true});\n    assert.equal(job.get('name'), 'JobName');\n    assert.equal(job.items.at(0).get('name'), 'Sub1');\n    assert.equal(job.items.length, 2);\n    assert.equal(job.items.get(1).subItems.get(1).get('subName'), 'One');\n    assert.equal(job.items.get(2).subItems.get(3).get('subName'), 'Three');\n    job.set(job.parse(newData, {parse: true}));\n    assert.equal(job.get('name'), 'NewJobName');\n    assert.equal(job.items.at(0).get('name'), 'NewSub1');\n    assert.equal(job.items.length, 2);\n    assert.equal(job.items.get(1).subItems.get(1).get('subName'), 'NewOne');\n    assert.equal(job.items.get(2).subItems.get(3).get('subName'), 'NewThree');\n  });\n\n  QUnit.test('_addReference binds all collection events & adds to the lookup hashes', function(assert) {\n    assert.expect(8);\n\n    var calls = {add: 0, remove: 0};\n\n    var Collection = Backbone.Collection.extend({\n\n      _addReference: function(model) {\n        Backbone.Collection.prototype._addReference.apply(this, arguments);\n        calls.add++;\n        assert.equal(model, this._byId[model.id]);\n        assert.equal(model, this._byId[model.cid]);\n        assert.equal(model._events.all.length, 1);\n      },\n\n      _removeReference: function(model) {\n        Backbone.Collection.prototype._removeReference.apply(this, arguments);\n        calls.remove++;\n        assert.equal(this._byId[model.id], void 0);\n        assert.equal(this._byId[model.cid], void 0);\n        assert.equal(model.collection, void 0);\n      }\n\n    });\n\n    var collection = new Collection();\n    var model = collection.add({id: 1});\n    collection.remove(model);\n\n    assert.equal(calls.add, 1);\n    assert.equal(calls.remove, 1);\n  });\n\n  QUnit.test('Do not allow duplicate models to be `add`ed or `set`', function(assert) {\n    var collection = new Backbone.Collection();\n\n    collection.add([{id: 1}, {id: 1}]);\n    assert.equal(collection.length, 1);\n    assert.equal(collection.models.length, 1);\n\n    collection.set([{id: 1}, {id: 1}]);\n    assert.equal(collection.length, 1);\n    assert.equal(collection.models.length, 1);\n  });\n\n  QUnit.test('#3020: #set with {add: false} should not throw.', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection;\n    collection.set([{id: 1}], {add: false});\n    assert.strictEqual(collection.length, 0);\n    assert.strictEqual(collection.models.length, 0);\n  });\n\n  QUnit.test('create with wait, model instance, #3028', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection();\n    var model = new Backbone.Model({id: 1});\n    model.sync = function(){\n      assert.equal(this.collection, collection);\n    };\n    collection.create(model, {wait: true});\n  });\n\n  QUnit.test('modelId', function(assert) {\n    var Stooge = Backbone.Model.extend();\n    var StoogeCollection = Backbone.Collection.extend();\n\n    // Default to using `id` if `model::idAttribute` and `Collection::model::idAttribute` not present.\n    assert.equal(StoogeCollection.prototype.modelId({id: 1}), 1);\n\n    // Default to using `model::idAttribute` if present.\n    Stooge.prototype.idAttribute = '_id';\n    var model = new Stooge({_id: 1});\n    assert.equal(StoogeCollection.prototype.modelId(model.attributes, model.idAttribute), 1);\n\n    // Default to using `Collection::model::idAttribute` if model::idAttribute not present.\n    StoogeCollection.prototype.model = Stooge;\n    assert.equal(StoogeCollection.prototype.modelId({_id: 1}), 1);\n\n  });\n\n  QUnit.test('Polymorphic models work with \"simple\" constructors', function(assert) {\n    var A = Backbone.Model.extend();\n    var B = Backbone.Model.extend();\n    var C = Backbone.Collection.extend({\n      model: function(attrs) {\n        return attrs.type === 'a' ? new A(attrs) : new B(attrs);\n      }\n    });\n    var collection = new C([{id: 1, type: 'a'}, {id: 2, type: 'b'}]);\n    assert.equal(collection.length, 2);\n    assert.ok(collection.at(0) instanceof A);\n    assert.equal(collection.at(0).id, 1);\n    assert.ok(collection.at(1) instanceof B);\n    assert.equal(collection.at(1).id, 2);\n  });\n\n  QUnit.test('Polymorphic models work with \"advanced\" constructors', function(assert) {\n    var A = Backbone.Model.extend({idAttribute: '_id'});\n    var B = Backbone.Model.extend({idAttribute: '_id'});\n    var C = Backbone.Collection.extend({\n      model: Backbone.Model.extend({\n        constructor: function(attrs) {\n          return attrs.type === 'a' ? new A(attrs) : new B(attrs);\n        },\n\n        idAttribute: '_id'\n      })\n    });\n    var collection = new C([{_id: 1, type: 'a'}, {_id: 2, type: 'b'}]);\n    assert.equal(collection.length, 2);\n    assert.ok(collection.at(0) instanceof A);\n    assert.equal(collection.at(0), collection.get(1));\n    assert.ok(collection.at(1) instanceof B);\n    assert.equal(collection.at(1), collection.get(2));\n\n    C = Backbone.Collection.extend({\n      model: function(attrs) {\n        return attrs.type === 'a' ? new A(attrs) : new B(attrs);\n      },\n\n      modelId: function(attrs) {\n        return attrs.type + '-' + attrs.id;\n      }\n    });\n    collection = new C([{id: 1, type: 'a'}, {id: 1, type: 'b'}]);\n    assert.equal(collection.length, 2);\n    assert.ok(collection.at(0) instanceof A);\n    assert.equal(collection.at(0), collection.get('a-1'));\n    assert.ok(collection.at(1) instanceof B);\n    assert.equal(collection.at(1), collection.get('b-1'));\n  });\n\n  QUnit.test('Collection with polymorphic models receives id from modelId using model instance idAttribute', function(assert) {\n    assert.expect(6);\n    // When the polymorphic models use 'id' for the idAttribute, all is fine.\n    var C1 = Backbone.Collection.extend({\n      model: function(attrs) {\n        return new Backbone.Model(attrs);\n      }\n    });\n    var c1 = new C1({id: 1});\n    assert.equal(c1.get(1).id, 1);\n    assert.equal(c1.modelId({id: 1}), 1);\n\n    // If the polymorphic models define their own idAttribute,\n    // the modelId method will use the model's idAttribute property before the\n    // collection's model constructor's.\n    var M = Backbone.Model.extend({\n      idAttribute: '_id'\n    });\n    var C2 = Backbone.Collection.extend({\n      model: function(attrs) {\n        return new M(attrs);\n      }\n    });\n    var c2 = new C2({_id: 1});\n    assert.equal(c2.get(1), c2.at(0));\n    assert.equal(c2.modelId(c2.at(0).attributes, c2.at(0).idAttribute), 1);\n    var m = new M({_id: 2});\n    c2.add(m);\n    assert.equal(c2.get(2), m);\n    assert.equal(c2.modelId(m.attributes, m.idAttribute), 2);\n  });\n\n  QUnit.test('Collection implements Iterable, values is default iterator function', function(assert) {\n    /* global Symbol */\n    var $$iterator = typeof Symbol === 'function' && Symbol.iterator;\n    // This test only applies to environments which define Symbol.iterator.\n    if (!$$iterator) {\n      assert.expect(0);\n      return;\n    }\n    assert.expect(2);\n    var collection = new Backbone.Collection([]);\n    assert.strictEqual(collection[$$iterator], collection.values);\n    var iterator = collection[$$iterator]();\n    assert.deepEqual(iterator.next(), {value: void 0, done: true});\n  });\n\n  QUnit.test('Collection.values iterates models in sorted order', function(assert) {\n    assert.expect(4);\n    var one = new Backbone.Model({id: 1});\n    var two = new Backbone.Model({id: 2});\n    var three = new Backbone.Model({id: 3});\n    var collection = new Backbone.Collection([one, two, three]);\n    var iterator = collection.values();\n    assert.strictEqual(iterator.next().value, one);\n    assert.strictEqual(iterator.next().value, two);\n    assert.strictEqual(iterator.next().value, three);\n    assert.strictEqual(iterator.next().value, void 0);\n  });\n\n  QUnit.test('Collection.keys iterates ids in sorted order', function(assert) {\n    assert.expect(4);\n    var one = new Backbone.Model({id: 1});\n    var two = new Backbone.Model({id: 2});\n    var three = new Backbone.Model({id: 3});\n    var collection = new Backbone.Collection([one, two, three]);\n    var iterator = collection.keys();\n    assert.strictEqual(iterator.next().value, 1);\n    assert.strictEqual(iterator.next().value, 2);\n    assert.strictEqual(iterator.next().value, 3);\n    assert.strictEqual(iterator.next().value, void 0);\n  });\n\n  QUnit.test('Collection.entries iterates ids and models in sorted order', function(assert) {\n    assert.expect(4);\n    var one = new Backbone.Model({id: 1});\n    var two = new Backbone.Model({id: 2});\n    var three = new Backbone.Model({id: 3});\n    var collection = new Backbone.Collection([one, two, three]);\n    var iterator = collection.entries();\n    assert.deepEqual(iterator.next().value, [1, one]);\n    assert.deepEqual(iterator.next().value, [2, two]);\n    assert.deepEqual(iterator.next().value, [3, three]);\n    assert.strictEqual(iterator.next().value, void 0);\n  });\n\n  QUnit.test('#3039 #3951: adding at index fires with correct at', function(assert) {\n    assert.expect(4);\n    var collection = new Backbone.Collection([{val: 0}, {val: 4}]);\n    collection.on('add', function(model, coll, options) {\n      assert.equal(model.get('val'), options.index);\n    });\n    collection.add([{val: 1}, {val: 2}, {val: 3}], {at: 1});\n    collection.add({val: 5}, {at: 10});\n  });\n\n  QUnit.test('#3039: index is not sent when at is not specified', function(assert) {\n    assert.expect(2);\n    var collection = new Backbone.Collection([{at: 0}]);\n    collection.on('add', function(model, coll, options) {\n      assert.equal(undefined, options.index);\n    });\n    collection.add([{at: 1}, {at: 2}]);\n  });\n\n  QUnit.test('#3199 - Order changing should trigger a sort', function(assert) {\n    assert.expect(1);\n    var one = new Backbone.Model({id: 1});\n    var two = new Backbone.Model({id: 2});\n    var three = new Backbone.Model({id: 3});\n    var collection = new Backbone.Collection([one, two, three]);\n    collection.on('sort', function() {\n      assert.ok(true);\n    });\n    collection.set([{id: 3}, {id: 2}, {id: 1}]);\n  });\n\n  QUnit.test('#3199 - Adding a model should trigger a sort', function(assert) {\n    assert.expect(1);\n    var one = new Backbone.Model({id: 1});\n    var two = new Backbone.Model({id: 2});\n    var three = new Backbone.Model({id: 3});\n    var collection = new Backbone.Collection([one, two, three]);\n    collection.on('sort', function() {\n      assert.ok(true);\n    });\n    collection.set([{id: 1}, {id: 2}, {id: 3}, {id: 0}]);\n  });\n\n  QUnit.test('#3199 - Order not changing should not trigger a sort', function(assert) {\n    assert.expect(0);\n    var one = new Backbone.Model({id: 1});\n    var two = new Backbone.Model({id: 2});\n    var three = new Backbone.Model({id: 3});\n    var collection = new Backbone.Collection([one, two, three]);\n    collection.on('sort', function() {\n      assert.ok(false);\n    });\n    collection.set([{id: 1}, {id: 2}, {id: 3}]);\n  });\n\n  QUnit.test('add supports negative indexes', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([{id: 1}]);\n    collection.add([{id: 2}, {id: 3}], {at: -1});\n    collection.add([{id: 2.5}], {at: -2});\n    collection.add([{id: 0.5}], {at: -6});\n    assert.equal(collection.pluck('id').join(','), '0.5,1,2,2.5,3');\n  });\n\n  QUnit.test('#set accepts options.at as a string', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([{id: 1}, {id: 2}]);\n    collection.add([{id: 3}], {at: '1'});\n    assert.deepEqual(collection.pluck('id'), [1, 3, 2]);\n  });\n\n  QUnit.test('adding multiple models triggers `update` event once', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection;\n    collection.on('update', function() { assert.ok(true); });\n    collection.add([{id: 1}, {id: 2}, {id: 3}]);\n  });\n\n  QUnit.test('removing models triggers `update` event once', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}]);\n    collection.on('update', function() { assert.ok(true); });\n    collection.remove([{id: 1}, {id: 2}]);\n  });\n\n  QUnit.test('remove does not trigger `update` when nothing removed', function(assert) {\n    assert.expect(0);\n    var collection = new Backbone.Collection([{id: 1}, {id: 2}]);\n    collection.on('update', function() { assert.ok(false); });\n    collection.remove([{id: 3}]);\n  });\n\n  QUnit.test('set triggers `set` event once', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([{id: 1}, {id: 2}]);\n    collection.on('update', function() { assert.ok(true); });\n    collection.set([{id: 1}, {id: 3}]);\n  });\n\n  QUnit.test('set does not trigger `update` event when nothing added nor removed', function(assert) {\n    var collection = new Backbone.Collection([{id: 1}, {id: 2}]);\n    collection.on('update', function(coll, options) {\n      assert.equal(options.changes.added.length, 0);\n      assert.equal(options.changes.removed.length, 0);\n      assert.equal(options.changes.merged.length, 2);\n    });\n    collection.set([{id: 1}, {id: 2}]);\n  });\n\n  QUnit.test('#3610 - invoke collects arguments', function(assert) {\n    assert.expect(3);\n    var Model = Backbone.Model.extend({\n      method: function(x, y, z) {\n        assert.equal(x, 1);\n        assert.equal(y, 2);\n        assert.equal(z, 3);\n      }\n    });\n    var Collection = Backbone.Collection.extend({\n      model: Model\n    });\n    var collection = new Collection([{id: 1}]);\n    collection.invoke('method', 1, 2, 3);\n  });\n\n  QUnit.test('#3662 - triggering change without model will not error', function(assert) {\n    assert.expect(1);\n    var collection = new Backbone.Collection([{id: 1}]);\n    var model = collection.first();\n    collection.on('change', function(m) {\n      assert.equal(m, undefined);\n    });\n    model.trigger('change');\n  });\n\n  QUnit.test('#3871 - falsy parse result creates empty collection', function(assert) {\n    var collection = new (Backbone.Collection.extend({\n      parse: function(data, options) {}\n    }));\n    collection.set('', {parse: true});\n    assert.equal(collection.length, 0);\n  });\n\n  QUnit.test(\"#3711 - remove's `update` event returns one removed model\", function(assert) {\n    var model = new Backbone.Model({id: 1, title: 'First Post'});\n    var collection = new Backbone.Collection([model]);\n    collection.on('update', function(context, options) {\n      var changed = options.changes;\n      assert.deepEqual(changed.added, []);\n      assert.deepEqual(changed.merged, []);\n      assert.strictEqual(changed.removed[0], model);\n    });\n    collection.remove(model);\n  });\n\n  QUnit.test(\"#3711 - remove's `update` event returns multiple removed models\", function(assert) {\n    var model = new Backbone.Model({id: 1, title: 'First Post'});\n    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});\n    var collection = new Backbone.Collection([model, model2]);\n    collection.on('update', function(context, options) {\n      var changed = options.changes;\n      assert.deepEqual(changed.added, []);\n      assert.deepEqual(changed.merged, []);\n      assert.ok(changed.removed.length === 2);\n\n      assert.ok(_.indexOf(changed.removed, model) > -1 && _.indexOf(changed.removed, model2) > -1);\n    });\n    collection.remove([model, model2]);\n  });\n\n  QUnit.test(\"#3711 - set's `update` event returns one added model\", function(assert) {\n    var model = new Backbone.Model({id: 1, title: 'First Post'});\n    var collection = new Backbone.Collection();\n    collection.on('update', function(context, options) {\n      var addedModels = options.changes.added;\n      assert.ok(addedModels.length === 1);\n      assert.strictEqual(addedModels[0], model);\n    });\n    collection.set(model);\n  });\n\n  QUnit.test(\"#3711 - set's `update` event returns multiple added models\", function(assert) {\n    var model = new Backbone.Model({id: 1, title: 'First Post'});\n    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});\n    var collection = new Backbone.Collection();\n    collection.on('update', function(context, options) {\n      var addedModels = options.changes.added;\n      assert.ok(addedModels.length === 2);\n      assert.strictEqual(addedModels[0], model);\n      assert.strictEqual(addedModels[1], model2);\n    });\n    collection.set([model, model2]);\n  });\n\n  QUnit.test(\"#3711 - set's `update` event returns one removed model\", function(assert) {\n    var model = new Backbone.Model({id: 1, title: 'First Post'});\n    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});\n    var model3 = new Backbone.Model({id: 3, title: 'My Last Post'});\n    var collection = new Backbone.Collection([model]);\n    collection.on('update', function(context, options) {\n      var changed = options.changes;\n      assert.equal(changed.added.length, 2);\n      assert.equal(changed.merged.length, 0);\n      assert.ok(changed.removed.length === 1);\n      assert.strictEqual(changed.removed[0], model);\n    });\n    collection.set([model2, model3]);\n  });\n\n  QUnit.test(\"#3711 - set's `update` event returns multiple removed models\", function(assert) {\n    var model = new Backbone.Model({id: 1, title: 'First Post'});\n    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});\n    var model3 = new Backbone.Model({id: 3, title: 'My Last Post'});\n    var collection = new Backbone.Collection([model, model2]);\n    collection.on('update', function(context, options) {\n      var removedModels = options.changes.removed;\n      assert.ok(removedModels.length === 2);\n      assert.strictEqual(removedModels[0], model);\n      assert.strictEqual(removedModels[1], model2);\n    });\n    collection.set([model3]);\n  });\n\n  QUnit.test(\"#3711 - set's `update` event returns one merged model\", function(assert) {\n    var model = new Backbone.Model({id: 1, title: 'First Post'});\n    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});\n    var model2Update = new Backbone.Model({id: 2, title: 'Second Post V2'});\n    var collection = new Backbone.Collection([model, model2]);\n    collection.on('update', function(context, options) {\n      var mergedModels = options.changes.merged;\n      assert.ok(mergedModels.length === 1);\n      assert.strictEqual(mergedModels[0].get('title'), model2Update.get('title'));\n    });\n    collection.set([model2Update]);\n  });\n\n  QUnit.test(\"#3711 - set's `update` event returns multiple merged models\", function(assert) {\n    var model = new Backbone.Model({id: 1, title: 'First Post'});\n    var modelUpdate = new Backbone.Model({id: 1, title: 'First Post V2'});\n    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});\n    var model2Update = new Backbone.Model({id: 2, title: 'Second Post V2'});\n    var collection = new Backbone.Collection([model, model2]);\n    collection.on('update', function(context, options) {\n      var mergedModels = options.changes.merged;\n      assert.ok(mergedModels.length === 2);\n      assert.strictEqual(mergedModels[0].get('title'), model2Update.get('title'));\n      assert.strictEqual(mergedModels[1].get('title'), modelUpdate.get('title'));\n    });\n    collection.set([model2Update, modelUpdate]);\n  });\n\n  QUnit.test(\"#3711 - set's `update` event should not be triggered adding a model which already exists exactly alike\", function(assert) {\n    var fired = false;\n    var model = new Backbone.Model({id: 1, title: 'First Post'});\n    var collection = new Backbone.Collection([model]);\n    collection.on('update', function(context, options) {\n      fired = true;\n    });\n    collection.set([model]);\n    assert.equal(fired, false);\n  });\n\n  QUnit.test('get models with `attributes` key', function(assert) {\n    var model = {id: 1, attributes: {}};\n    var collection = new Backbone.Collection([model]);\n    assert.ok(collection.get(model));\n  });\n\n  QUnit.test('#3961 - add events sends options.index that correspond to wrong index', function(assert) {\n    var numModels = 4;\n    var models = _.each(['a', 'b', 'c', 'd'], function(val) {\n      return new Backbone.Model({id: val});\n    });\n    var collection = new Backbone.Collection(models);\n    models.shift(); // remove first element;\n    models.push(new Backbone.Model({id: 'e'}));\n    collection.on('add', function(model, coll, options){\n      assert.equal(options.index, undefined);\n    });\n    collection.set(models);\n  });\n\n  QUnit.test('#4233 - can instantiate new model in ES class Collection', function(assert) {\n    var model;\n    try {\n      model = new Function('return ({\\n' +\n          '    model(attrs, options) {\\n' +\n          '        var MyModel = Backbone.Model.extend({});\\n' +\n          '        return new MyModel(attrs, options);\\n' +\n          '    }\\n' +\n          '}).model')();\n    } catch (error) {\n      model = error;\n    }\n\n    if (model instanceof SyntaxError) {\n      assert.expect(0);\n      return;\n    }\n\n    assert.expect(1);\n\n    var MyCollection = Backbone.Collection.extend({\n      modelId: function(attr) {\n        return attr.x;\n      },\n\n      model: model\n    });\n\n    var instance = new MyCollection([{a: 2}]);\n\n    assert.ok(instance, 'Should instantiate collection with model');\n  });\n})(QUnit);\n"
  },
  {
    "path": "test/debuginfo.js",
    "content": "/* eslint-disable no-console */\n\n(function(QUnit) {\n\n  var logs, originalDebug = console.debug;\n\n  function spyDebug() {\n    logs.push(arguments);\n    originalDebug.apply(console, arguments);\n  }\n\n  QUnit.module('Backbone.debugInfo', {\n\n    beforeEach: function() {\n      logs = [];\n      console.debug = spyDebug;\n    },\n\n    afterEach: function() {\n      console.debug = originalDebug;\n      logs = undefined;\n    }\n  });\n\n  QUnit.test('debugInfo', function(assert) {\n    var info = Backbone.debugInfo();\n    assert.strictEqual(info.backbone, Backbone.VERSION, 'includes Backbone version');\n    assert.strictEqual(info.distribution, 'MARK_DEVELOPMENT', 'distribution mark sticks to development');\n    assert.strictEqual(info._, _.VERSION, 'includes Underscore version');\n    assert.strictEqual(info.$, $.fn.jquery, 'includes jQuery version');\n    if (typeof navigator !== 'undefined') {\n      assert.ok(typeof info.navigator === 'object');\n      assert.strictEqual(info.navigator.userAgent, navigator.userAgent, 'includes user agent');\n      assert.strictEqual(info.navigator.platform, navigator.platform, 'includes navigator platform');\n      assert.strictEqual(info.navigator.webdriver, navigator.webdriver, 'includes webdriver state');\n    }\n    assert.strictEqual(logs.length, 1, 'prints to console as side effect');\n    var debugArgs = logs[0];\n    var infoString = JSON.stringify(info, null, 4);\n    assert.strictEqual(debugArgs[1], infoString, 'prints payload as second argument');\n  });\n\n})(QUnit);\n"
  },
  {
    "path": "test/events.js",
    "content": "(function(QUnit) {\n\n  QUnit.module('Backbone.Events');\n\n  QUnit.test('on and trigger', function(assert) {\n    assert.expect(2);\n    var obj = {counter: 0};\n    _.extend(obj, Backbone.Events);\n    obj.on('event', function() { obj.counter += 1; });\n    obj.trigger('event');\n    assert.equal(obj.counter, 1, 'counter should be incremented.');\n    obj.trigger('event');\n    obj.trigger('event');\n    obj.trigger('event');\n    obj.trigger('event');\n    assert.equal(obj.counter, 5, 'counter should be incremented five times.');\n  });\n\n  QUnit.test('binding and triggering multiple events', function(assert) {\n    assert.expect(4);\n    var obj = {counter: 0};\n    _.extend(obj, Backbone.Events);\n\n    obj.on('a b c', function() { obj.counter += 1; });\n\n    obj.trigger('a');\n    assert.equal(obj.counter, 1);\n\n    obj.trigger('a b');\n    assert.equal(obj.counter, 3);\n\n    obj.trigger('c');\n    assert.equal(obj.counter, 4);\n\n    obj.off('a c');\n    obj.trigger('a b c');\n    assert.equal(obj.counter, 5);\n  });\n\n  QUnit.test('binding and triggering with event maps', function(assert) {\n    var obj = {counter: 0};\n    _.extend(obj, Backbone.Events);\n\n    var increment = function() {\n      this.counter += 1;\n    };\n\n    obj.on({\n      a: increment,\n      b: increment,\n      c: increment\n    }, obj);\n\n    obj.trigger('a');\n    assert.equal(obj.counter, 1);\n\n    obj.trigger('a b');\n    assert.equal(obj.counter, 3);\n\n    obj.trigger('c');\n    assert.equal(obj.counter, 4);\n\n    obj.off({\n      a: increment,\n      c: increment\n    }, obj);\n    obj.trigger('a b c');\n    assert.equal(obj.counter, 5);\n  });\n\n  QUnit.test('binding and triggering multiple event names with event maps', function(assert) {\n    var obj = {counter: 0};\n    _.extend(obj, Backbone.Events);\n\n    var increment = function() {\n      this.counter += 1;\n    };\n\n    obj.on({\n      'a b c': increment\n    });\n\n    obj.trigger('a');\n    assert.equal(obj.counter, 1);\n\n    obj.trigger('a b');\n    assert.equal(obj.counter, 3);\n\n    obj.trigger('c');\n    assert.equal(obj.counter, 4);\n\n    obj.off({\n      'a c': increment\n    });\n    obj.trigger('a b c');\n    assert.equal(obj.counter, 5);\n  });\n\n  QUnit.test('binding and trigger with event maps context', function(assert) {\n    assert.expect(2);\n    var obj = {counter: 0};\n    var context = {};\n    _.extend(obj, Backbone.Events);\n\n    obj.on({\n      a: function() {\n        assert.strictEqual(this, context, 'defaults `context` to `callback` param');\n      }\n    }, context).trigger('a');\n\n    obj.off().on({\n      a: function() {\n        assert.strictEqual(this, context, 'will not override explicit `context` param');\n      }\n    }, this, context).trigger('a');\n  });\n\n  QUnit.test('listenTo and stopListening', function(assert) {\n    assert.expect(1);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    a.listenTo(b, 'all', function(){ assert.ok(true); });\n    b.trigger('anything');\n    a.listenTo(b, 'all', function(){ assert.ok(false); });\n    a.stopListening();\n    b.trigger('anything');\n  });\n\n  QUnit.test('listenTo and stopListening with event maps', function(assert) {\n    assert.expect(4);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    var cb = function(){ assert.ok(true); };\n    a.listenTo(b, {event: cb});\n    b.trigger('event');\n    a.listenTo(b, {event2: cb});\n    b.on('event2', cb);\n    a.stopListening(b, {event2: cb});\n    b.trigger('event event2');\n    a.stopListening();\n    b.trigger('event event2');\n  });\n\n  QUnit.test('stopListening with omitted args', function(assert) {\n    assert.expect(2);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    var cb = function() { assert.ok(true); };\n    a.listenTo(b, 'event', cb);\n    b.on('event', cb);\n    a.listenTo(b, 'event2', cb);\n    a.stopListening(null, {event: cb});\n    b.trigger('event event2');\n    b.off();\n    a.listenTo(b, 'event event2', cb);\n    a.stopListening(null, 'event');\n    a.stopListening();\n    b.trigger('event2');\n  });\n\n  QUnit.test('listenToOnce', function(assert) {\n    assert.expect(2);\n    // Same as the previous test, but we use once rather than having to explicitly unbind\n    var obj = {counterA: 0, counterB: 0};\n    _.extend(obj, Backbone.Events);\n    var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };\n    var incrB = function(){ obj.counterB += 1; };\n    obj.listenToOnce(obj, 'event', incrA);\n    obj.listenToOnce(obj, 'event', incrB);\n    obj.trigger('event');\n    assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');\n    assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');\n  });\n\n  QUnit.test('listenToOnce and stopListening', function(assert) {\n    assert.expect(1);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    a.listenToOnce(b, 'all', function() { assert.ok(true); });\n    b.trigger('anything');\n    b.trigger('anything');\n    a.listenToOnce(b, 'all', function() { assert.ok(false); });\n    a.stopListening();\n    b.trigger('anything');\n  });\n\n  QUnit.test('listenTo, listenToOnce and stopListening', function(assert) {\n    assert.expect(1);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    a.listenToOnce(b, 'all', function() { assert.ok(true); });\n    b.trigger('anything');\n    b.trigger('anything');\n    a.listenTo(b, 'all', function() { assert.ok(false); });\n    a.stopListening();\n    b.trigger('anything');\n  });\n\n  QUnit.test('listenTo and stopListening with event maps', function(assert) {\n    assert.expect(1);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    a.listenTo(b, {change: function(){ assert.ok(true); }});\n    b.trigger('change');\n    a.listenTo(b, {change: function(){ assert.ok(false); }});\n    a.stopListening();\n    b.trigger('change');\n  });\n\n  QUnit.test('listenTo yourself', function(assert) {\n    assert.expect(1);\n    var e = _.extend({}, Backbone.Events);\n    e.listenTo(e, 'foo', function(){ assert.ok(true); });\n    e.trigger('foo');\n  });\n\n  QUnit.test('listenTo yourself cleans yourself up with stopListening', function(assert) {\n    assert.expect(1);\n    var e = _.extend({}, Backbone.Events);\n    e.listenTo(e, 'foo', function(){ assert.ok(true); });\n    e.trigger('foo');\n    e.stopListening();\n    e.trigger('foo');\n  });\n\n  QUnit.test('stopListening cleans up references', function(assert) {\n    assert.expect(12);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    var fn = function() {};\n    b.on('event', fn);\n    a.listenTo(b, 'event', fn).stopListening();\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._events.event), 1);\n    assert.equal(_.size(b._listeners), 0);\n    a.listenTo(b, 'event', fn).stopListening(b);\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._events.event), 1);\n    assert.equal(_.size(b._listeners), 0);\n    a.listenTo(b, 'event', fn).stopListening(b, 'event');\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._events.event), 1);\n    assert.equal(_.size(b._listeners), 0);\n    a.listenTo(b, 'event', fn).stopListening(b, 'event', fn);\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._events.event), 1);\n    assert.equal(_.size(b._listeners), 0);\n  });\n\n  QUnit.test('stopListening cleans up references from listenToOnce', function(assert) {\n    assert.expect(12);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    var fn = function() {};\n    b.on('event', fn);\n    a.listenToOnce(b, 'event', fn).stopListening();\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._events.event), 1);\n    assert.equal(_.size(b._listeners), 0);\n    a.listenToOnce(b, 'event', fn).stopListening(b);\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._events.event), 1);\n    assert.equal(_.size(b._listeners), 0);\n    a.listenToOnce(b, 'event', fn).stopListening(b, 'event');\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._events.event), 1);\n    assert.equal(_.size(b._listeners), 0);\n    a.listenToOnce(b, 'event', fn).stopListening(b, 'event', fn);\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._events.event), 1);\n    assert.equal(_.size(b._listeners), 0);\n  });\n\n  QUnit.test('listenTo and off cleaning up references', function(assert) {\n    assert.expect(8);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    var fn = function() {};\n    a.listenTo(b, 'event', fn);\n    b.off();\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._listeners), 0);\n    a.listenTo(b, 'event', fn);\n    b.off('event');\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._listeners), 0);\n    a.listenTo(b, 'event', fn);\n    b.off(null, fn);\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._listeners), 0);\n    a.listenTo(b, 'event', fn);\n    b.off(null, null, a);\n    assert.equal(_.size(a._listeningTo), 0);\n    assert.equal(_.size(b._listeners), 0);\n  });\n\n  QUnit.test('listenTo and stopListening cleaning up references', function(assert) {\n    assert.expect(2);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    a.listenTo(b, 'all', function(){ assert.ok(true); });\n    b.trigger('anything');\n    a.listenTo(b, 'other', function(){ assert.ok(false); });\n    a.stopListening(b, 'other');\n    a.stopListening(b, 'all');\n    assert.equal(_.size(a._listeningTo), 0);\n  });\n\n  QUnit.test('listenToOnce without context cleans up references after the event has fired', function(assert) {\n    assert.expect(2);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    a.listenToOnce(b, 'all', function(){ assert.ok(true); });\n    b.trigger('anything');\n    assert.equal(_.size(a._listeningTo), 0);\n  });\n\n  QUnit.test('listenToOnce with event maps cleans up references', function(assert) {\n    assert.expect(2);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    a.listenToOnce(b, {\n      one: function() { assert.ok(true); },\n      two: function() { assert.ok(false); }\n    });\n    b.trigger('one');\n    assert.equal(_.size(a._listeningTo), 1);\n  });\n\n  QUnit.test('listenToOnce with event maps binds the correct `this`', function(assert) {\n    assert.expect(1);\n    var a = _.extend({}, Backbone.Events);\n    var b = _.extend({}, Backbone.Events);\n    a.listenToOnce(b, {\n      one: function() { assert.ok(this === a); },\n      two: function() { assert.ok(false); }\n    });\n    b.trigger('one');\n  });\n\n  QUnit.test(\"listenTo with empty callback doesn't throw an error\", function(assert) {\n    assert.expect(1);\n    var e = _.extend({}, Backbone.Events);\n    e.listenTo(e, 'foo', null);\n    e.trigger('foo');\n    assert.ok(true);\n  });\n\n  QUnit.test('trigger all for each event', function(assert) {\n    assert.expect(3);\n    var a, b, obj = {counter: 0};\n    _.extend(obj, Backbone.Events);\n    obj.on('all', function(event) {\n      obj.counter++;\n      if (event === 'a') a = true;\n      if (event === 'b') b = true;\n    })\n    .trigger('a b');\n    assert.ok(a);\n    assert.ok(b);\n    assert.equal(obj.counter, 2);\n  });\n\n  QUnit.test('on, then unbind all functions', function(assert) {\n    assert.expect(1);\n    var obj = {counter: 0};\n    _.extend(obj, Backbone.Events);\n    var callback = function() { obj.counter += 1; };\n    obj.on('event', callback);\n    obj.trigger('event');\n    obj.off('event');\n    obj.trigger('event');\n    assert.equal(obj.counter, 1, 'counter should have only been incremented once.');\n  });\n\n  QUnit.test('bind two callbacks, unbind only one', function(assert) {\n    assert.expect(2);\n    var obj = {counterA: 0, counterB: 0};\n    _.extend(obj, Backbone.Events);\n    var callback = function() { obj.counterA += 1; };\n    obj.on('event', callback);\n    obj.on('event', function() { obj.counterB += 1; });\n    obj.trigger('event');\n    obj.off('event', callback);\n    obj.trigger('event');\n    assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');\n    assert.equal(obj.counterB, 2, 'counterB should have been incremented twice.');\n  });\n\n  QUnit.test('unbind a callback in the midst of it firing', function(assert) {\n    assert.expect(1);\n    var obj = {counter: 0};\n    _.extend(obj, Backbone.Events);\n    var callback = function() {\n      obj.counter += 1;\n      obj.off('event', callback);\n    };\n    obj.on('event', callback);\n    obj.trigger('event');\n    obj.trigger('event');\n    obj.trigger('event');\n    assert.equal(obj.counter, 1, 'the callback should have been unbound.');\n  });\n\n  QUnit.test('two binds that unbind themeselves', function(assert) {\n    assert.expect(2);\n    var obj = {counterA: 0, counterB: 0};\n    _.extend(obj, Backbone.Events);\n    var incrA = function(){ obj.counterA += 1; obj.off('event', incrA); };\n    var incrB = function(){ obj.counterB += 1; obj.off('event', incrB); };\n    obj.on('event', incrA);\n    obj.on('event', incrB);\n    obj.trigger('event');\n    obj.trigger('event');\n    obj.trigger('event');\n    assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');\n    assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');\n  });\n\n  QUnit.test('bind a callback with a default context when none supplied', function(assert) {\n    assert.expect(1);\n    var obj = _.extend({\n      assertTrue: function() {\n        assert.equal(this, obj, '`this` was bound to the callback');\n      }\n    }, Backbone.Events);\n\n    obj.once('event', obj.assertTrue);\n    obj.trigger('event');\n  });\n\n  QUnit.test('bind a callback with a supplied context', function(assert) {\n    assert.expect(1);\n    var TestClass = function() {\n      return this;\n    };\n    TestClass.prototype.assertTrue = function() {\n      assert.ok(true, '`this` was bound to the callback');\n    };\n\n    var obj = _.extend({}, Backbone.Events);\n    obj.on('event', function() { this.assertTrue(); }, new TestClass);\n    obj.trigger('event');\n  });\n\n  QUnit.test('nested trigger with unbind', function(assert) {\n    assert.expect(1);\n    var obj = {counter: 0};\n    _.extend(obj, Backbone.Events);\n    var incr1 = function(){ obj.counter += 1; obj.off('event', incr1); obj.trigger('event'); };\n    var incr2 = function(){ obj.counter += 1; };\n    obj.on('event', incr1);\n    obj.on('event', incr2);\n    obj.trigger('event');\n    assert.equal(obj.counter, 3, 'counter should have been incremented three times');\n  });\n\n  QUnit.test('callback list is not altered during trigger', function(assert) {\n    assert.expect(2);\n    var counter = 0, obj = _.extend({}, Backbone.Events);\n    var incr = function(){ counter++; };\n    var incrOn = function(){ obj.on('event all', incr); };\n    var incrOff = function(){ obj.off('event all', incr); };\n\n    obj.on('event all', incrOn).trigger('event');\n    assert.equal(counter, 0, 'on does not alter callback list');\n\n    obj.off().on('event', incrOff).on('event all', incr).trigger('event');\n    assert.equal(counter, 2, 'off does not alter callback list');\n  });\n\n  QUnit.test(\"#1282 - 'all' callback list is retrieved after each event.\", function(assert) {\n    assert.expect(1);\n    var counter = 0;\n    var obj = _.extend({}, Backbone.Events);\n    var incr = function(){ counter++; };\n    obj.on('x', function() {\n      obj.on('y', incr).on('all', incr);\n    })\n    .trigger('x y');\n    assert.strictEqual(counter, 2);\n  });\n\n  QUnit.test('if no callback is provided, `on` is a noop', function(assert) {\n    assert.expect(0);\n    _.extend({}, Backbone.Events).on('test').trigger('test');\n  });\n\n  QUnit.test('if callback is truthy but not a function, `on` should throw an error just like jQuery', function(assert) {\n    assert.expect(1);\n    var view = _.extend({}, Backbone.Events).on('test', 'noop');\n    assert.raises(function() {\n      view.trigger('test');\n    });\n  });\n\n  QUnit.test('remove all events for a specific context', function(assert) {\n    assert.expect(4);\n    var obj = _.extend({}, Backbone.Events);\n    obj.on('x y all', function() { assert.ok(true); });\n    obj.on('x y all', function() { assert.ok(false); }, obj);\n    obj.off(null, null, obj);\n    obj.trigger('x y');\n  });\n\n  QUnit.test('remove all events for a specific callback', function(assert) {\n    assert.expect(4);\n    var obj = _.extend({}, Backbone.Events);\n    var success = function() { assert.ok(true); };\n    var fail = function() { assert.ok(false); };\n    obj.on('x y all', success);\n    obj.on('x y all', fail);\n    obj.off(null, fail);\n    obj.trigger('x y');\n  });\n\n  QUnit.test('#1310 - off does not skip consecutive events', function(assert) {\n    assert.expect(0);\n    var obj = _.extend({}, Backbone.Events);\n    obj.on('event', function() { assert.ok(false); }, obj);\n    obj.on('event', function() { assert.ok(false); }, obj);\n    obj.off(null, null, obj);\n    obj.trigger('event');\n  });\n\n  QUnit.test('once', function(assert) {\n    assert.expect(2);\n    // Same as the previous test, but we use once rather than having to explicitly unbind\n    var obj = {counterA: 0, counterB: 0};\n    _.extend(obj, Backbone.Events);\n    var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };\n    var incrB = function(){ obj.counterB += 1; };\n    obj.once('event', incrA);\n    obj.once('event', incrB);\n    obj.trigger('event');\n    assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');\n    assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');\n  });\n\n  QUnit.test('once variant one', function(assert) {\n    assert.expect(3);\n    var f = function(){ assert.ok(true); };\n\n    var a = _.extend({}, Backbone.Events).once('event', f);\n    var b = _.extend({}, Backbone.Events).on('event', f);\n\n    a.trigger('event');\n\n    b.trigger('event');\n    b.trigger('event');\n  });\n\n  QUnit.test('once variant two', function(assert) {\n    assert.expect(3);\n    var f = function(){ assert.ok(true); };\n    var obj = _.extend({}, Backbone.Events);\n\n    obj\n    .once('event', f)\n    .on('event', f)\n    .trigger('event')\n    .trigger('event');\n  });\n\n  QUnit.test('once with off', function(assert) {\n    assert.expect(0);\n    var f = function(){ assert.ok(true); };\n    var obj = _.extend({}, Backbone.Events);\n\n    obj.once('event', f);\n    obj.off('event', f);\n    obj.trigger('event');\n  });\n\n  QUnit.test('once with event maps', function(assert) {\n    var obj = {counter: 0};\n    _.extend(obj, Backbone.Events);\n\n    var increment = function() {\n      this.counter += 1;\n    };\n\n    obj.once({\n      a: increment,\n      b: increment,\n      c: increment\n    }, obj);\n\n    obj.trigger('a');\n    assert.equal(obj.counter, 1);\n\n    obj.trigger('a b');\n    assert.equal(obj.counter, 2);\n\n    obj.trigger('c');\n    assert.equal(obj.counter, 3);\n\n    obj.trigger('a b c');\n    assert.equal(obj.counter, 3);\n  });\n\n  QUnit.test('bind a callback with a supplied context using once with object notation', function(assert) {\n    assert.expect(1);\n    var obj = {counter: 0};\n    var context = {};\n    _.extend(obj, Backbone.Events);\n\n    obj.once({\n      a: function() {\n        assert.strictEqual(this, context, 'defaults `context` to `callback` param');\n      }\n    }, context).trigger('a');\n  });\n\n  QUnit.test('once with off only by context', function(assert) {\n    assert.expect(0);\n    var context = {};\n    var obj = _.extend({}, Backbone.Events);\n    obj.once('event', function(){ assert.ok(false); }, context);\n    obj.off(null, null, context);\n    obj.trigger('event');\n  });\n\n  QUnit.test('Backbone object inherits Events', function(assert) {\n    assert.ok(Backbone.on === Backbone.Events.on);\n  });\n\n  QUnit.test('once with asynchronous events', function(assert) {\n    var done = assert.async();\n    assert.expect(1);\n    var func = _.debounce(function() { assert.ok(true); done(); }, 50);\n    var obj = _.extend({}, Backbone.Events).once('async', func);\n\n    obj.trigger('async');\n    obj.trigger('async');\n  });\n\n  QUnit.test('once with multiple events.', function(assert) {\n    assert.expect(2);\n    var obj = _.extend({}, Backbone.Events);\n    obj.once('x y', function() { assert.ok(true); });\n    obj.trigger('x y');\n  });\n\n  QUnit.test('Off during iteration with once.', function(assert) {\n    assert.expect(2);\n    var obj = _.extend({}, Backbone.Events);\n    var f = function(){ this.off('event', f); };\n    obj.on('event', f);\n    obj.once('event', function(){});\n    obj.on('event', function(){ assert.ok(true); });\n\n    obj.trigger('event');\n    obj.trigger('event');\n  });\n\n  QUnit.test('`once` on `all` should work as expected', function(assert) {\n    assert.expect(1);\n    Backbone.once('all', function() {\n      assert.ok(true);\n      Backbone.trigger('all');\n    });\n    Backbone.trigger('all');\n  });\n\n  QUnit.test('once without a callback is a noop', function(assert) {\n    assert.expect(0);\n    _.extend({}, Backbone.Events).once('event').trigger('event');\n  });\n\n  QUnit.test('listenToOnce without a callback is a noop', function(assert) {\n    assert.expect(0);\n    var obj = _.extend({}, Backbone.Events);\n    obj.listenToOnce(obj, 'event').trigger('event');\n  });\n\n  QUnit.test('event functions are chainable', function(assert) {\n    var obj = _.extend({}, Backbone.Events);\n    var obj2 = _.extend({}, Backbone.Events);\n    var fn = function() {};\n    assert.equal(obj, obj.trigger('noeventssetyet'));\n    assert.equal(obj, obj.off('noeventssetyet'));\n    assert.equal(obj, obj.stopListening('noeventssetyet'));\n    assert.equal(obj, obj.on('a', fn));\n    assert.equal(obj, obj.once('c', fn));\n    assert.equal(obj, obj.trigger('a'));\n    assert.equal(obj, obj.listenTo(obj2, 'a', fn));\n    assert.equal(obj, obj.listenToOnce(obj2, 'b', fn));\n    assert.equal(obj, obj.off('a c'));\n    assert.equal(obj, obj.stopListening(obj2, 'a'));\n    assert.equal(obj, obj.stopListening());\n  });\n\n  QUnit.test('#3448 - listenToOnce with space-separated events', function(assert) {\n    assert.expect(2);\n    var one = _.extend({}, Backbone.Events);\n    var two = _.extend({}, Backbone.Events);\n    var count = 1;\n    one.listenToOnce(two, 'x y', function(n) { assert.ok(n === count++); });\n    two.trigger('x', 1);\n    two.trigger('x', 1);\n    two.trigger('y', 2);\n    two.trigger('y', 2);\n  });\n\n  QUnit.test('#3611 - listenTo is compatible with non-Backbone event libraries', function(assert) {\n    var obj = _.extend({}, Backbone.Events);\n    var other = {\n      events: {},\n      on: function(name, callback) {\n        this.events[name] = callback;\n      },\n      trigger: function(name) {\n        this.events[name]();\n      }\n    };\n\n    obj.listenTo(other, 'test', function() { assert.ok(true); });\n    other.trigger('test');\n  });\n\n  QUnit.test('#3611 - stopListening is compatible with non-Backbone event libraries', function(assert) {\n    var obj = _.extend({}, Backbone.Events);\n    var other = {\n      events: {},\n      on: function(name, callback) {\n        this.events[name] = callback;\n      },\n      off: function() {\n        this.events = {};\n      },\n      trigger: function(name) {\n        var fn = this.events[name];\n        if (fn) fn();\n      }\n    };\n\n    obj.listenTo(other, 'test', function() { assert.ok(false); });\n    obj.stopListening(other);\n    other.trigger('test');\n    assert.equal(_.size(obj._listeningTo), 0);\n  });\n})(QUnit);\n"
  },
  {
    "path": "test/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta charset='utf8'>\n  <title>Backbone Test Suite</title>\n  <link rel=\"stylesheet\" href=\"vendor/qunit.css\" type=\"text/css\" media=\"screen\">\n</head>\n<body>\n  <script src=\"vendor/qunit.js\"></script>\n  <script src=\"vendor/jquery.js\"></script>\n  <script src=\"vendor/json2.js\"></script>\n  <script src=\"vendor/underscore.js\"></script>\n  <script src=\"../backbone.js\"></script>\n  <script src=\"../debug-info.js\"></script>\n  <script src=\"setup/dom-setup.js\"></script>\n  <script src=\"setup/environment.js\"></script>\n  <script src=\"noconflict.js\"></script>\n  <script src=\"debuginfo.js\"></script>\n  <script src=\"events.js\"></script>\n  <script src=\"model.js\"></script>\n  <script src=\"collection.js\"></script>\n  <script src=\"router.js\"></script>\n  <script src=\"view.js\"></script>\n  <script src=\"sync.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "test/model.coffee",
    "content": "# Quick Backbone/CoffeeScript tests to make sure that inheritance\n# works correctly.\n\n{ok, equal, deepEqual}      = require 'assert'\n{Model, Collection, Events} = require '../backbone'\n\n\n# Patch `ok` to store a count of passed tests...\ncount = 0\noldOk = ok\nok = ->\n  oldOk arguments...\n  count++\n\n\nclass Document extends Model\n\n  fullName: ->\n    @get('name') + ' ' + @get('surname')\n\ntempest = new Document\n  id      : '1-the-tempest',\n  title   : \"The Tempest\",\n  name    : \"William\"\n  surname : \"Shakespeare\"\n  length  : 123\n\nok tempest.fullName() is \"William Shakespeare\"\nok tempest.get('length') is 123\n\n\nclass ProperDocument extends Document\n\n  fullName: ->\n    \"Mr. \" + super(arguments...)\n\nproperTempest = new ProperDocument tempest.attributes\n\nok properTempest.fullName() is \"Mr. William Shakespeare\"\nok properTempest.get('length') is 123\n\n\nconsole.log \"passed #{count} tests\"\n"
  },
  {
    "path": "test/model.js",
    "content": "(function(QUnit) {\n\n  var ProxyModel = Backbone.Model.extend();\n  var Klass = Backbone.Collection.extend({\n    url: function() { return '/collection'; }\n  });\n  var doc, collection;\n\n  QUnit.module('Backbone.Model', {\n\n    beforeEach: function(assert) {\n      doc = new ProxyModel({\n        id: '1-the-tempest',\n        title: 'The Tempest',\n        author: 'Bill Shakespeare',\n        length: 123\n      });\n      collection = new Klass();\n      collection.add(doc);\n    }\n\n  });\n\n  QUnit.test('initialize', function(assert) {\n    assert.expect(3);\n    var Model = Backbone.Model.extend({\n      initialize: function() {\n        this.one = 1;\n        assert.equal(this.collection, collection);\n      }\n    });\n    var model = new Model({}, {collection: collection});\n    assert.equal(model.one, 1);\n    assert.equal(model.collection, collection);\n  });\n\n  QUnit.test('Object.prototype properties are overridden by attributes', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model({hasOwnProperty: true});\n    assert.equal(model.get('hasOwnProperty'), true);\n  });\n\n  QUnit.test('initialize with attributes and options', function(assert) {\n    assert.expect(1);\n    var Model = Backbone.Model.extend({\n      initialize: function(attributes, options) {\n        this.one = options.one;\n      }\n    });\n    var model = new Model({}, {one: 1});\n    assert.equal(model.one, 1);\n  });\n\n  QUnit.test('initialize with parsed attributes', function(assert) {\n    assert.expect(1);\n    var Model = Backbone.Model.extend({\n      parse: function(attrs) {\n        attrs.value += 1;\n        return attrs;\n      }\n    });\n    var model = new Model({value: 1}, {parse: true});\n    assert.equal(model.get('value'), 2);\n  });\n\n\n  QUnit.test('preinitialize', function(assert) {\n    assert.expect(2);\n    var Model = Backbone.Model.extend({\n\n      preinitialize: function() {\n        this.one = 1;\n      }\n    });\n    var model = new Model({}, {collection: collection});\n    assert.equal(model.one, 1);\n    assert.equal(model.collection, collection);\n  });\n\n  QUnit.test('preinitialize occurs before the model is set up', function(assert) {\n    assert.expect(6);\n    var Model = Backbone.Model.extend({\n\n      preinitialize: function() {\n        assert.equal(this.collection, undefined);\n        assert.equal(this.cid, undefined);\n        assert.equal(this.id, undefined);\n      }\n    });\n    var model = new Model({id: 'foo'}, {collection: collection});\n    assert.equal(model.collection, collection);\n    assert.equal(model.id, 'foo');\n    assert.notEqual(model.cid, undefined);\n  });\n\n  QUnit.test('parse can return null', function(assert) {\n    assert.expect(1);\n    var Model = Backbone.Model.extend({\n      parse: function(attrs) {\n        attrs.value += 1;\n        return null;\n      }\n    });\n    var model = new Model({value: 1}, {parse: true});\n    assert.equal(JSON.stringify(model.toJSON()), '{}');\n  });\n\n  QUnit.test('url', function(assert) {\n    assert.expect(3);\n    doc.urlRoot = null;\n    assert.equal(doc.url(), '/collection/1-the-tempest');\n    doc.collection.url = '/collection/';\n    assert.equal(doc.url(), '/collection/1-the-tempest');\n    doc.collection = null;\n    assert.raises(function() { doc.url(); });\n    doc.collection = collection;\n  });\n\n  QUnit.test('url when using urlRoot, and uri encoding', function(assert) {\n    assert.expect(2);\n    var Model = Backbone.Model.extend({\n      urlRoot: '/collection'\n    });\n    var model = new Model();\n    assert.equal(model.url(), '/collection');\n    model.set({id: '+1+'});\n    assert.equal(model.url(), '/collection/%2B1%2B');\n  });\n\n  QUnit.test('url when using urlRoot as a function to determine urlRoot at runtime', function(assert) {\n    assert.expect(2);\n    var Model = Backbone.Model.extend({\n      urlRoot: function() {\n        return '/nested/' + this.get('parentId') + '/collection';\n      }\n    });\n\n    var model = new Model({parentId: 1});\n    assert.equal(model.url(), '/nested/1/collection');\n    model.set({id: 2});\n    assert.equal(model.url(), '/nested/1/collection/2');\n  });\n\n  QUnit.test('underscore methods', function(assert) {\n    assert.expect(5);\n    var model = new Backbone.Model({foo: 'a', bar: 'b', baz: 'c'});\n    var model2 = model.clone();\n    assert.deepEqual(model.keys(), ['foo', 'bar', 'baz']);\n    assert.deepEqual(model.values(), ['a', 'b', 'c']);\n    assert.deepEqual(model.invert(), {a: 'foo', b: 'bar', c: 'baz'});\n    assert.deepEqual(model.pick('foo', 'baz'), {foo: 'a', baz: 'c'});\n    assert.deepEqual(model.omit('foo', 'bar'), {baz: 'c'});\n  });\n\n  QUnit.test('chain', function(assert) {\n    var model = new Backbone.Model({a: 0, b: 1, c: 2});\n    assert.deepEqual(model.chain().pick('a', 'b', 'c').values().compact().value(), [1, 2]);\n  });\n\n  QUnit.test('clone', function(assert) {\n    assert.expect(10);\n    var a = new Backbone.Model({foo: 1, bar: 2, baz: 3});\n    var b = a.clone();\n    assert.equal(a.get('foo'), 1);\n    assert.equal(a.get('bar'), 2);\n    assert.equal(a.get('baz'), 3);\n    assert.equal(b.get('foo'), a.get('foo'), 'Foo should be the same on the clone.');\n    assert.equal(b.get('bar'), a.get('bar'), 'Bar should be the same on the clone.');\n    assert.equal(b.get('baz'), a.get('baz'), 'Baz should be the same on the clone.');\n    a.set({foo: 100});\n    assert.equal(a.get('foo'), 100);\n    assert.equal(b.get('foo'), 1, 'Changing a parent attribute does not change the clone.');\n\n    var foo = new Backbone.Model({p: 1});\n    var bar = new Backbone.Model({p: 2});\n    bar.set(foo.clone().attributes, {unset: true});\n    assert.equal(foo.get('p'), 1);\n    assert.equal(bar.get('p'), undefined);\n  });\n\n  QUnit.test('isNew', function(assert) {\n    assert.expect(6);\n    var a = new Backbone.Model({foo: 1, bar: 2, baz: 3});\n    assert.ok(a.isNew(), 'it should be new');\n    a = new Backbone.Model({foo: 1, bar: 2, baz: 3, id: -5});\n    assert.ok(!a.isNew(), 'any defined ID is legal, negative or positive');\n    a = new Backbone.Model({foo: 1, bar: 2, baz: 3, id: 0});\n    assert.ok(!a.isNew(), 'any defined ID is legal, including zero');\n    assert.ok(new Backbone.Model().isNew(), 'is true when there is no id');\n    assert.ok(!new Backbone.Model({id: 2}).isNew(), 'is false for a positive integer');\n    assert.ok(!new Backbone.Model({id: -5}).isNew(), 'is false for a negative integer');\n  });\n\n  QUnit.test('get', function(assert) {\n    assert.expect(2);\n    assert.equal(doc.get('title'), 'The Tempest');\n    assert.equal(doc.get('author'), 'Bill Shakespeare');\n  });\n\n  QUnit.test('escape', function(assert) {\n    assert.expect(5);\n    assert.equal(doc.escape('title'), 'The Tempest');\n    doc.set({audience: 'Bill & Bob'});\n    assert.equal(doc.escape('audience'), 'Bill &amp; Bob');\n    doc.set({audience: 'Tim > Joan'});\n    assert.equal(doc.escape('audience'), 'Tim &gt; Joan');\n    doc.set({audience: 10101});\n    assert.equal(doc.escape('audience'), '10101');\n    doc.unset('audience');\n    assert.equal(doc.escape('audience'), '');\n  });\n\n  QUnit.test('has', function(assert) {\n    assert.expect(10);\n    var model = new Backbone.Model();\n\n    assert.strictEqual(model.has('name'), false);\n\n    model.set({\n      '0': 0,\n      '1': 1,\n      'true': true,\n      'false': false,\n      'empty': '',\n      'name': 'name',\n      'null': null,\n      'undefined': undefined\n    });\n\n    assert.strictEqual(model.has('0'), true);\n    assert.strictEqual(model.has('1'), true);\n    assert.strictEqual(model.has('true'), true);\n    assert.strictEqual(model.has('false'), true);\n    assert.strictEqual(model.has('empty'), true);\n    assert.strictEqual(model.has('name'), true);\n\n    model.unset('name');\n\n    assert.strictEqual(model.has('name'), false);\n    assert.strictEqual(model.has('null'), false);\n    assert.strictEqual(model.has('undefined'), false);\n  });\n\n  QUnit.test('matches', function(assert) {\n    assert.expect(4);\n    var model = new Backbone.Model();\n\n    assert.strictEqual(model.matches({name: 'Jonas', cool: true}), false);\n\n    model.set({name: 'Jonas', cool: true});\n\n    assert.strictEqual(model.matches({name: 'Jonas'}), true);\n    assert.strictEqual(model.matches({name: 'Jonas', cool: true}), true);\n    assert.strictEqual(model.matches({name: 'Jonas', cool: false}), false);\n  });\n\n  QUnit.test('matches with predicate', function(assert) {\n    var model = new Backbone.Model({a: 0});\n\n    assert.strictEqual(model.matches(function(attr) {\n      return attr.a > 1 && attr.b != null;\n    }), false);\n\n    model.set({a: 3, b: true});\n\n    assert.strictEqual(model.matches(function(attr) {\n      return attr.a > 1 && attr.b != null;\n    }), true);\n  });\n\n  QUnit.test('set and unset', function(assert) {\n    assert.expect(8);\n    var a = new Backbone.Model({id: 'id', foo: 1, bar: 2, baz: 3});\n    var changeCount = 0;\n    a.on('change:foo', function() { changeCount += 1; });\n    a.set({foo: 2});\n    assert.equal(a.get('foo'), 2, 'Foo should have changed.');\n    assert.equal(changeCount, 1, 'Change count should have incremented.');\n    // set with value that is not new shouldn't fire change event\n    a.set({foo: 2});\n    assert.equal(a.get('foo'), 2, 'Foo should NOT have changed, still 2');\n    assert.equal(changeCount, 1, 'Change count should NOT have incremented.');\n\n    a.validate = function(attrs) {\n      assert.equal(attrs.foo, void 0, 'validate:true passed while unsetting');\n    };\n    a.unset('foo', {validate: true});\n    assert.equal(a.get('foo'), void 0, 'Foo should have changed');\n    delete a.validate;\n    assert.equal(changeCount, 2, 'Change count should have incremented for unset.');\n\n    a.unset('id');\n    assert.equal(a.id, undefined, 'Unsetting the id should remove the id property.');\n  });\n\n  QUnit.test('#2030 - set with failed validate, followed by another set triggers change', function(assert) {\n    var attr = 0, main = 0, error = 0;\n    var Model = Backbone.Model.extend({\n      validate: function(attrs) {\n        if (attrs.x > 1) {\n          error++;\n          return 'this is an error';\n        }\n      }\n    });\n    var model = new Model({x: 0});\n    model.on('change:x', function() { attr++; });\n    model.on('change', function() { main++; });\n    model.set({x: 2}, {validate: true});\n    model.set({x: 1}, {validate: true});\n    assert.deepEqual([attr, main, error], [1, 1, 1]);\n  });\n\n  QUnit.test('set triggers changes in the correct order', function(assert) {\n    var value = null;\n    var model = new Backbone.Model;\n    model.on('last', function(){ value = 'last'; });\n    model.on('first', function(){ value = 'first'; });\n    model.trigger('first');\n    model.trigger('last');\n    assert.equal(value, 'last');\n  });\n\n  QUnit.test('set falsy values in the correct order', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model({result: 'result'});\n    model.on('change', function() {\n      assert.equal(model.changed.result, void 0);\n      assert.equal(model.previous('result'), false);\n    });\n    model.set({result: void 0}, {silent: true});\n    model.set({result: null}, {silent: true});\n    model.set({result: false}, {silent: true});\n    model.set({result: void 0});\n  });\n\n  QUnit.test('nested set triggers with the correct options', function(assert) {\n    var model = new Backbone.Model();\n    var o1 = {};\n    var o2 = {};\n    var o3 = {};\n    model.on('change', function(__, options) {\n      switch (model.get('a')) {\n        case 1:\n          assert.equal(options, o1);\n          return model.set('a', 2, o2);\n        case 2:\n          assert.equal(options, o2);\n          return model.set('a', 3, o3);\n        case 3:\n          assert.equal(options, o3);\n      }\n    });\n    model.set('a', 1, o1);\n  });\n\n  QUnit.test('multiple unsets', function(assert) {\n    assert.expect(1);\n    var i = 0;\n    var counter = function(){ i++; };\n    var model = new Backbone.Model({a: 1});\n    model.on('change:a', counter);\n    model.set({a: 2});\n    model.unset('a');\n    model.unset('a');\n    assert.equal(i, 2, 'Unset does not fire an event for missing attributes.');\n  });\n\n  QUnit.test('unset and changedAttributes', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model({a: 1});\n    model.on('change', function() {\n      assert.ok('a' in model.changedAttributes(), 'changedAttributes should contain unset properties');\n    });\n    model.unset('a');\n  });\n\n  QUnit.test('using a non-default id attribute.', function(assert) {\n    assert.expect(5);\n    var MongoModel = Backbone.Model.extend({idAttribute: '_id'});\n    var model = new MongoModel({id: 'eye-dee', _id: 25, title: 'Model'});\n    assert.equal(model.get('id'), 'eye-dee');\n    assert.equal(model.id, 25);\n    assert.equal(model.isNew(), false);\n    model.unset('_id');\n    assert.equal(model.id, undefined);\n    assert.equal(model.isNew(), true);\n  });\n\n  QUnit.test('setting an alternative cid prefix', function(assert) {\n    assert.expect(4);\n    var Model = Backbone.Model.extend({\n      cidPrefix: 'm'\n    });\n    var model = new Model();\n\n    assert.equal(model.cid.charAt(0), 'm');\n\n    model = new Backbone.Model();\n    assert.equal(model.cid.charAt(0), 'c');\n\n    var Collection = Backbone.Collection.extend({\n      model: Model\n    });\n    var col = new Collection([{id: 'c5'}, {id: 'c6'}, {id: 'c7'}]);\n\n    assert.equal(col.get('c6').cid.charAt(0), 'm');\n    col.set([{id: 'c6', value: 'test'}], {\n      merge: true,\n      add: true,\n      remove: false\n    });\n    assert.ok(col.get('c6').has('value'));\n  });\n\n  QUnit.test('set an empty string', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model({name: 'Model'});\n    model.set({name: ''});\n    assert.equal(model.get('name'), '');\n  });\n\n  QUnit.test('setting an object', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model({\n      custom: {foo: 1}\n    });\n    model.on('change', function() {\n      assert.ok(1);\n    });\n    model.set({\n      custom: {foo: 1} // no change should be fired\n    });\n    model.set({\n      custom: {foo: 2} // change event should be fired\n    });\n  });\n\n  QUnit.test('clear', function(assert) {\n    assert.expect(3);\n    var changed;\n    var model = new Backbone.Model({id: 1, name: 'Model'});\n    model.on('change:name', function(){ changed = true; });\n    model.on('change', function() {\n      var changedAttrs = model.changedAttributes();\n      assert.ok('name' in changedAttrs);\n    });\n    model.clear();\n    assert.equal(changed, true);\n    assert.equal(model.get('name'), undefined);\n  });\n\n  QUnit.test('defaults', function(assert) {\n    assert.expect(9);\n    var Defaulted = Backbone.Model.extend({\n      defaults: {\n        one: 1,\n        two: 2\n      }\n    });\n    var model = new Defaulted({two: undefined});\n    assert.equal(model.get('one'), 1);\n    assert.equal(model.get('two'), 2);\n    model = new Defaulted({two: 3});\n    assert.equal(model.get('one'), 1);\n    assert.equal(model.get('two'), 3);\n    Defaulted = Backbone.Model.extend({\n      defaults: function() {\n        return {\n          one: 3,\n          two: 4\n        };\n      }\n    });\n    model = new Defaulted({two: undefined});\n    assert.equal(model.get('one'), 3);\n    assert.equal(model.get('two'), 4);\n    Defaulted = Backbone.Model.extend({\n      defaults: {hasOwnProperty: true}\n    });\n    model = new Defaulted();\n    assert.equal(model.get('hasOwnProperty'), true);\n    model = new Defaulted({hasOwnProperty: undefined});\n    assert.equal(model.get('hasOwnProperty'), true);\n    model = new Defaulted({hasOwnProperty: false});\n    assert.equal(model.get('hasOwnProperty'), false);\n  });\n\n  QUnit.test('change, hasChanged, changedAttributes, previous, previousAttributes', function(assert) {\n    assert.expect(9);\n    var model = new Backbone.Model({name: 'Tim', age: 10});\n    assert.deepEqual(model.changedAttributes(), false);\n    model.on('change', function() {\n      assert.ok(model.hasChanged('name'), 'name changed');\n      assert.ok(!model.hasChanged('age'), 'age did not');\n      assert.ok(_.isEqual(model.changedAttributes(), {name: 'Rob'}), 'changedAttributes returns the changed attrs');\n      assert.equal(model.previous('name'), 'Tim');\n      assert.ok(_.isEqual(model.previousAttributes(), {name: 'Tim', age: 10}), 'previousAttributes is correct');\n    });\n    assert.equal(model.hasChanged(), false);\n    assert.equal(model.hasChanged(undefined), false);\n    model.set({name: 'Rob'});\n    assert.equal(model.get('name'), 'Rob');\n  });\n\n  QUnit.test('changedAttributes', function(assert) {\n    assert.expect(3);\n    var model = new Backbone.Model({a: 'a', b: 'b'});\n    assert.deepEqual(model.changedAttributes(), false);\n    assert.equal(model.changedAttributes({a: 'a'}), false);\n    assert.equal(model.changedAttributes({a: 'b'}).a, 'b');\n  });\n\n  QUnit.test('change with options', function(assert) {\n    assert.expect(2);\n    var value;\n    var model = new Backbone.Model({name: 'Rob'});\n    model.on('change', function(m, options) {\n      value = options.prefix + m.get('name');\n    });\n    model.set({name: 'Bob'}, {prefix: 'Mr. '});\n    assert.equal(value, 'Mr. Bob');\n    model.set({name: 'Sue'}, {prefix: 'Ms. '});\n    assert.equal(value, 'Ms. Sue');\n  });\n\n  QUnit.test('change after initialize', function(assert) {\n    assert.expect(1);\n    var changed = 0;\n    var attrs = {id: 1, label: 'c'};\n    var obj = new Backbone.Model(attrs);\n    obj.on('change', function() { changed += 1; });\n    obj.set(attrs);\n    assert.equal(changed, 0);\n  });\n\n  QUnit.test('save within change event', function(assert) {\n    assert.expect(1);\n    var env = this;\n    var model = new Backbone.Model({firstName: 'Taylor', lastName: 'Swift'});\n    model.url = '/test';\n    model.on('change', function() {\n      model.save();\n      assert.ok(_.isEqual(env.syncArgs.model, model));\n    });\n    model.set({lastName: 'Hicks'});\n  });\n\n  QUnit.test('validate after save', function(assert) {\n    assert.expect(2);\n    var lastError, model = new Backbone.Model();\n    model.validate = function(attrs) {\n      if (attrs.admin) return \"Can't change admin status.\";\n    };\n    model.sync = function(method, m, options) {\n      options.success.call(this, {admin: true});\n    };\n    model.on('invalid', function(m, error) {\n      lastError = error;\n    });\n    model.save(null);\n\n    assert.equal(lastError, \"Can't change admin status.\");\n    assert.equal(model.validationError, \"Can't change admin status.\");\n  });\n\n  QUnit.test('save', function(assert) {\n    assert.expect(2);\n    doc.save({title: 'Henry V'});\n    assert.equal(this.syncArgs.method, 'update');\n    assert.ok(_.isEqual(this.syncArgs.model, doc));\n  });\n\n  QUnit.test('save, fetch, destroy triggers error event when an error occurs', function(assert) {\n    assert.expect(3);\n    var model = new Backbone.Model();\n    model.on('error', function() {\n      assert.ok(true);\n    });\n    model.sync = function(method, m, options) {\n      options.error();\n    };\n    model.save({data: 2, id: 1});\n    model.fetch();\n    model.destroy();\n  });\n\n  QUnit.test('#3283 - save, fetch, destroy calls success with context', function(assert) {\n    assert.expect(3);\n    var model = new Backbone.Model();\n    var obj = {};\n    var options = {\n      context: obj,\n      success: function() {\n        assert.equal(this, obj);\n      }\n    };\n    model.sync = function(method, m, opts) {\n      opts.success.call(opts.context);\n    };\n    model.save({data: 2, id: 1}, options);\n    model.fetch(options);\n    model.destroy(options);\n  });\n\n  QUnit.test('#3283 - save, fetch, destroy calls error with context', function(assert) {\n    assert.expect(3);\n    var model = new Backbone.Model();\n    var obj = {};\n    var options = {\n      context: obj,\n      error: function() {\n        assert.equal(this, obj);\n      }\n    };\n    model.sync = function(method, m, opts) {\n      opts.error.call(opts.context);\n    };\n    model.save({data: 2, id: 1}, options);\n    model.fetch(options);\n    model.destroy(options);\n  });\n\n  QUnit.test('#3470 - save and fetch with parse false', function(assert) {\n    assert.expect(2);\n    var i = 0;\n    var model = new Backbone.Model();\n    model.parse = function() {\n      assert.ok(false);\n    };\n    model.sync = function(method, m, options) {\n      options.success({i: ++i});\n    };\n    model.fetch({parse: false});\n    assert.equal(model.get('i'), i);\n    model.save(null, {parse: false});\n    assert.equal(model.get('i'), i);\n  });\n\n  QUnit.test('save with PATCH', function(assert) {\n    doc.clear().set({id: 1, a: 1, b: 2, c: 3, d: 4});\n    doc.save();\n    assert.equal(this.syncArgs.method, 'update');\n    assert.equal(this.syncArgs.options.attrs, undefined);\n\n    doc.save({b: 2, d: 4}, {patch: true});\n    assert.equal(this.syncArgs.method, 'patch');\n    assert.equal(_.size(this.syncArgs.options.attrs), 2);\n    assert.equal(this.syncArgs.options.attrs.d, 4);\n    assert.equal(this.syncArgs.options.attrs.a, undefined);\n    assert.equal(this.ajaxSettings.data, '{\"b\":2,\"d\":4}');\n  });\n\n  QUnit.test('save with PATCH and different attrs', function(assert) {\n    doc.clear().save({b: 2, d: 4}, {patch: true, attrs: {B: 1, D: 3}});\n    assert.equal(this.syncArgs.options.attrs.D, 3);\n    assert.equal(this.syncArgs.options.attrs.d, undefined);\n    assert.equal(this.ajaxSettings.data, '{\"B\":1,\"D\":3}');\n    assert.deepEqual(doc.attributes, {b: 2, d: 4});\n  });\n\n  QUnit.test('save in positional style', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    model.sync = function(method, m, options) {\n      options.success();\n    };\n    model.save('title', 'Twelfth Night');\n    assert.equal(model.get('title'), 'Twelfth Night');\n  });\n\n  QUnit.test('save with non-object success response', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model();\n    model.sync = function(method, m, options) {\n      options.success('', options);\n      options.success(null, options);\n    };\n    model.save({testing: 'empty'}, {\n      success: function(m) {\n        assert.deepEqual(m.attributes, {testing: 'empty'});\n      }\n    });\n  });\n\n  QUnit.test('save with wait and supplied id', function(assert) {\n    var Model = Backbone.Model.extend({\n      urlRoot: '/collection'\n    });\n    var model = new Model();\n    model.save({id: 42}, {wait: true});\n    assert.equal(this.ajaxSettings.url, '/collection/42');\n  });\n\n  QUnit.test('save will pass extra options to success callback', function(assert) {\n    assert.expect(1);\n    var SpecialSyncModel = Backbone.Model.extend({\n      sync: function(method, m, options) {\n        _.extend(options, {specialSync: true});\n        return Backbone.Model.prototype.sync.call(this, method, m, options);\n      },\n      urlRoot: '/test'\n    });\n\n    var model = new SpecialSyncModel();\n\n    var onSuccess = function(m, response, options) {\n      assert.ok(options.specialSync, 'Options were passed correctly to callback');\n    };\n\n    model.save(null, {success: onSuccess});\n    this.ajaxSettings.success();\n  });\n\n  QUnit.test('failing save with wait:true triggers error event (#4262)', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model;\n    model.urlRoot = '/test';\n    model.on('error', function() { assert.ok(true); });\n    model.save({id: '1'}, {wait: true});\n    this.ajaxSettings.error();\n  });\n\n  QUnit.test('fetch', function(assert) {\n    assert.expect(2);\n    doc.fetch();\n    assert.equal(this.syncArgs.method, 'read');\n    assert.ok(_.isEqual(this.syncArgs.model, doc));\n  });\n\n  QUnit.test('fetch will pass extra options to success callback', function(assert) {\n    assert.expect(1);\n    var SpecialSyncModel = Backbone.Model.extend({\n      sync: function(method, m, options) {\n        _.extend(options, {specialSync: true});\n        return Backbone.Model.prototype.sync.call(this, method, m, options);\n      },\n      urlRoot: '/test'\n    });\n\n    var model = new SpecialSyncModel();\n\n    var onSuccess = function(m, response, options) {\n      assert.ok(options.specialSync, 'Options were passed correctly to callback');\n    };\n\n    model.fetch({success: onSuccess});\n    this.ajaxSettings.success();\n  });\n\n  QUnit.test('destroy', function(assert) {\n    assert.expect(3);\n    doc.destroy();\n    assert.equal(this.syncArgs.method, 'delete');\n    assert.ok(_.isEqual(this.syncArgs.model, doc));\n\n    var newModel = new Backbone.Model;\n    assert.equal(newModel.destroy(), false);\n  });\n\n  QUnit.test('destroy will pass extra options to success callback', function(assert) {\n    assert.expect(1);\n    var SpecialSyncModel = Backbone.Model.extend({\n      sync: function(method, m, options) {\n        _.extend(options, {specialSync: true});\n        return Backbone.Model.prototype.sync.call(this, method, m, options);\n      },\n      urlRoot: '/test'\n    });\n\n    var model = new SpecialSyncModel({id: 'id'});\n\n    var onSuccess = function(m, response, options) {\n      assert.ok(options.specialSync, 'Options were passed correctly to callback');\n    };\n\n    model.destroy({success: onSuccess});\n    this.ajaxSettings.success();\n  });\n\n  QUnit.test('non-persisted destroy', function(assert) {\n    assert.expect(1);\n    var a = new Backbone.Model({foo: 1, bar: 2, baz: 3});\n    a.sync = function() { throw 'should not be called'; };\n    a.destroy();\n    assert.ok(true, 'non-persisted model should not call sync');\n  });\n\n  QUnit.test('validate', function(assert) {\n    var lastError;\n    var model = new Backbone.Model();\n    model.validate = function(attrs) {\n      if (attrs.admin !== this.get('admin')) return \"Can't change admin status.\";\n    };\n    model.on('invalid', function(m, error) {\n      lastError = error;\n    });\n    var result = model.set({a: 100});\n    assert.equal(result, model);\n    assert.equal(model.get('a'), 100);\n    assert.equal(lastError, undefined);\n    result = model.set({admin: true});\n    assert.equal(model.get('admin'), true);\n    result = model.set({a: 200, admin: false}, {validate: true});\n    assert.equal(lastError, \"Can't change admin status.\");\n    assert.equal(result, false);\n    assert.equal(model.get('a'), 100);\n  });\n\n  QUnit.test('validate on unset and clear', function(assert) {\n    assert.expect(6);\n    var error;\n    var model = new Backbone.Model({name: 'One'});\n    model.validate = function(attrs) {\n      if (!attrs.name) {\n        error = true;\n        return 'No thanks.';\n      }\n    };\n    model.set({name: 'Two'});\n    assert.equal(model.get('name'), 'Two');\n    assert.equal(error, undefined);\n    model.unset('name', {validate: true});\n    assert.equal(error, true);\n    assert.equal(model.get('name'), 'Two');\n    model.clear({validate: true});\n    assert.equal(model.get('name'), 'Two');\n    delete model.validate;\n    model.clear();\n    assert.equal(model.get('name'), undefined);\n  });\n\n  QUnit.test('validate with error callback', function(assert) {\n    assert.expect(8);\n    var lastError, boundError;\n    var model = new Backbone.Model();\n    model.validate = function(attrs) {\n      if (attrs.admin) return \"Can't change admin status.\";\n    };\n    model.on('invalid', function(m, error) {\n      boundError = true;\n    });\n    var result = model.set({a: 100}, {validate: true});\n    assert.equal(result, model);\n    assert.equal(model.get('a'), 100);\n    assert.equal(model.validationError, null);\n    assert.equal(boundError, undefined);\n    result = model.set({a: 200, admin: true}, {validate: true});\n    assert.equal(result, false);\n    assert.equal(model.get('a'), 100);\n    assert.equal(model.validationError, \"Can't change admin status.\");\n    assert.equal(boundError, true);\n  });\n\n  QUnit.test('defaults always extend attrs (#459)', function(assert) {\n    assert.expect(2);\n    var Defaulted = Backbone.Model.extend({\n      defaults: {one: 1},\n      initialize: function(attrs, opts) {\n        assert.equal(this.attributes.one, 1);\n      }\n    });\n    var providedattrs = new Defaulted({});\n    var emptyattrs = new Defaulted();\n  });\n\n  QUnit.test('Inherit class properties', function(assert) {\n    assert.expect(6);\n    var Parent = Backbone.Model.extend({\n      instancePropSame: function() {},\n      instancePropDiff: function() {}\n    }, {\n      classProp: function() {}\n    });\n    var Child = Parent.extend({\n      instancePropDiff: function() {}\n    });\n\n    var adult = new Parent;\n    var kid   = new Child;\n\n    assert.equal(Child.classProp, Parent.classProp);\n    assert.notEqual(Child.classProp, undefined);\n\n    assert.equal(kid.instancePropSame, adult.instancePropSame);\n    assert.notEqual(kid.instancePropSame, undefined);\n\n    assert.notEqual(Child.prototype.instancePropDiff, Parent.prototype.instancePropDiff);\n    assert.notEqual(Child.prototype.instancePropDiff, undefined);\n  });\n\n  QUnit.test(\"Nested change events don't clobber previous attributes\", function(assert) {\n    assert.expect(4);\n    new Backbone.Model()\n    .on('change:state', function(m, newState) {\n      assert.equal(m.previous('state'), undefined);\n      assert.equal(newState, 'hello');\n      // Fire a nested change event.\n      m.set({other: 'whatever'});\n    })\n    .on('change:state', function(m, newState) {\n      assert.equal(m.previous('state'), undefined);\n      assert.equal(newState, 'hello');\n    })\n    .set({state: 'hello'});\n  });\n\n  QUnit.test('hasChanged/set should use same comparison', function(assert) {\n    assert.expect(2);\n    var changed = 0, model = new Backbone.Model({a: null});\n    model.on('change', function() {\n      assert.ok(this.hasChanged('a'));\n    })\n    .on('change:a', function() {\n      changed++;\n    })\n    .set({a: undefined});\n    assert.equal(changed, 1);\n  });\n\n  QUnit.test('#582, #425, change:attribute callbacks should fire after all changes have occurred', function(assert) {\n    assert.expect(9);\n    var model = new Backbone.Model;\n\n    var assertion = function() {\n      assert.equal(model.get('a'), 'a');\n      assert.equal(model.get('b'), 'b');\n      assert.equal(model.get('c'), 'c');\n    };\n\n    model.on('change:a', assertion);\n    model.on('change:b', assertion);\n    model.on('change:c', assertion);\n\n    model.set({a: 'a', b: 'b', c: 'c'});\n  });\n\n  QUnit.test('#871, set with attributes property', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    model.set({attributes: true});\n    assert.ok(model.has('attributes'));\n  });\n\n  QUnit.test('set value regardless of equality/change', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model({x: []});\n    var a = [];\n    model.set({x: a});\n    assert.ok(model.get('x') === a);\n  });\n\n  QUnit.test('set same value does not trigger change', function(assert) {\n    assert.expect(0);\n    var model = new Backbone.Model({x: 1});\n    model.on('change change:x', function() { assert.ok(false); });\n    model.set({x: 1});\n    model.set({x: 1});\n  });\n\n  QUnit.test('unset does not fire a change for undefined attributes', function(assert) {\n    assert.expect(0);\n    var model = new Backbone.Model({x: undefined});\n    model.on('change:x', function(){ assert.ok(false); });\n    model.unset('x');\n  });\n\n  QUnit.test('set: undefined values', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model({x: undefined});\n    assert.ok('x' in model.attributes);\n  });\n\n  QUnit.test('hasChanged works outside of change events, and true within', function(assert) {\n    assert.expect(6);\n    var model = new Backbone.Model({x: 1});\n    model.on('change:x', function() {\n      assert.ok(model.hasChanged('x'));\n      assert.equal(model.get('x'), 1);\n    });\n    model.set({x: 2}, {silent: true});\n    assert.ok(model.hasChanged());\n    assert.equal(model.hasChanged('x'), true);\n    model.set({x: 1});\n    assert.ok(model.hasChanged());\n    assert.equal(model.hasChanged('x'), true);\n  });\n\n  QUnit.test('hasChanged gets cleared on the following set', function(assert) {\n    assert.expect(4);\n    var model = new Backbone.Model;\n    model.set({x: 1});\n    assert.ok(model.hasChanged());\n    model.set({x: 1});\n    assert.ok(!model.hasChanged());\n    model.set({x: 2});\n    assert.ok(model.hasChanged());\n    model.set({});\n    assert.ok(!model.hasChanged());\n  });\n\n  QUnit.test('save with `wait` succeeds without `validate`', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    model.url = '/test';\n    model.save({x: 1}, {wait: true});\n    assert.ok(this.syncArgs.model === model);\n  });\n\n  QUnit.test(\"save without `wait` doesn't set invalid attributes\", function(assert) {\n    var model = new Backbone.Model();\n    model.validate = function() { return 1; };\n    model.save({a: 1});\n    assert.equal(model.get('a'), void 0);\n  });\n\n  QUnit.test(\"save doesn't validate twice\", function(assert) {\n    var model = new Backbone.Model();\n    var times = 0;\n    model.sync = function() {};\n    model.validate = function() { ++times; };\n    model.save({});\n    assert.equal(times, 1);\n  });\n\n  QUnit.test('`hasChanged` for falsey keys', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model();\n    model.set({x: true}, {silent: true});\n    assert.ok(!model.hasChanged(0));\n    assert.ok(!model.hasChanged(''));\n  });\n\n  QUnit.test('`previous` for falsey keys', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model({'0': true, '': true});\n    model.set({'0': false, '': false}, {silent: true});\n    assert.equal(model.previous(0), true);\n    assert.equal(model.previous(''), true);\n  });\n\n  QUnit.test('`save` with `wait` sends correct attributes', function(assert) {\n    assert.expect(5);\n    var changed = 0;\n    var model = new Backbone.Model({x: 1, y: 2});\n    model.url = '/test';\n    model.on('change:x', function() { changed++; });\n    model.save({x: 3}, {wait: true});\n    assert.deepEqual(JSON.parse(this.ajaxSettings.data), {x: 3, y: 2});\n    assert.equal(model.get('x'), 1);\n    assert.equal(changed, 0);\n    this.syncArgs.options.success({});\n    assert.equal(model.get('x'), 3);\n    assert.equal(changed, 1);\n  });\n\n  QUnit.test(\"a failed `save` with `wait` doesn't leave attributes behind\", function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model;\n    model.url = '/test';\n    model.save({x: 1}, {wait: true});\n    assert.equal(model.get('x'), void 0);\n  });\n\n  QUnit.test('#1030 - `save` with `wait` results in correct attributes if success is called during sync', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model({x: 1, y: 2});\n    model.sync = function(method, m, options) {\n      options.success();\n    };\n    model.on('change:x', function() { assert.ok(true); });\n    model.save({x: 3}, {wait: true});\n    assert.equal(model.get('x'), 3);\n  });\n\n  QUnit.test('save with wait validates attributes', function(assert) {\n    var model = new Backbone.Model();\n    model.url = '/test';\n    model.validate = function() { assert.ok(true); };\n    model.save({x: 1}, {wait: true});\n  });\n\n  QUnit.test('save turns on parse flag', function(assert) {\n    var Model = Backbone.Model.extend({\n      sync: function(method, m, options) { assert.ok(options.parse); }\n    });\n    new Model().save();\n  });\n\n  QUnit.test(\"nested `set` during `'change:attr'`\", function(assert) {\n    assert.expect(2);\n    var events = [];\n    var model = new Backbone.Model();\n    model.on('all', function(event) { events.push(event); });\n    model.on('change', function() {\n      model.set({z: true}, {silent: true});\n    });\n    model.on('change:x', function() {\n      model.set({y: true});\n    });\n    model.set({x: true});\n    assert.deepEqual(events, ['change:y', 'change:x', 'change']);\n    events = [];\n    model.set({z: true});\n    assert.deepEqual(events, []);\n  });\n\n  QUnit.test('nested `change` only fires once', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    model.on('change', function() {\n      assert.ok(true);\n      model.set({x: true});\n    });\n    model.set({x: true});\n  });\n\n  QUnit.test(\"nested `set` during `'change'`\", function(assert) {\n    assert.expect(6);\n    var count = 0;\n    var model = new Backbone.Model();\n    model.on('change', function() {\n      switch (count++) {\n        case 0:\n          assert.deepEqual(this.changedAttributes(), {x: true});\n          assert.equal(model.previous('x'), undefined);\n          model.set({y: true});\n          break;\n        case 1:\n          assert.deepEqual(this.changedAttributes(), {x: true, y: true});\n          assert.equal(model.previous('x'), undefined);\n          model.set({z: true});\n          break;\n        case 2:\n          assert.deepEqual(this.changedAttributes(), {x: true, y: true, z: true});\n          assert.equal(model.previous('y'), undefined);\n          break;\n        default:\n          assert.ok(false);\n      }\n    });\n    model.set({x: true});\n  });\n\n  QUnit.test('nested `change` with silent', function(assert) {\n    assert.expect(3);\n    var count = 0;\n    var model = new Backbone.Model();\n    model.on('change:y', function() { assert.ok(false); });\n    model.on('change', function() {\n      switch (count++) {\n        case 0:\n          assert.deepEqual(this.changedAttributes(), {x: true});\n          model.set({y: true}, {silent: true});\n          model.set({z: true});\n          break;\n        case 1:\n          assert.deepEqual(this.changedAttributes(), {x: true, y: true, z: true});\n          break;\n        case 2:\n          assert.deepEqual(this.changedAttributes(), {z: false});\n          break;\n        default:\n          assert.ok(false);\n      }\n    });\n    model.set({x: true});\n    model.set({z: false});\n  });\n\n  QUnit.test('nested `change:attr` with silent', function(assert) {\n    assert.expect(0);\n    var model = new Backbone.Model();\n    model.on('change:y', function(){ assert.ok(false); });\n    model.on('change', function() {\n      model.set({y: true}, {silent: true});\n      model.set({z: true});\n    });\n    model.set({x: true});\n  });\n\n  QUnit.test('multiple nested changes with silent', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    model.on('change:x', function() {\n      model.set({y: 1}, {silent: true});\n      model.set({y: 2});\n    });\n    model.on('change:y', function(m, val) {\n      assert.equal(val, 2);\n    });\n    model.set({x: true});\n  });\n\n  QUnit.test('multiple nested changes with silent', function(assert) {\n    assert.expect(1);\n    var changes = [];\n    var model = new Backbone.Model();\n    model.on('change:b', function(m, val) { changes.push(val); });\n    model.on('change', function() {\n      model.set({b: 1});\n    });\n    model.set({b: 0});\n    assert.deepEqual(changes, [0, 1]);\n  });\n\n  QUnit.test('basic silent change semantics', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model;\n    model.set({x: 1});\n    model.on('change', function(){ assert.ok(true); });\n    model.set({x: 2}, {silent: true});\n    model.set({x: 1});\n  });\n\n  QUnit.test('nested set multiple times', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    model.on('change:b', function() {\n      assert.ok(true);\n    });\n    model.on('change:a', function() {\n      model.set({b: true});\n      model.set({b: true});\n    });\n    model.set({a: true});\n  });\n\n  QUnit.test('#1122 - clear does not alter options.', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    var options = {};\n    model.clear(options);\n    assert.ok(!options.unset);\n  });\n\n  QUnit.test('#1122 - unset does not alter options.', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    var options = {};\n    model.unset('x', options);\n    assert.ok(!options.unset);\n  });\n\n  QUnit.test('#1355 - `options` is passed to success callbacks', function(assert) {\n    assert.expect(3);\n    var model = new Backbone.Model();\n    var opts = {\n      success: function( m, resp, options ) {\n        assert.ok(options);\n      }\n    };\n    model.sync = function(method, m, options) {\n      options.success();\n    };\n    model.save({id: 1}, opts);\n    model.fetch(opts);\n    model.destroy(opts);\n  });\n\n  QUnit.test(\"#1412 - Trigger 'sync' event.\", function(assert) {\n    assert.expect(3);\n    var model = new Backbone.Model({id: 1});\n    model.sync = function(method, m, options) { options.success(); };\n    model.on('sync', function(){ assert.ok(true); });\n    model.fetch();\n    model.save();\n    model.destroy();\n  });\n\n  QUnit.test('#1365 - Destroy: New models execute success callback.', function(assert) {\n    var done = assert.async();\n    assert.expect(2);\n    new Backbone.Model()\n    .on('sync', function() { assert.ok(false); })\n    .on('destroy', function(){ assert.ok(true); })\n    .destroy({success: function(){\n      assert.ok(true);\n      done();\n    }});\n  });\n\n  QUnit.test('#1433 - Save: An invalid model cannot be persisted.', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model;\n    model.validate = function(){ return 'invalid'; };\n    model.sync = function(){ assert.ok(false); };\n    assert.strictEqual(model.save(), false);\n  });\n\n  QUnit.test(\"#1377 - Save without attrs triggers 'error'.\", function(assert) {\n    assert.expect(1);\n    var Model = Backbone.Model.extend({\n      url: '/test/',\n      sync: function(method, m, options){ options.success(); },\n      validate: function(){ return 'invalid'; }\n    });\n    var model = new Model({id: 1});\n    model.on('invalid', function(){ assert.ok(true); });\n    model.save();\n  });\n\n  QUnit.test('#1545 - `undefined` can be passed to a model constructor without coersion', function(assert) {\n    var Model = Backbone.Model.extend({\n      defaults: {one: 1},\n      initialize: function(attrs, opts) {\n        assert.equal(attrs, undefined);\n      }\n    });\n    var emptyattrs = new Model();\n    var undefinedattrs = new Model(undefined);\n  });\n\n  QUnit.test('#1478 - Model `save` does not trigger change on unchanged attributes', function(assert) {\n    var done = assert.async();\n    assert.expect(0);\n    var Model = Backbone.Model.extend({\n      sync: function(method, m, options) {\n        setTimeout(function(){\n          options.success();\n          done();\n        }, 0);\n      }\n    });\n    new Model({x: true})\n    .on('change:x', function(){ assert.ok(false); })\n    .save(null, {wait: true});\n  });\n\n  QUnit.test('#1664 - Changing from one value, silently to another, back to original triggers a change.', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model({x: 1});\n    model.on('change:x', function() { assert.ok(true); });\n    model.set({x: 2}, {silent: true});\n    model.set({x: 3}, {silent: true});\n    model.set({x: 1});\n  });\n\n  QUnit.test('#1664 - multiple silent changes nested inside a change event', function(assert) {\n    assert.expect(2);\n    var changes = [];\n    var model = new Backbone.Model();\n    model.on('change', function() {\n      model.set({a: 'c'}, {silent: true});\n      model.set({b: 2}, {silent: true});\n      model.unset('c', {silent: true});\n    });\n    model.on('change:a change:b change:c', function(m, val) { changes.push(val); });\n    model.set({a: 'a', b: 1, c: 'item'});\n    assert.deepEqual(changes, ['a', 1, 'item']);\n    assert.deepEqual(model.attributes, {a: 'c', b: 2});\n  });\n\n  QUnit.test('#1791 - `attributes` is available for `parse`', function(assert) {\n    var Model = Backbone.Model.extend({\n      parse: function() { this.has('a'); } // shouldn't throw an error\n    });\n    var model = new Model(null, {parse: true});\n    assert.expect(0);\n  });\n\n  QUnit.test('silent changes in last `change` event back to original triggers change', function(assert) {\n    assert.expect(2);\n    var changes = [];\n    var model = new Backbone.Model();\n    model.on('change:a change:b change:c', function(m, val) { changes.push(val); });\n    model.on('change', function() {\n      model.set({a: 'c'}, {silent: true});\n    });\n    model.set({a: 'a'});\n    assert.deepEqual(changes, ['a']);\n    model.set({a: 'a'});\n    assert.deepEqual(changes, ['a', 'a']);\n  });\n\n  QUnit.test('#1943 change calculations should use _.isEqual', function(assert) {\n    var model = new Backbone.Model({a: {key: 'value'}});\n    model.set('a', {key: 'value'}, {silent: true});\n    assert.equal(model.changedAttributes(), false);\n  });\n\n  QUnit.test('#1964 - final `change` event is always fired, regardless of interim changes', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    model.on('change:property', function() {\n      model.set('property', 'bar');\n    });\n    model.on('change', function() {\n      assert.ok(true);\n    });\n    model.set('property', 'foo');\n  });\n\n  QUnit.test('isValid', function(assert) {\n    var model = new Backbone.Model({valid: true});\n    model.validate = function(attrs) {\n      if (!attrs.valid) return 'invalid';\n    };\n    assert.equal(model.isValid(), true);\n    assert.equal(model.set({valid: false}, {validate: true}), false);\n    assert.equal(model.isValid(), true);\n    model.set({valid: false});\n    assert.equal(model.isValid(), false);\n    assert.ok(!model.set('valid', false, {validate: true}));\n  });\n\n  QUnit.test('mixin', function(assert) {\n    Backbone.Model.mixin({\n      isEqual: function(model1, model2) {\n        return _.isEqual(model1, model2.attributes);\n      }\n    });\n\n    var model1 = new Backbone.Model({\n      a: {b: 2}, c: 3\n    });\n    var model2 = new Backbone.Model({\n      a: {b: 2}, c: 3\n    });\n    var model3 = new Backbone.Model({\n      a: {b: 4}, c: 3\n    });\n\n    assert.equal(model1.isEqual(model2), true);\n    assert.equal(model1.isEqual(model3), false);\n  });\n\n\n  QUnit.test('#1179 - isValid returns true in the absence of validate.', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    model.validate = null;\n    assert.ok(model.isValid());\n  });\n\n  QUnit.test('#1961 - Creating a model with {validate:true} will call validate and use the error callback', function(assert) {\n    var Model = Backbone.Model.extend({\n      validate: function(attrs) {\n        if (attrs.id === 1) return \"This shouldn't happen\";\n      }\n    });\n    var model = new Model({id: 1}, {validate: true});\n    assert.equal(model.validationError, \"This shouldn't happen\");\n  });\n\n  QUnit.test('toJSON receives attrs during save(..., {wait: true})', function(assert) {\n    assert.expect(1);\n    var Model = Backbone.Model.extend({\n      url: '/test',\n      toJSON: function() {\n        assert.strictEqual(this.attributes.x, 1);\n        return _.clone(this.attributes);\n      }\n    });\n    var model = new Model;\n    model.save({x: 1}, {wait: true});\n  });\n\n  QUnit.test('#2034 - nested set with silent only triggers one change', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model();\n    model.on('change', function() {\n      model.set({b: true}, {silent: true});\n      assert.ok(true);\n    });\n    model.set({a: true});\n  });\n\n  QUnit.test('#3778 - id will only be updated if it is set', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model({id: 1});\n    model.id = 2;\n    model.set({foo: 'bar'});\n    assert.equal(model.id, 2);\n    model.set({id: 3});\n    assert.equal(model.id, 3);\n  });\n\n  QUnit.test('#4289 - Trigger \"changeId\" need to be generate only if the content id change', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model({id: 1});\n    model.idAttribute = 'id';\n    model.on('changeId', function(m) {\n      assert.equal(m.get('id'), 2);\n    });\n    model.set({id: 1});\n    model.set({id: 2});\n  });\n\n})(QUnit);\n"
  },
  {
    "path": "test/noconflict.js",
    "content": "(function(QUnit) {\n\n  QUnit.module('Backbone.noConflict');\n\n  QUnit.test('noConflict', function(assert) {\n    assert.expect(2);\n    var noconflictBackbone = Backbone.noConflict();\n    assert.equal(window.Backbone, undefined, 'Returned window.Backbone');\n    window.Backbone = noconflictBackbone;\n    assert.equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');\n  });\n\n})(QUnit);\n"
  },
  {
    "path": "test/router.js",
    "content": "(function(QUnit) {\n\n  var router = null;\n  var location = null;\n  var lastRoute = null;\n  var lastArgs = [];\n\n  var onRoute = function(routerParam, route, args) {\n    lastRoute = route;\n    lastArgs = args;\n  };\n\n  var Location = function(href) {\n    this.replace(href);\n  };\n\n  _.extend(Location.prototype, {\n\n    parser: document.createElement('a'),\n\n    replace: function(href) {\n      this.parser.href = href;\n      _.extend(this, _.pick(this.parser,\n        'href',\n        'hash',\n        'host',\n        'search',\n        'fragment',\n        'pathname',\n        'protocol'\n      ));\n\n      // In IE, anchor.pathname does not contain a leading slash though\n      // window.location.pathname does.\n      if (!/^\\//.test(this.pathname)) this.pathname = '/' + this.pathname;\n    },\n\n    toString: function() {\n      return this.href;\n    }\n\n  });\n\n  QUnit.module('Backbone.Router', {\n\n    beforeEach: function() {\n      location = new Location('http://example.com');\n      Backbone.history = _.extend(new Backbone.History, {location: location});\n      router = new Router({testing: 101});\n      Backbone.history.interval = 9;\n      Backbone.history.start({pushState: false});\n      lastRoute = null;\n      lastArgs = [];\n      Backbone.history.on('route', onRoute);\n    },\n\n    afterEach: function() {\n      Backbone.history.stop();\n      Backbone.history.off('route', onRoute);\n    }\n\n  });\n\n  var ExternalObject = {\n    value: 'unset',\n\n    routingFunction: function(value) {\n      this.value = value;\n    }\n  };\n  ExternalObject.routingFunction = _.bind(ExternalObject.routingFunction, ExternalObject);\n\n  var Router = Backbone.Router.extend({\n\n    count: 0,\n\n    routes: {\n      'noCallback': 'noCallback',\n      'counter': 'counter',\n      'search/:query': 'search',\n      'search/:query/p:page': 'search',\n      'charñ': 'charUTF',\n      'char%C3%B1': 'charEscaped',\n      'contacts': 'contacts',\n      'contacts/new': 'newContact',\n      'contacts/:id': 'loadContact',\n      'route-event/:arg': 'routeEvent',\n      'optional(/:item)': 'optionalItem',\n      'named/optional/(y:z)': 'namedOptional',\n      'splat/*args/end': 'splat',\n      ':repo/compare/*from...*to': 'github',\n      'decode/:named/*splat': 'decode',\n      '*first/complex-*part/*rest': 'complex',\n      'query/:entity': 'query',\n      'function/:value': ExternalObject.routingFunction,\n      '*anything': 'anything'\n    },\n\n    preinitialize: function(options) {\n      this.testpreinit = 'foo';\n    },\n\n    initialize: function(options) {\n      this.testing = options.testing;\n      this.route('implicit', 'implicit');\n    },\n\n    counter: function() {\n      this.count++;\n    },\n\n    implicit: function() {\n      this.count++;\n    },\n\n    search: function(query, page) {\n      this.query = query;\n      this.page = page;\n    },\n\n    charUTF: function() {\n      this.charType = 'UTF';\n    },\n\n    charEscaped: function() {\n      this.charType = 'escaped';\n    },\n\n    contacts: function() {\n      this.contact = 'index';\n    },\n\n    newContact: function() {\n      this.contact = 'new';\n    },\n\n    loadContact: function() {\n      this.contact = 'load';\n    },\n\n    optionalItem: function(arg) {\n      this.arg = arg !== void 0 ? arg : null;\n    },\n\n    splat: function(args) {\n      this.args = args;\n    },\n\n    github: function(repo, from, to) {\n      this.repo = repo;\n      this.from = from;\n      this.to = to;\n    },\n\n    complex: function(first, part, rest) {\n      this.first = first;\n      this.part = part;\n      this.rest = rest;\n    },\n\n    query: function(entity, args) {\n      this.entity    = entity;\n      this.queryArgs = args;\n    },\n\n    anything: function(whatever) {\n      this.anything = whatever;\n    },\n\n    namedOptional: function(z) {\n      this.z = z;\n    },\n\n    decode: function(named, path) {\n      this.named = named;\n      this.path = path;\n    },\n\n    routeEvent: function(arg) {\n    }\n\n  });\n\n  QUnit.test('initialize', function(assert) {\n    assert.expect(1);\n    assert.equal(router.testing, 101);\n  });\n\n  QUnit.test('preinitialize', function(assert) {\n    assert.expect(1);\n    assert.equal(router.testpreinit, 'foo');\n  });\n\n  QUnit.test('routes (simple)', function(assert) {\n    assert.expect(4);\n    location.replace('http://example.com#search/news');\n    Backbone.history.checkUrl();\n    assert.equal(router.query, 'news');\n    assert.equal(router.page, void 0);\n    assert.equal(lastRoute, 'search');\n    assert.equal(lastArgs[0], 'news');\n  });\n\n  QUnit.test('routes (simple, but unicode)', function(assert) {\n    assert.expect(4);\n    location.replace('http://example.com#search/тест');\n    Backbone.history.checkUrl();\n    assert.equal(router.query, 'тест');\n    assert.equal(router.page, void 0);\n    assert.equal(lastRoute, 'search');\n    assert.equal(lastArgs[0], 'тест');\n  });\n\n  QUnit.test('routes (two part)', function(assert) {\n    assert.expect(2);\n    location.replace('http://example.com#search/nyc/p10');\n    Backbone.history.checkUrl();\n    assert.equal(router.query, 'nyc');\n    assert.equal(router.page, '10');\n  });\n\n  QUnit.test('routes via navigate', function(assert) {\n    assert.expect(2);\n    Backbone.history.navigate('search/manhattan/p20', {trigger: true});\n    assert.equal(router.query, 'manhattan');\n    assert.equal(router.page, '20');\n  });\n\n  QUnit.test('routes via navigate with params', function(assert) {\n    assert.expect(1);\n    Backbone.history.navigate('query/test?a=b', {trigger: true});\n    assert.equal(router.queryArgs, 'a=b');\n  });\n\n  QUnit.test('routes via navigate for backwards-compatibility', function(assert) {\n    assert.expect(2);\n    Backbone.history.navigate('search/manhattan/p20', true);\n    assert.equal(router.query, 'manhattan');\n    assert.equal(router.page, '20');\n  });\n\n  QUnit.test('reports matched route via nagivate', function(assert) {\n    assert.expect(1);\n    assert.ok(Backbone.history.navigate('search/manhattan/p20', true));\n  });\n\n  QUnit.test('route precedence via navigate', function(assert) {\n    assert.expect(6);\n\n    // Check both 0.9.x and backwards-compatibility options\n    _.each([{trigger: true}, true], function(options) {\n      Backbone.history.navigate('contacts', options);\n      assert.equal(router.contact, 'index');\n      Backbone.history.navigate('contacts/new', options);\n      assert.equal(router.contact, 'new');\n      Backbone.history.navigate('contacts/foo', options);\n      assert.equal(router.contact, 'load');\n    });\n  });\n\n  QUnit.test('loadUrl is not called for identical routes.', function(assert) {\n    assert.expect(0);\n    Backbone.history.loadUrl = function() { assert.ok(false); };\n    location.replace('http://example.com#route');\n    Backbone.history.navigate('route');\n    Backbone.history.navigate('/route');\n    Backbone.history.navigate('/route');\n  });\n\n  QUnit.test('use implicit callback if none provided', function(assert) {\n    assert.expect(1);\n    router.count = 0;\n    router.navigate('implicit', {trigger: true});\n    assert.equal(router.count, 1);\n  });\n\n  QUnit.test('routes via navigate with {replace: true}', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com#start_here');\n    Backbone.history.checkUrl();\n    location.replace = function(href) {\n      assert.strictEqual(href, new Location('http://example.com#end_here').href);\n    };\n    Backbone.history.navigate('end_here', {replace: true});\n  });\n\n  QUnit.test('routes (splats)', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com#splat/long-list/of/splatted_99args/end');\n    Backbone.history.checkUrl();\n    assert.equal(router.args, 'long-list/of/splatted_99args');\n  });\n\n  QUnit.test('routes (github)', function(assert) {\n    assert.expect(3);\n    location.replace('http://example.com#backbone/compare/1.0...braddunbar:with/slash');\n    Backbone.history.checkUrl();\n    assert.equal(router.repo, 'backbone');\n    assert.equal(router.from, '1.0');\n    assert.equal(router.to, 'braddunbar:with/slash');\n  });\n\n  QUnit.test('routes (optional)', function(assert) {\n    assert.expect(2);\n    location.replace('http://example.com#optional');\n    Backbone.history.checkUrl();\n    assert.ok(!router.arg);\n    location.replace('http://example.com#optional/thing');\n    Backbone.history.checkUrl();\n    assert.equal(router.arg, 'thing');\n  });\n\n  QUnit.test('routes (complex)', function(assert) {\n    assert.expect(3);\n    location.replace('http://example.com#one/two/three/complex-part/four/five/six/seven');\n    Backbone.history.checkUrl();\n    assert.equal(router.first, 'one/two/three');\n    assert.equal(router.part, 'part');\n    assert.equal(router.rest, 'four/five/six/seven');\n  });\n\n  QUnit.test('routes (query)', function(assert) {\n    assert.expect(5);\n    location.replace('http://example.com#query/mandel?a=b&c=d');\n    Backbone.history.checkUrl();\n    assert.equal(router.entity, 'mandel');\n    assert.equal(router.queryArgs, 'a=b&c=d');\n    assert.equal(lastRoute, 'query');\n    assert.equal(lastArgs[0], 'mandel');\n    assert.equal(lastArgs[1], 'a=b&c=d');\n  });\n\n  QUnit.test('routes (anything)', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com#doesnt-match-a-route');\n    Backbone.history.checkUrl();\n    assert.equal(router.anything, 'doesnt-match-a-route');\n  });\n\n  QUnit.test('routes (function)', function(assert) {\n    assert.expect(3);\n    router.on('route', function(name) {\n      assert.ok(name === '');\n    });\n    assert.equal(ExternalObject.value, 'unset');\n    location.replace('http://example.com#function/set');\n    Backbone.history.checkUrl();\n    assert.equal(ExternalObject.value, 'set');\n  });\n\n  QUnit.test('Decode named parameters, not splats.', function(assert) {\n    assert.expect(2);\n    location.replace('http://example.com#decode/a%2Fb/c%2Fd/e');\n    Backbone.history.checkUrl();\n    assert.strictEqual(router.named, 'a/b');\n    assert.strictEqual(router.path, 'c/d/e');\n  });\n\n  QUnit.test('fires event when router doesn\\'t have callback on it', function(assert) {\n    assert.expect(1);\n    router.on('route:noCallback', function() { assert.ok(true); });\n    location.replace('http://example.com#noCallback');\n    Backbone.history.checkUrl();\n  });\n\n  QUnit.test('No events are triggered if #execute returns false.', function(assert) {\n    assert.expect(1);\n    var MyRouter = Backbone.Router.extend({\n\n      routes: {\n        foo: function() {\n          assert.ok(true);\n        }\n      },\n\n      execute: function(callback, args) {\n        callback.apply(this, args);\n        return false;\n      }\n\n    });\n\n    var myRouter = new MyRouter;\n\n    myRouter.on('route route:foo', function() {\n      assert.ok(false);\n    });\n\n    Backbone.history.on('route', function() {\n      assert.ok(false);\n    });\n\n    location.replace('http://example.com#foo');\n    Backbone.history.checkUrl();\n  });\n\n  QUnit.test('#933, #908 - leading slash', function(assert) {\n    assert.expect(2);\n    location.replace('http://example.com/root/foo');\n\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.start({root: '/root', hashChange: false, silent: true});\n    assert.strictEqual(Backbone.history.getFragment(), 'foo');\n\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.start({root: '/root/', hashChange: false, silent: true});\n    assert.strictEqual(Backbone.history.getFragment(), 'foo');\n  });\n\n  QUnit.test('#967 - Route callback gets passed encoded values.', function(assert) {\n    assert.expect(3);\n    var route = 'has%2Fslash/complex-has%23hash/has%20space';\n    Backbone.history.navigate(route, {trigger: true});\n    assert.strictEqual(router.first, 'has/slash');\n    assert.strictEqual(router.part, 'has#hash');\n    assert.strictEqual(router.rest, 'has space');\n  });\n\n  QUnit.test('correctly handles URLs with % (#868)', function(assert) {\n    assert.expect(3);\n    location.replace('http://example.com#search/fat%3A1.5%25');\n    Backbone.history.checkUrl();\n    location.replace('http://example.com#search/fat');\n    Backbone.history.checkUrl();\n    assert.equal(router.query, 'fat');\n    assert.equal(router.page, void 0);\n    assert.equal(lastRoute, 'search');\n  });\n\n  QUnit.test('#2666 - Hashes with UTF8 in them.', function(assert) {\n    assert.expect(2);\n    Backbone.history.navigate('charñ', {trigger: true});\n    assert.equal(router.charType, 'UTF');\n    Backbone.history.navigate('char%C3%B1', {trigger: true});\n    assert.equal(router.charType, 'UTF');\n  });\n\n  QUnit.test('#1185 - Use pathname when hashChange is not wanted.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/path/name#hash');\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.start({hashChange: false});\n    var fragment = Backbone.history.getFragment();\n    assert.strictEqual(fragment, location.pathname.replace(/^\\//, ''));\n  });\n\n  QUnit.test('#1206 - Strip leading slash before location.assign.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root/');\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.start({hashChange: false, root: '/root/'});\n    location.assign = function(pathname) {\n      assert.strictEqual(pathname, '/root/fragment');\n    };\n    Backbone.history.navigate('/fragment');\n  });\n\n  QUnit.test('#1387 - Root fragment without trailing slash.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root');\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.start({hashChange: false, root: '/root/', silent: true});\n    assert.strictEqual(Backbone.history.getFragment(), '');\n  });\n\n  QUnit.test('#1366 - History does not prepend root to fragment.', function(assert) {\n    assert.expect(2);\n    Backbone.history.stop();\n    location.replace('http://example.com/root/');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {\n          assert.strictEqual(url, '/root/x');\n        }\n      }\n    });\n    Backbone.history.start({\n      root: '/root/',\n      pushState: true,\n      hashChange: false\n    });\n    Backbone.history.navigate('x');\n    assert.strictEqual(Backbone.history.fragment, 'x');\n  });\n\n  QUnit.test('Normalize root.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {\n          assert.strictEqual(url, '/root/fragment');\n        }\n      }\n    });\n    Backbone.history.start({\n      pushState: true,\n      root: '/root',\n      hashChange: false\n    });\n    Backbone.history.navigate('fragment');\n  });\n\n  QUnit.test('Normalize root.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root#fragment');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {},\n        replaceState: function(state, title, url) {\n          assert.strictEqual(url, '/root/fragment');\n        }\n      }\n    });\n    Backbone.history.start({\n      pushState: true,\n      root: '/root'\n    });\n  });\n\n  QUnit.test('Normalize root.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root');\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.loadUrl = function() { assert.ok(true); };\n    Backbone.history.start({\n      pushState: true,\n      root: '/root'\n    });\n  });\n\n  QUnit.test('Normalize root - leading slash.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function() {},\n        replaceState: function() {}\n      }\n    });\n    Backbone.history.start({root: 'root'});\n    assert.strictEqual(Backbone.history.root, '/root/');\n  });\n\n  QUnit.test('Transition from hashChange to pushState.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root#x/y');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function() {},\n        replaceState: function(state, title, url) {\n          assert.strictEqual(url, '/root/x/y');\n        }\n      }\n    });\n    Backbone.history.start({\n      root: 'root',\n      pushState: true\n    });\n  });\n\n  QUnit.test('#1619: Router: Normalize empty root', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function() {},\n        replaceState: function() {}\n      }\n    });\n    Backbone.history.start({root: ''});\n    assert.strictEqual(Backbone.history.root, '/');\n  });\n\n  QUnit.test('#1619: Router: nagivate with empty root', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {\n          assert.strictEqual(url, '/fragment');\n        }\n      }\n    });\n    Backbone.history.start({\n      pushState: true,\n      root: '',\n      hashChange: false\n    });\n    Backbone.history.navigate('fragment');\n  });\n\n  QUnit.test('Transition from pushState to hashChange.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root/x/y?a=b');\n    location.replace = function(url) {\n      assert.strictEqual(url, '/root#x/y?a=b');\n    };\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: null,\n        replaceState: null\n      }\n    });\n    Backbone.history.start({\n      root: 'root',\n      pushState: true\n    });\n  });\n\n  QUnit.test('#1695 - hashChange to pushState with search.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root#x/y?a=b');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function() {},\n        replaceState: function(state, title, url) {\n          assert.strictEqual(url, '/root/x/y?a=b');\n        }\n      }\n    });\n    Backbone.history.start({\n      root: 'root',\n      pushState: true\n    });\n  });\n\n  QUnit.test('#1746 - Router allows empty route.', function(assert) {\n    assert.expect(1);\n    var MyRouter = Backbone.Router.extend({\n      routes: {'': 'empty'},\n      empty: function() {},\n      route: function(route) {\n        assert.strictEqual(route, '');\n      }\n    });\n    new MyRouter;\n  });\n\n  QUnit.test('#1794 - Trailing space in fragments.', function(assert) {\n    assert.expect(1);\n    var history = new Backbone.History;\n    assert.strictEqual(history.getFragment('fragment   '), 'fragment');\n  });\n\n  QUnit.test('#1820 - Leading slash and trailing space.', function(assert) {\n    assert.expect(1);\n    var history = new Backbone.History;\n    assert.strictEqual(history.getFragment('/fragment '), 'fragment');\n  });\n\n  QUnit.test('#1980 - Optional parameters.', function(assert) {\n    assert.expect(2);\n    location.replace('http://example.com#named/optional/y');\n    Backbone.history.checkUrl();\n    assert.strictEqual(router.z, undefined);\n    location.replace('http://example.com#named/optional/y123');\n    Backbone.history.checkUrl();\n    assert.strictEqual(router.z, '123');\n  });\n\n  QUnit.test('#2062 - Trigger \"route\" event on router instance.', function(assert) {\n    assert.expect(2);\n    router.on('route', function(name, args) {\n      assert.strictEqual(name, 'routeEvent');\n      assert.deepEqual(args, ['x', null]);\n    });\n    location.replace('http://example.com#route-event/x');\n    Backbone.history.checkUrl();\n  });\n\n  QUnit.test('#2255 - Extend routes by making routes a function.', function(assert) {\n    assert.expect(1);\n    var RouterBase = Backbone.Router.extend({\n      routes: function() {\n        return {\n          home: 'root',\n          index: 'index.html'\n        };\n      }\n    });\n\n    var RouterExtended = RouterBase.extend({\n      routes: function() {\n        var _super = RouterExtended.__super__.routes;\n        return _.extend(_super(), {show: 'show', search: 'search'});\n      }\n    });\n\n    var myRouter = new RouterExtended();\n    assert.deepEqual({home: 'root', index: 'index.html', show: 'show', search: 'search'}, myRouter.routes);\n  });\n\n  QUnit.test('#2538 - hashChange to pushState only if both requested.', function(assert) {\n    assert.expect(0);\n    Backbone.history.stop();\n    location.replace('http://example.com/root?a=b#x/y');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function() {},\n        replaceState: function() { assert.ok(false); }\n      }\n    });\n    Backbone.history.start({\n      root: 'root',\n      pushState: true,\n      hashChange: false\n    });\n  });\n\n  QUnit.test('No hash fallback.', function(assert) {\n    assert.expect(0);\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function() {},\n        replaceState: function() {}\n      }\n    });\n\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        hash: function() { assert.ok(false); }\n      }\n    });\n    var myRouter = new MyRouter;\n\n    location.replace('http://example.com/');\n    Backbone.history.start({\n      pushState: true,\n      hashChange: false\n    });\n    location.replace('http://example.com/nomatch#hash');\n    Backbone.history.checkUrl();\n  });\n\n  QUnit.test('#2656 - No trailing slash on root.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {\n          assert.strictEqual(url, '/root');\n        }\n      }\n    });\n    location.replace('http://example.com/root/path');\n    Backbone.history.start({pushState: true, hashChange: false, root: 'root'});\n    Backbone.history.navigate('');\n  });\n\n  QUnit.test('#2656 - No trailing slash on root.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {\n          assert.strictEqual(url, '/');\n        }\n      }\n    });\n    location.replace('http://example.com/path');\n    Backbone.history.start({pushState: true, hashChange: false});\n    Backbone.history.navigate('');\n  });\n\n  QUnit.test('#2656 - No trailing slash on root.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {\n          assert.strictEqual(url, '/root?x=1');\n        }\n      }\n    });\n    location.replace('http://example.com/root/path');\n    Backbone.history.start({pushState: true, hashChange: false, root: 'root'});\n    Backbone.history.navigate('?x=1');\n  });\n\n  QUnit.test('#3391 - Empty root normalizes to single slash.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {\n          assert.strictEqual(url, '/');\n        }\n      }\n    });\n    location.replace('http://example.com/root/path');\n    Backbone.history.start({pushState: true, hashChange: false, root: ''});\n    Backbone.history.navigate('');\n  });\n\n  QUnit.test('#3391 - Use trailing slash on root when trailingSlash is true.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {\n          assert.strictEqual(url, '/root/');\n        }\n      }\n    });\n    location.replace('http://example.com/root/path');\n    Backbone.history.start({pushState: true, hashChange: false, root: 'root', trailingSlash: true});\n    Backbone.history.navigate('');\n  });\n\n  QUnit.test('#2765 - Fragment matching sans query/hash.', function(assert) {\n    assert.expect(2);\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function(state, title, url) {\n          assert.strictEqual(url, '/path?query#hash');\n        }\n      }\n    });\n\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        path: function() { assert.ok(true); }\n      }\n    });\n    var myRouter = new MyRouter;\n\n    location.replace('http://example.com/');\n    Backbone.history.start({pushState: true, hashChange: false});\n    Backbone.history.navigate('path?query#hash', true);\n  });\n\n  QUnit.test('Do not decode the search params.', function(assert) {\n    assert.expect(1);\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        path: function(params) {\n          assert.strictEqual(params, 'x=y%3Fz');\n        }\n      }\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.navigate('path?x=y%3Fz', true);\n  });\n\n  QUnit.test('Navigate to a hash url.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.start({pushState: true});\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        path: function(params) {\n          assert.strictEqual(params, 'x=y');\n        }\n      }\n    });\n    var myRouter = new MyRouter;\n    location.replace('http://example.com/path?x=y#hash');\n    Backbone.history.checkUrl();\n  });\n\n  QUnit.test('#navigate to a hash url.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.start({pushState: true});\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        path: function(params) {\n          assert.strictEqual(params, 'x=y');\n        }\n      }\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.navigate('path?x=y#hash', true);\n  });\n\n  QUnit.test('unicode pathname', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com/myyjä');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        myyjä: function() {\n          assert.ok(true);\n        }\n      }\n    });\n    new MyRouter;\n    Backbone.history.start({pushState: true});\n  });\n\n  QUnit.test('unicode pathname with % in a parameter', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com/myyjä/foo%20%25%3F%2f%40%25%20bar');\n    location.pathname = '/myyj%C3%A4/foo%20%25%3F%2f%40%25%20bar';\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        'myyjä/:query': function(query) {\n          assert.strictEqual(query, 'foo %?/@% bar');\n        }\n      }\n    });\n    new MyRouter;\n    Backbone.history.start({pushState: true});\n  });\n\n  QUnit.test('newline in route', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com/stuff%0Anonsense?param=foo%0Abar');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        'stuff\\nnonsense': function() {\n          assert.ok(true);\n        }\n      }\n    });\n    new MyRouter;\n    Backbone.history.start({pushState: true});\n  });\n\n  QUnit.test('Router#execute receives callback, args, name.', function(assert) {\n    assert.expect(3);\n    location.replace('http://example.com#foo/123/bar?x=y');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var MyRouter = Backbone.Router.extend({\n      routes: {'foo/:id/bar': 'foo'},\n      foo: function() {},\n      execute: function(callback, args, name) {\n        assert.strictEqual(callback, this.foo);\n        assert.deepEqual(args, ['123', 'x=y']);\n        assert.strictEqual(name, 'foo');\n      }\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start();\n  });\n\n  QUnit.test('pushState to hashChange with only search params.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com?a=b');\n    location.replace = function(url) {\n      assert.strictEqual(url, '/#?a=b');\n    };\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: null\n    });\n    Backbone.history.start({pushState: true});\n  });\n\n  QUnit.test('#3123 - History#navigate decodes before comparison.', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/shop/search?keyword=short%20dress');\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: function() { assert.ok(false); },\n        replaceState: function() { assert.ok(false); }\n      }\n    });\n    Backbone.history.start({pushState: true});\n    Backbone.history.navigate('shop/search?keyword=short%20dress', true);\n    assert.strictEqual(Backbone.history.fragment, 'shop/search?keyword=short dress');\n  });\n\n  QUnit.test('#3175 - Urls in the params', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com#login?a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db');\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var myRouter = new Backbone.Router;\n    myRouter.route('login', function(params) {\n      assert.strictEqual(params, 'a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db');\n    });\n    Backbone.history.start();\n  });\n\n  QUnit.test('#3358 - pushState to hashChange transition with search params', function(assert) {\n    assert.expect(1);\n    Backbone.history.stop();\n    location.replace('http://example.com/root?foo=bar');\n    location.replace = function(url) {\n      assert.strictEqual(url, '/root#?foo=bar');\n    };\n    Backbone.history = _.extend(new Backbone.History, {\n      location: location,\n      history: {\n        pushState: undefined,\n        replaceState: undefined\n      }\n    });\n    Backbone.history.start({root: '/root', pushState: true});\n  });\n\n  QUnit.test('Paths that don\\'t match the root should not match no root', function(assert) {\n    assert.expect(0);\n    location.replace('http://example.com/foo');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        foo: function() {\n          assert.ok(false, 'should not match unless root matches');\n        }\n      }\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: 'root', pushState: true});\n  });\n\n  QUnit.test('Paths that don\\'t match the root should not match roots of the same length', function(assert) {\n    assert.expect(0);\n    location.replace('http://example.com/xxxx/foo');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var MyRouter = Backbone.Router.extend({\n      routes: {\n        foo: function() {\n          assert.ok(false, 'should not match unless root matches');\n        }\n      }\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: 'root', pushState: true});\n  });\n\n  QUnit.test('roots with regex characters', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com/x+y.z/foo');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var MyRouter = Backbone.Router.extend({\n      routes: {foo: function() { assert.ok(true); }}\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: 'x+y.z', pushState: true});\n  });\n\n  QUnit.test('roots with unicode characters', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com/®ooτ/foo');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var MyRouter = Backbone.Router.extend({\n      routes: {foo: function() { assert.ok(true); }}\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: '®ooτ', pushState: true});\n  });\n\n  QUnit.test('roots without slash', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com/®ooτ');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    var MyRouter = Backbone.Router.extend({\n      routes: {'': function() { assert.ok(true); }}\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: '®ooτ', pushState: true});\n  });\n\n  QUnit.test('#4025 - navigate updates URL hash as is', function(assert) {\n    assert.expect(1);\n    var route = 'search/has%20space';\n    Backbone.history.navigate(route);\n    assert.strictEqual(location.hash, '#' + route);\n  });\n\n  QUnit.test('initial non-matching root triggers notfound event', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com/root#foo');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.on('notfound', function() { assert.ok(true); });\n    var MyRouter = Backbone.Router.extend({\n      routes: {foo: function() { assert.ok(false); }}\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: 'other'});\n  });\n\n  QUnit.test('later non-matching root triggers notfound event', function(assert) {\n    assert.expect(2);\n    location.replace('http://example.com/root#foo');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.on('notfound', function() { assert.ok(true); });\n    var MyRouter = Backbone.Router.extend({\n      routes: {foo: function() { assert.ok(true); }}\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: 'root'});\n    location.replace('http://example.com/other#foo');\n    Backbone.history.checkUrl();\n  });\n\n  QUnit.test('initial non-matching route triggers notfound event', function(assert) {\n    assert.expect(1);\n    location.replace('http://example.com/root#bar');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.on('notfound', function() { assert.ok(true); });\n    var MyRouter = Backbone.Router.extend({\n      routes: {foo: function() { assert.ok(false); }}\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: 'root'});\n  });\n\n  QUnit.test('later non-matching route triggers notfound event', function(assert) {\n    assert.expect(2);\n    location.replace('http://example.com/root#foo');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.on('notfound', function() { assert.ok(true); });\n    var MyRouter = Backbone.Router.extend({\n      routes: {foo: function() { assert.ok(true); }}\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: 'root'});\n    location.replace('http://example.com/other#bar');\n    Backbone.history.checkUrl();\n  });\n\n  QUnit.test('non-matching pushState route triggers notfound event', function(assert) {\n    assert.expect(2);\n    location.replace('http://example.com/root/foo');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.on('notfound', function() { assert.ok(true); });\n    var MyRouter = Backbone.Router.extend({\n      routes: {foo: function() { assert.ok(true); }}\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: 'root', pushState: true});\n    location.replace('http://example.com/other/bar');\n    Backbone.history.checkUrl();\n  });\n\n  QUnit.test('non-matching navigate triggers notfound event', function(assert) {\n    assert.expect(2);\n    location.replace('http://example.com/root#foo');\n    Backbone.history.stop();\n    Backbone.history = _.extend(new Backbone.History, {location: location});\n    Backbone.history.on('notfound', function() { assert.ok(true); });\n    var MyRouter = Backbone.Router.extend({\n      routes: {foo: function() { assert.ok(true); }}\n    });\n    var myRouter = new MyRouter;\n    Backbone.history.start({root: 'root'});\n    Backbone.history.navigate('http://example.com/other#bar', {trigger: true});\n  });\n\n})(QUnit);\n"
  },
  {
    "path": "test/setup/dom-setup.js",
    "content": "$('body').append(\n    '<div id=\"qunit\"></div>' +\n    '<div id=\"qunit-fixture\"></div>'\n);\n"
  },
  {
    "path": "test/setup/environment.js",
    "content": "(function(QUnit) {\n\n  var sync = Backbone.sync;\n  var ajax = Backbone.ajax;\n  var emulateHTTP = Backbone.emulateHTTP;\n  var emulateJSON = Backbone.emulateJSON;\n  var history = window.history;\n  var pushState = history.pushState;\n  var replaceState = history.replaceState;\n\n  QUnit.config.noglobals = true;\n\n  QUnit.testStart(function() {\n    var env = QUnit.config.current.testEnvironment;\n\n    // We never want to actually call these during tests.\n    history.pushState = history.replaceState = function() {};\n\n    // Capture ajax settings for comparison.\n    Backbone.ajax = function(settings) {\n      env.ajaxSettings = settings;\n    };\n\n    // Capture the arguments to Backbone.sync for comparison.\n    Backbone.sync = function(method, model, options) {\n      env.syncArgs = {\n        method: method,\n        model: model,\n        options: options\n      };\n      sync.apply(this, arguments);\n    };\n\n  });\n\n  QUnit.testDone(function() {\n    Backbone.sync = sync;\n    Backbone.ajax = ajax;\n    Backbone.emulateHTTP = emulateHTTP;\n    Backbone.emulateJSON = emulateJSON;\n    history.pushState = pushState;\n    history.replaceState = replaceState;\n  });\n\n})(QUnit);\n"
  },
  {
    "path": "test/sync.js",
    "content": "(function(QUnit) {\n\n  var Library = Backbone.Collection.extend({\n    url: function() { return '/library'; }\n  });\n  var library;\n\n  var attrs = {\n    title: 'The Tempest',\n    author: 'Bill Shakespeare',\n    length: 123\n  };\n\n  QUnit.module('Backbone.sync', {\n\n    beforeEach: function(assert) {\n      library = new Library;\n      library.create(attrs, {wait: false});\n    },\n\n    afterEach: function(assert) {\n      Backbone.emulateHTTP = false;\n    }\n\n  });\n\n  QUnit.test('read', function(assert) {\n    assert.expect(4);\n    library.fetch();\n    assert.equal(this.ajaxSettings.url, '/library');\n    assert.equal(this.ajaxSettings.type, 'GET');\n    assert.equal(this.ajaxSettings.dataType, 'json');\n    assert.ok(_.isEmpty(this.ajaxSettings.data));\n  });\n\n  QUnit.test('passing data', function(assert) {\n    assert.expect(3);\n    library.fetch({data: {a: 'a', one: 1}});\n    assert.equal(this.ajaxSettings.url, '/library');\n    assert.equal(this.ajaxSettings.data.a, 'a');\n    assert.equal(this.ajaxSettings.data.one, 1);\n  });\n\n  QUnit.test('create', function(assert) {\n    assert.expect(6);\n    assert.equal(this.ajaxSettings.url, '/library');\n    assert.equal(this.ajaxSettings.type, 'POST');\n    assert.equal(this.ajaxSettings.dataType, 'json');\n    var data = JSON.parse(this.ajaxSettings.data);\n    assert.equal(data.title, 'The Tempest');\n    assert.equal(data.author, 'Bill Shakespeare');\n    assert.equal(data.length, 123);\n  });\n\n  QUnit.test('update', function(assert) {\n    assert.expect(7);\n    library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});\n    assert.equal(this.ajaxSettings.url, '/library/1-the-tempest');\n    assert.equal(this.ajaxSettings.type, 'PUT');\n    assert.equal(this.ajaxSettings.dataType, 'json');\n    var data = JSON.parse(this.ajaxSettings.data);\n    assert.equal(data.id, '1-the-tempest');\n    assert.equal(data.title, 'The Tempest');\n    assert.equal(data.author, 'William Shakespeare');\n    assert.equal(data.length, 123);\n  });\n\n  QUnit.test('update with emulateHTTP and emulateJSON', function(assert) {\n    assert.expect(7);\n    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {\n      emulateHTTP: true,\n      emulateJSON: true\n    });\n    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');\n    assert.equal(this.ajaxSettings.type, 'POST');\n    assert.equal(this.ajaxSettings.dataType, 'json');\n    assert.equal(this.ajaxSettings.data._method, 'PUT');\n    var data = JSON.parse(this.ajaxSettings.data.model);\n    assert.equal(data.id, '2-the-tempest');\n    assert.equal(data.author, 'Tim Shakespeare');\n    assert.equal(data.length, 123);\n  });\n\n  QUnit.test('update with just emulateHTTP', function(assert) {\n    assert.expect(6);\n    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {\n      emulateHTTP: true\n    });\n    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');\n    assert.equal(this.ajaxSettings.type, 'POST');\n    assert.equal(this.ajaxSettings.contentType, 'application/json');\n    var data = JSON.parse(this.ajaxSettings.data);\n    assert.equal(data.id, '2-the-tempest');\n    assert.equal(data.author, 'Tim Shakespeare');\n    assert.equal(data.length, 123);\n  });\n\n  QUnit.test('update with just emulateJSON', function(assert) {\n    assert.expect(6);\n    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {\n      emulateJSON: true\n    });\n    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');\n    assert.equal(this.ajaxSettings.type, 'PUT');\n    assert.equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');\n    var data = JSON.parse(this.ajaxSettings.data.model);\n    assert.equal(data.id, '2-the-tempest');\n    assert.equal(data.author, 'Tim Shakespeare');\n    assert.equal(data.length, 123);\n  });\n\n  QUnit.test('read model', function(assert) {\n    assert.expect(3);\n    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});\n    library.first().fetch();\n    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');\n    assert.equal(this.ajaxSettings.type, 'GET');\n    assert.ok(_.isEmpty(this.ajaxSettings.data));\n  });\n\n  QUnit.test('destroy', function(assert) {\n    assert.expect(3);\n    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});\n    library.first().destroy({wait: true});\n    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');\n    assert.equal(this.ajaxSettings.type, 'DELETE');\n    assert.equal(this.ajaxSettings.data, null);\n  });\n\n  QUnit.test('destroy with emulateHTTP', function(assert) {\n    assert.expect(3);\n    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});\n    library.first().destroy({\n      emulateHTTP: true,\n      emulateJSON: true\n    });\n    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');\n    assert.equal(this.ajaxSettings.type, 'POST');\n    assert.equal(JSON.stringify(this.ajaxSettings.data), '{\"_method\":\"DELETE\"}');\n  });\n\n  QUnit.test('urlError', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model();\n    assert.raises(function() {\n      model.fetch();\n    });\n    model.fetch({url: '/one/two'});\n    assert.equal(this.ajaxSettings.url, '/one/two');\n  });\n\n  QUnit.test('#1052 - `options` is optional.', function(assert) {\n    assert.expect(0);\n    var model = new Backbone.Model();\n    model.url = '/test';\n    Backbone.sync('create', model);\n  });\n\n  QUnit.test('Backbone.ajax', function(assert) {\n    assert.expect(1);\n    Backbone.ajax = function(settings) {\n      assert.strictEqual(settings.url, '/test');\n    };\n    var model = new Backbone.Model();\n    model.url = '/test';\n    Backbone.sync('create', model);\n  });\n\n  QUnit.test('Call provided error callback on error.', function(assert) {\n    assert.expect(1);\n    var model = new Backbone.Model;\n    model.url = '/test';\n    Backbone.sync('read', model, {\n      error: function() { assert.ok(true); }\n    });\n    this.ajaxSettings.error();\n  });\n\n  QUnit.test('Use Backbone.emulateHTTP as default.', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model;\n    model.url = '/test';\n\n    Backbone.emulateHTTP = true;\n    model.sync('create', model);\n    assert.strictEqual(this.ajaxSettings.emulateHTTP, true);\n\n    Backbone.emulateHTTP = false;\n    model.sync('create', model);\n    assert.strictEqual(this.ajaxSettings.emulateHTTP, false);\n  });\n\n  QUnit.test('Use Backbone.emulateJSON as default.', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model;\n    model.url = '/test';\n\n    Backbone.emulateJSON = true;\n    model.sync('create', model);\n    assert.strictEqual(this.ajaxSettings.emulateJSON, true);\n\n    Backbone.emulateJSON = false;\n    model.sync('create', model);\n    assert.strictEqual(this.ajaxSettings.emulateJSON, false);\n  });\n\n  QUnit.test('#1756 - Call user provided beforeSend function.', function(assert) {\n    assert.expect(4);\n    Backbone.emulateHTTP = true;\n    var model = new Backbone.Model;\n    model.url = '/test';\n    var xhr = {\n      setRequestHeader: function(header, value) {\n        assert.strictEqual(header, 'X-HTTP-Method-Override');\n        assert.strictEqual(value, 'DELETE');\n      }\n    };\n    model.sync('delete', model, {\n      beforeSend: function(_xhr) {\n        assert.ok(_xhr === xhr);\n        return false;\n      }\n    });\n    assert.strictEqual(this.ajaxSettings.beforeSend(xhr), false);\n  });\n\n  QUnit.test('#2928 - Pass along `textStatus` and `errorThrown`.', function(assert) {\n    assert.expect(2);\n    var model = new Backbone.Model;\n    model.url = '/test';\n    model.on('error', function(m, xhr, options) {\n      assert.strictEqual(options.textStatus, 'textStatus');\n      assert.strictEqual(options.errorThrown, 'errorThrown');\n    });\n    model.fetch();\n    this.ajaxSettings.error({}, 'textStatus', 'errorThrown');\n  });\n\n})(QUnit);\n"
  },
  {
    "path": "test/vendor/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.8.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2012 jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)\n */\n(function( window, undefined ) {\nvar\n\t// A central reference to the root jQuery(document)\n\trootjQuery,\n\n\t// The deferred used on DOM ready\n\treadyList,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\tlocation = window.location,\n\tnavigator = window.navigator,\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$,\n\n\t// Save a reference to some core methods\n\tcore_push = Array.prototype.push,\n\tcore_slice = Array.prototype.slice,\n\tcore_indexOf = Array.prototype.indexOf,\n\tcore_toString = Object.prototype.toString,\n\tcore_hasOwn = Object.prototype.hasOwnProperty,\n\tcore_trim = String.prototype.trim,\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\treturn new jQuery.fn.init( selector, context, rootjQuery );\n\t},\n\n\t// Used for matching numbers\n\tcore_pnum = /[\\-+]?(?:\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/.source,\n\n\t// Used for detecting and trimming whitespace\n\tcore_rnotwhite = /\\S/,\n\tcore_rspace = /\\s+/,\n\n\t// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\trquickExpr = /^(?:[^#<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)/,\n\n\t// Match a standalone tag\n\trsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\n\n\t// JSON RegExp\n\trvalidchars = /^[\\],:{}\\s]*$/,\n\trvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n\trvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[\\da-fA-F]{4})/g,\n\trvalidtokens = /\"[^\"\\\\\\r\\n]*\"|true|false|null|-?(?:\\d\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn ( letter + \"\" ).toUpperCase();\n\t},\n\n\t// The ready event handler and self cleanup method\n\tDOMContentLoaded = function() {\n\t\tif ( document.addEventListener ) {\n\t\t\tdocument.removeEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\t\t\tjQuery.ready();\n\t\t} else if ( document.readyState === \"complete\" ) {\n\t\t\t// we're here because readyState === \"complete\" in oldIE\n\t\t\t// which is good enough for us to call the dom ready!\n\t\t\tdocument.detachEvent( \"onreadystatechange\", DOMContentLoaded );\n\t\t\tjQuery.ready();\n\t\t}\n\t},\n\n\t// [[Class]] -> type pairs\n\tclass2type = {};\n\njQuery.fn = jQuery.prototype = {\n\tconstructor: jQuery,\n\tinit: function( selector, context, rootjQuery ) {\n\t\tvar match, elem, ret, doc;\n\n\t\t// Handle $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle $(DOMElement)\n\t\tif ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\t\t\t\t\tdoc = ( context && context.nodeType ? context.ownerDocument || context : document );\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\tselector = jQuery.parseHTML( match[1], doc, true );\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tthis.attr.call( selector, context, true );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.merge( this, selector );\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn rootjQuery.ready( selector );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t},\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The current version of jQuery being used\n\tjquery: \"1.8.3\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\t// The number of elements contained in the matched element set\n\tsize: function() {\n\t\treturn this.length;\n\t},\n\n\ttoArray: function() {\n\t\treturn core_slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num == null ?\n\n\t\t\t// Return a 'clean' array\n\t\t\tthis.toArray() :\n\n\t\t\t// Return just the object\n\t\t\t( num < 0 ? this[ this.length + num ] : this[ num ] );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems, name, selector ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\tret.context = this.context;\n\n\t\tif ( name === \"find\" ) {\n\t\t\tret.selector = this.selector + ( this.selector ? \" \" : \"\" ) + selector;\n\t\t} else if ( name ) {\n\t\t\tret.selector = this.selector + \".\" + name + \"(\" + selector + \")\";\n\t\t}\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tready: function( fn ) {\n\t\t// Add the callback\n\t\tjQuery.ready.promise().done( fn );\n\n\t\treturn this;\n\t},\n\n\teq: function( i ) {\n\t\ti = +i;\n\t\treturn i === -1 ?\n\t\t\tthis.slice( i ) :\n\t\t\tthis.slice( i, i + 1 );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( core_slice.apply( this, arguments ),\n\t\t\t\"slice\", core_slice.call(arguments).join(\",\") );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: core_push,\n\tsort: [].sort,\n\tsplice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( length === i ) {\n\t\ttarget = this;\n\t\t--i;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\tnoConflict: function( deep ) {\n\t\tif ( window.$ === jQuery ) {\n\t\t\twindow.$ = _$;\n\t\t}\n\n\t\tif ( deep && window.jQuery === jQuery ) {\n\t\t\twindow.jQuery = _jQuery;\n\t\t}\n\n\t\treturn jQuery;\n\t},\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready, 1 );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.trigger ) {\n\t\t\tjQuery( document ).trigger(\"ready\").off(\"ready\");\n\t\t}\n\t},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\treturn !isNaN( parseFloat(obj) ) && isFinite( obj );\n\t},\n\n\ttype: function( obj ) {\n\t\treturn obj == null ?\n\t\t\tString( obj ) :\n\t\t\tclass2type[ core_toString.call(obj) ] || \"object\";\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!core_hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!core_hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\n\t\tvar key;\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || core_hasOwn.call( obj, key );\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\t// data: string of html\n\t// context (optional): If specified, the fragment will be created in this context, defaults to document\n\t// scripts (optional): If true, will include scripts passed in the html string\n\tparseHTML: function( data, context, scripts ) {\n\t\tvar parsed;\n\t\tif ( !data || typeof data !== \"string\" ) {\n\t\t\treturn null;\n\t\t}\n\t\tif ( typeof context === \"boolean\" ) {\n\t\t\tscripts = context;\n\t\t\tcontext = 0;\n\t\t}\n\t\tcontext = context || document;\n\n\t\t// Single tag\n\t\tif ( (parsed = rsingleTag.exec( data )) ) {\n\t\t\treturn [ context.createElement( parsed[1] ) ];\n\t\t}\n\n\t\tparsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );\n\t\treturn jQuery.merge( [],\n\t\t\t(parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );\n\t},\n\n\tparseJSON: function( data ) {\n\t\tif ( !data || typeof data !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Make sure leading/trailing whitespace is removed (IE can't handle it)\n\t\tdata = jQuery.trim( data );\n\n\t\t// Attempt to parse using the native JSON parser first\n\t\tif ( window.JSON && window.JSON.parse ) {\n\t\t\treturn window.JSON.parse( data );\n\t\t}\n\n\t\t// Make sure the incoming data is actual JSON\n\t\t// Logic borrowed from http://json.org/json2.js\n\t\tif ( rvalidchars.test( data.replace( rvalidescape, \"@\" )\n\t\t\t.replace( rvalidtokens, \"]\" )\n\t\t\t.replace( rvalidbraces, \"\")) ) {\n\n\t\t\treturn ( new Function( \"return \" + data ) )();\n\n\t\t}\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n\t},\n\n\t// Cross-browser xml parsing\n\tparseXML: function( data ) {\n\t\tvar xml, tmp;\n\t\tif ( !data || typeof data !== \"string\" ) {\n\t\t\treturn null;\n\t\t}\n\t\ttry {\n\t\t\tif ( window.DOMParser ) { // Standard\n\t\t\t\ttmp = new DOMParser();\n\t\t\t\txml = tmp.parseFromString( data , \"text/xml\" );\n\t\t\t} else { // IE\n\t\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\t\txml.async = \"false\";\n\t\t\t\txml.loadXML( data );\n\t\t\t}\n\t\t} catch( e ) {\n\t\t\txml = undefined;\n\t\t}\n\t\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\t\tjQuery.error( \"Invalid XML: \" + data );\n\t\t}\n\t\treturn xml;\n\t},\n\n\tnoop: function() {},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && core_rnotwhite.test( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar name,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisObj = length === undefined || jQuery.isFunction( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in obj ) {\n\t\t\t\t\tif ( callback.apply( obj[ name ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( ; i < length; ) {\n\t\t\t\t\tif ( callback.apply( obj[ i++ ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in obj ) {\n\t\t\t\t\tif ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( ; i < length; ) {\n\t\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Use native String.trim function wherever possible\n\ttrim: core_trim && !core_trim.call(\"\\uFEFF\\xA0\") ?\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\tcore_trim.call( text );\n\t\t} :\n\n\t\t// Otherwise use our own trimming functionality\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar type,\n\t\t\tret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\t// The window, strings (and functions) also have 'length'\n\t\t\t// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930\n\t\t\ttype = jQuery.type( arr );\n\n\t\t\tif ( arr.length == null || type === \"string\" || type === \"function\" || type === \"regexp\" || jQuery.isWindow( arr ) ) {\n\t\t\t\tcore_push.call( ret, arr );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( core_indexOf ) {\n\t\t\t\treturn core_indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar l = second.length,\n\t\t\ti = first.length,\n\t\t\tj = 0;\n\n\t\tif ( typeof l === \"number\" ) {\n\t\t\tfor ( ; j < l; j++ ) {\n\t\t\t\tfirst[ i++ ] = second[ j ];\n\t\t\t}\n\n\t\t} else {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, inv ) {\n\t\tvar retVal,\n\t\t\tret = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length;\n\t\tinv = !!inv;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tretVal = !!callback( elems[ i ], i );\n\t\t\tif ( inv !== retVal ) {\n\t\t\t\tret.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value, key,\n\t\t\tret = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\t// jquery objects are treated as arrays\n\t\t\tisArray = elems instanceof jQuery || length !== undefined && typeof length === \"number\" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;\n\n\t\t// Go through the array, translating each of the items to their\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( key in elems ) {\n\t\t\t\tvalue = callback( elems[ key ], key, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn ret.concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = core_slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context, args.concat( core_slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\t// Multifunctional method to get and set values of a collection\n\t// The value/s can optionally be executed if it's a function\n\taccess: function( elems, fn, key, value, chainable, emptyGet, pass ) {\n\t\tvar exec,\n\t\t\tbulk = key == null,\n\t\t\ti = 0,\n\t\t\tlength = elems.length;\n\n\t\t// Sets many values\n\t\tif ( key && typeof key === \"object\" ) {\n\t\t\tfor ( i in key ) {\n\t\t\t\tjQuery.access( elems, fn, i, key[i], 1, emptyGet, value );\n\t\t\t}\n\t\t\tchainable = 1;\n\n\t\t// Sets one value\n\t\t} else if ( value !== undefined ) {\n\t\t\t// Optionally, function values get executed if exec is true\n\t\t\texec = pass === undefined && jQuery.isFunction( value );\n\n\t\t\tif ( bulk ) {\n\t\t\t\t// Bulk operations only iterate when executing function values\n\t\t\t\tif ( exec ) {\n\t\t\t\t\texec = fn;\n\t\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\t\treturn exec.call( jQuery( elem ), value );\n\t\t\t\t\t};\n\n\t\t\t\t// Otherwise they run against the entire set\n\t\t\t\t} else {\n\t\t\t\t\tfn.call( elems, value );\n\t\t\t\t\tfn = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( fn ) {\n\t\t\t\tfor (; i < length; i++ ) {\n\t\t\t\t\tfn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchainable = 1;\n\t\t}\n\n\t\treturn chainable ?\n\t\t\telems :\n\n\t\t\t// Gets\n\t\t\tbulk ?\n\t\t\t\tfn.call( elems ) :\n\t\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n\t},\n\n\tnow: function() {\n\t\treturn ( new Date() ).getTime();\n\t}\n});\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready, 1 );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", jQuery.ready, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", DOMContentLoaded );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", jQuery.ready );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.split( core_rspace ), function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// Flag to know if list is currently firing\n\t\tfiring,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Control if a given callback is in the list\n\t\t\thas: function( fn ) {\n\t\t\t\treturn jQuery.inArray( fn, list ) > -1;\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\targs = args || [];\n\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar action = tuple[ 0 ],\n\t\t\t\t\t\t\t\tfn = fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ]( jQuery.isFunction( fn ) ?\n\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\tvar returned = fn.apply( this, arguments );\n\t\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tnewDefer[ action + \"With\" ]( this === deferred ? newDefer : this, [ returned ] );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} :\n\t\t\t\t\t\t\t\tnewDefer[ action ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ] = list.fire\n\t\t\tdeferred[ tuple[0] ] = list.fire;\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = core_slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;\n\t\t\t\t\tif( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\t\t\t\t\t} else if ( !( --remaining ) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\njQuery.support = (function() {\n\n\tvar support,\n\t\tall,\n\t\ta,\n\t\tselect,\n\t\topt,\n\t\tinput,\n\t\tfragment,\n\t\teventName,\n\t\ti,\n\t\tisSupported,\n\t\tclickFn,\n\t\tdiv = document.createElement(\"div\");\n\n\t// Setup\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n\t// Support tests won't run in some limited or non-browser environments\n\tall = div.getElementsByTagName(\"*\");\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\tif ( !all || !a || !all.length ) {\n\t\treturn {};\n\t}\n\n\t// First batch of tests\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px;float:left;opacity:.5\";\n\tsupport = {\n\t\t// IE strips leading whitespace when .innerHTML is used\n\t\tleadingWhitespace: ( div.firstChild.nodeType === 3 ),\n\n\t\t// Make sure that tbody elements aren't automatically inserted\n\t\t// IE will insert them into empty tables\n\t\ttbody: !div.getElementsByTagName(\"tbody\").length,\n\n\t\t// Make sure that link elements get serialized correctly by innerHTML\n\t\t// This requires a wrapper element in IE\n\t\thtmlSerialize: !!div.getElementsByTagName(\"link\").length,\n\n\t\t// Get the style information from getAttribute\n\t\t// (IE uses .cssText instead)\n\t\tstyle: /top/.test( a.getAttribute(\"style\") ),\n\n\t\t// Make sure that URLs aren't manipulated\n\t\t// (IE normalizes it by default)\n\t\threfNormalized: ( a.getAttribute(\"href\") === \"/a\" ),\n\n\t\t// Make sure that element opacity exists\n\t\t// (IE uses filter instead)\n\t\t// Use a regex to work around a WebKit issue. See #5145\n\t\topacity: /^0.5/.test( a.style.opacity ),\n\n\t\t// Verify style float existence\n\t\t// (IE uses styleFloat instead of cssFloat)\n\t\tcssFloat: !!a.style.cssFloat,\n\n\t\t// Make sure that if no value is specified for a checkbox\n\t\t// that it defaults to \"on\".\n\t\t// (WebKit defaults to \"\" instead)\n\t\tcheckOn: ( input.value === \"on\" ),\n\n\t\t// Make sure that a selected-by-default option has a working selected property.\n\t\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\t\toptSelected: opt.selected,\n\n\t\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\t\tgetSetAttribute: div.className !== \"t\",\n\n\t\t// Tests for enctype support on a form (#6743)\n\t\tenctype: !!document.createElement(\"form\").enctype,\n\n\t\t// Makes sure cloning an html5 element does not cause problems\n\t\t// Where outerHTML is undefined, this still works\n\t\thtml5Clone: document.createElement(\"nav\").cloneNode( true ).outerHTML !== \"<:nav></:nav>\",\n\n\t\t// jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode\n\t\tboxModel: ( document.compatMode === \"CSS1Compat\" ),\n\n\t\t// Will be defined later\n\t\tsubmitBubbles: true,\n\t\tchangeBubbles: true,\n\t\tfocusinBubbles: false,\n\t\tdeleteExpando: true,\n\t\tnoCloneEvent: true,\n\t\tinlineBlockNeedsLayout: false,\n\t\tshrinkWrapBlocks: false,\n\t\treliableMarginRight: true,\n\t\tboxSizingReliable: true,\n\t\tpixelPosition: false\n\t};\n\n\t// Make sure checked status is properly cloned\n\tinput.checked = true;\n\tsupport.noCloneChecked = input.cloneNode( true ).checked;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Test to see if it's possible to delete an expando from an element\n\t// Fails in Internet Explorer\n\ttry {\n\t\tdelete div.test;\n\t} catch( e ) {\n\t\tsupport.deleteExpando = false;\n\t}\n\n\tif ( !div.addEventListener && div.attachEvent && div.fireEvent ) {\n\t\tdiv.attachEvent( \"onclick\", clickFn = function() {\n\t\t\t// Cloning a node shouldn't copy over any\n\t\t\t// bound event handlers (IE does this)\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\t\tdiv.cloneNode( true ).fireEvent(\"onclick\");\n\t\tdiv.detachEvent( \"onclick\", clickFn );\n\t}\n\n\t// Check if a radio maintains its value\n\t// after being appended to the DOM\n\tinput = document.createElement(\"input\");\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n\n\tinput.setAttribute( \"checked\", \"checked\" );\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\tfragment = document.createDocumentFragment();\n\tfragment.appendChild( div.lastChild );\n\n\t// WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tsupport.appendChecked = input.checked;\n\n\tfragment.removeChild( input );\n\tfragment.appendChild( div );\n\n\t// Technique from Juriy Zaytsev\n\t// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/\n\t// We only care about the case where non-standard event systems\n\t// are used, namely in IE. Short-circuiting here helps us to\n\t// avoid an eval call (in setAttribute) which can cause CSP\n\t// to go haywire. See: https://developer.mozilla.org/en/Security/CSP\n\tif ( div.attachEvent ) {\n\t\tfor ( i in {\n\t\t\tsubmit: true,\n\t\t\tchange: true,\n\t\t\tfocusin: true\n\t\t}) {\n\t\t\teventName = \"on\" + i;\n\t\t\tisSupported = ( eventName in div );\n\t\t\tif ( !isSupported ) {\n\t\t\t\tdiv.setAttribute( eventName, \"return;\" );\n\t\t\t\tisSupported = ( typeof div[ eventName ] === \"function\" );\n\t\t\t}\n\t\t\tsupport[ i + \"Bubbles\" ] = isSupported;\n\t\t}\n\t}\n\n\t// Run tests that need a body at doc ready\n\tjQuery(function() {\n\t\tvar container, div, tds, marginDiv,\n\t\t\tdivReset = \"padding:0;margin:0;border:0;display:block;overflow:hidden;\",\n\t\t\tbody = document.getElementsByTagName(\"body\")[0];\n\n\t\tif ( !body ) {\n\t\t\t// Return for frameset docs that don't have a body\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer = document.createElement(\"div\");\n\t\tcontainer.style.cssText = \"visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px\";\n\t\tbody.insertBefore( container, body.firstChild );\n\n\t\t// Construct the test element\n\t\tdiv = document.createElement(\"div\");\n\t\tcontainer.appendChild( div );\n\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\t// (only IE 8 fails this test)\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\ttds = div.getElementsByTagName(\"td\");\n\t\ttds[ 0 ].style.cssText = \"padding:0;margin:0;border:0;display:none\";\n\t\tisSupported = ( tds[ 0 ].offsetHeight === 0 );\n\n\t\ttds[ 0 ].style.display = \"\";\n\t\ttds[ 1 ].style.display = \"none\";\n\n\t\t// Check if empty table cells still have offsetWidth/Height\n\t\t// (IE <= 8 fail this test)\n\t\tsupport.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );\n\n\t\t// Check box-sizing and margin behavior\n\t\tdiv.innerHTML = \"\";\n\t\tdiv.style.cssText = \"box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;\";\n\t\tsupport.boxSizing = ( div.offsetWidth === 4 );\n\t\tsupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );\n\n\t\t// NOTE: To any future maintainer, we've window.getComputedStyle\n\t\t// because jsdom on node.js will break without it.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tsupport.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tsupport.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Check if div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container. For more\n\t\t\t// info see bug #3333\n\t\t\t// Fails in WebKit before Feb 2011 nightlies\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tmarginDiv = document.createElement(\"div\");\n\t\t\tmarginDiv.style.cssText = div.style.cssText = divReset;\n\t\t\tmarginDiv.style.marginRight = marginDiv.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\t\t\tdiv.appendChild( marginDiv );\n\t\t\tsupport.reliableMarginRight =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );\n\t\t}\n\n\t\tif ( typeof div.style.zoom !== \"undefined\" ) {\n\t\t\t// Check if natively block-level elements act like inline-block\n\t\t\t// elements when setting their display to 'inline' and giving\n\t\t\t// them layout\n\t\t\t// (IE < 8 does this)\n\t\t\tdiv.innerHTML = \"\";\n\t\t\tdiv.style.cssText = divReset + \"width:1px;padding:1px;display:inline;zoom:1\";\n\t\t\tsupport.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );\n\n\t\t\t// Check if elements with layout shrink-wrap their children\n\t\t\t// (IE 6 does this)\n\t\t\tdiv.style.display = \"block\";\n\t\t\tdiv.style.overflow = \"visible\";\n\t\t\tdiv.innerHTML = \"<div></div>\";\n\t\t\tdiv.firstChild.style.width = \"5px\";\n\t\t\tsupport.shrinkWrapBlocks = ( div.offsetWidth !== 3 );\n\n\t\t\tcontainer.style.zoom = 1;\n\t\t}\n\n\t\t// Null elements to avoid leaks in IE\n\t\tbody.removeChild( container );\n\t\tcontainer = div = tds = marginDiv = null;\n\t});\n\n\t// Null elements to avoid leaks in IE\n\tfragment.removeChild( div );\n\tall = a = select = opt = input = fragment = div = null;\n\n\treturn support;\n})();\nvar rbrace = /(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\njQuery.extend({\n\tcache: {},\n\n\tdeletedIds: [],\n\n\t// Remove at next major release (1.9/2.0)\n\tuuid: 0,\n\n\t// Unique for each copy of jQuery on the page\n\t// Non-digits removed to match rinlinejQuery\n\texpando: \"jQuery\" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// The following elements throw uncatchable exceptions if you\n\t// attempt to add expando properties to them.\n\tnoData: {\n\t\t\"embed\": true,\n\t\t// Ban all objects except for Flash (which handle expandos)\n\t\t\"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\",\n\t\t\"applet\": true\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar thisCache, ret,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tgetByName = typeof name === \"string\",\n\n\t\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t\t// can't GC object references properly across the DOM-JS boundary\n\t\t\tisNode = elem.nodeType,\n\n\t\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t\t// attached directly to the object so GC can occur automatically\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t\t// Avoid doing any more work than we need to when trying to get data on an\n\t\t// object that has no data at all\n\t\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !id ) {\n\t\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t\t// ends up in the global cache\n\t\t\tif ( isNode ) {\n\t\t\t\telem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;\n\t\t\t} else {\n\t\t\t\tid = internalKey;\n\t\t\t}\n\t\t}\n\n\t\tif ( !cache[ id ] ) {\n\t\t\tcache[ id ] = {};\n\n\t\t\t// Avoids exposing jQuery metadata on plain JS objects when the object\n\t\t\t// is serialized using JSON.stringify\n\t\t\tif ( !isNode ) {\n\t\t\t\tcache[ id ].toJSON = jQuery.noop;\n\t\t\t}\n\t\t}\n\n\t\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t\t// shallow copied over onto the existing cache\n\t\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\t\tif ( pvt ) {\n\t\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t\t} else {\n\t\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t\t}\n\t\t}\n\n\t\tthisCache = cache[ id ];\n\n\t\t// jQuery data() is stored in a separate object inside the object's internal data\n\t\t// cache in order to avoid key collisions between internal data and user-defined\n\t\t// data.\n\t\tif ( !pvt ) {\n\t\t\tif ( !thisCache.data ) {\n\t\t\t\tthisCache.data = {};\n\t\t\t}\n\n\t\t\tthisCache = thisCache.data;\n\t\t}\n\n\t\tif ( data !== undefined ) {\n\t\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t\t}\n\n\t\t// Check for both converted-to-camel and non-converted data property names\n\t\t// If a data property was specified\n\t\tif ( getByName ) {\n\n\t\t\t// First Try to find as-is property data\n\t\t\tret = thisCache[ name ];\n\n\t\t\t// Test for null|undefined property data\n\t\t\tif ( ret == null ) {\n\n\t\t\t\t// Try to find the camelCased property\n\t\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t\t}\n\t\t} else {\n\t\t\tret = thisCache;\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tremoveData: function( elem, name, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar thisCache, i, l,\n\n\t\t\tisNode = elem.nodeType,\n\n\t\t\t// See jQuery.data for more information\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\t\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t\t// If there is already no cache entry for this object, there is no\n\t\t// purpose in continuing\n\t\tif ( !cache[ id ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( name ) {\n\n\t\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\t\tif ( thisCache ) {\n\n\t\t\t\t// Support array or space separated string names for data keys\n\t\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0, l = name.length; i < l; i++ ) {\n\t\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t\t}\n\n\t\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t\t// and let the cache object itself get destroyed\n\t\t\t\tif ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// See jQuery.data for more information\n\t\tif ( !pvt ) {\n\t\t\tdelete cache[ id ].data;\n\n\t\t\t// Don't destroy the parent cache unless the internal data object\n\t\t\t// had been the only thing left in it\n\t\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Destroy the cache\n\t\tif ( isNode ) {\n\t\t\tjQuery.cleanData( [ elem ], true );\n\n\t\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t\t} else if ( jQuery.support.deleteExpando || cache != cache.window ) {\n\t\t\tdelete cache[ id ];\n\n\t\t// When all else fails, null\n\t\t} else {\n\t\t\tcache[ id ] = null;\n\t\t}\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn jQuery.data( elem, name, data, true );\n\t},\n\n\t// A method for determining if a DOM node can handle the data expando\n\tacceptData: function( elem ) {\n\t\tvar noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n\t\t// nodes accept data unless otherwise specified; rejection can be conditional\n\t\treturn !noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar parts, part, attr, name, l,\n\t\t\telem = this[0],\n\t\t\ti = 0,\n\t\t\tdata = null;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\tattr = elem.attributes;\n\t\t\t\t\tfor ( l = attr.length; i < l; i++ ) {\n\t\t\t\t\t\tname = attr[i].name;\n\n\t\t\t\t\t\tif ( !name.indexOf( \"data-\" ) ) {\n\t\t\t\t\t\t\tname = jQuery.camelCase( name.substring(5) );\n\n\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\tparts = key.split( \".\", 2 );\n\t\tparts[1] = parts[1] ? \".\" + parts[1] : \"\";\n\t\tpart = parts[1] + \"!\";\n\n\t\treturn jQuery.access( this, function( value ) {\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\tdata = this.triggerHandler( \"getData\" + part, [ parts[0] ] );\n\n\t\t\t\t// Try to fetch any internally stored data first\n\t\t\t\tif ( data === undefined && elem ) {\n\t\t\t\t\tdata = jQuery.data( elem, key );\n\t\t\t\t\tdata = dataAttr( elem, key, data );\n\t\t\t\t}\n\n\t\t\t\treturn data === undefined && parts[1] ?\n\t\t\t\t\tthis.data( parts[0] ) :\n\t\t\t\t\tdata;\n\t\t\t}\n\n\t\t\tparts[1] = value;\n\t\t\tthis.each(function() {\n\t\t\t\tvar self = jQuery( this );\n\n\t\t\t\tself.triggerHandler( \"setData\" + part, parts );\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t\tself.triggerHandler( \"changeData\" + part, parts );\n\t\t\t});\n\t\t}, null, value, arguments.length > 1, null, false );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\tdata === \"false\" ? false :\n\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery.removeData( elem, type + \"queue\", true );\n\t\t\t\tjQuery.removeData( elem, key, true );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\t// Based off of the plugin by Clint Helfers, with permission.\n\t// http://blindsignals.com/index.php/2009/07/jquery-delay/\n\tdelay: function( time, type ) {\n\t\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\t\ttype = type || \"fx\";\n\n\t\treturn this.queue( type, function( next, hooks ) {\n\t\t\tvar timeout = setTimeout( next, time );\n\t\t\thooks.stop = function() {\n\t\t\t\tclearTimeout( timeout );\n\t\t\t};\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar nodeHook, boolHook, fixSpecified,\n\trclass = /[\\t\\r\\n]/g,\n\trreturn = /\\r/g,\n\trtype = /^(?:button|input)$/i,\n\trfocusable = /^(?:button|input|object|select|textarea)$/i,\n\trclickable = /^a(?:rea|)$/i,\n\trboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,\n\tgetSetAttribute = jQuery.support.getSetAttribute;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t},\n\n\tprop: function( name, value ) {\n\t\treturn jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t},\n\n\taddClass: function( value ) {\n\t\tvar classNames, i, l, elem,\n\t\t\tsetClass, c, cl;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call(this, j, this.className) );\n\t\t\t});\n\t\t}\n\n\t\tif ( value && typeof value === \"string\" ) {\n\t\t\tclassNames = value.split( core_rspace );\n\n\t\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\telem = this[ i ];\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !elem.className && classNames.length === 1 ) {\n\t\t\t\t\t\telem.className = value;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetClass = \" \" + elem.className + \" \";\n\n\t\t\t\t\t\tfor ( c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tif ( setClass.indexOf( \" \" + classNames[ c ] + \" \" ) < 0 ) {\n\t\t\t\t\t\t\t\tsetClass += classNames[ c ] + \" \";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telem.className = jQuery.trim( setClass );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar removes, className, elem, c, cl, i, l;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call(this, j, this.className) );\n\t\t\t});\n\t\t}\n\t\tif ( (value && typeof value === \"string\") || value === undefined ) {\n\t\t\tremoves = ( value || \"\" ).split( core_rspace );\n\n\t\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tif ( elem.nodeType === 1 && elem.className ) {\n\n\t\t\t\t\tclassName = (\" \" + elem.className + \" \").replace( rclass, \" \" );\n\n\t\t\t\t\t// loop over each item in the removal list\n\t\t\t\t\tfor ( c = 0, cl = removes.length; c < cl; c++ ) {\n\t\t\t\t\t\t// Remove until there is nothing to remove,\n\t\t\t\t\t\twhile ( className.indexOf(\" \" + removes[ c ] + \" \") >= 0 ) {\n\t\t\t\t\t\t\tclassName = className.replace( \" \" + removes[ c ] + \" \" , \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telem.className = value ? jQuery.trim( className ) : \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisBool = typeof stateVal === \"boolean\";\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tstate = stateVal,\n\t\t\t\t\tclassNames = value.split( core_rspace );\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tstate = isBool ? state : !self.hasClass( className );\n\t\t\t\t\tself[ state ? \"addClass\" : \"removeClass\" ]( className );\n\t\t\t\t}\n\n\t\t\t} else if ( type === \"undefined\" || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// toggle whole className\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val,\n\t\t\t\tself = jQuery(this);\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, self.val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map(val, function ( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// attributes.value is undefined in Blackberry 4.7 but\n\t\t\t\t// uses .value. See #6932\n\t\t\t\tvar val = elem.attributes.value;\n\t\t\t\treturn !val || val.specified ? elem.value : elem.text;\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// oldIE doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar values = jQuery.makeArray( value );\n\n\t\t\t\tjQuery(elem).find(\"option\").each(function() {\n\t\t\t\t\tthis.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;\n\t\t\t\t});\n\n\t\t\t\tif ( !values.length ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t},\n\n\t// Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9\n\tattrFn: {},\n\n\tattr: function( elem, name, value, pass ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {\n\t\t\treturn jQuery( elem )[ name ]( value );\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( notxml ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\n\t\t\t} else if ( hooks && \"set\" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\n\t\t\tret = elem.getAttribute( name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret === null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar propName, attrNames, name, isBool,\n\t\t\ti = 0;\n\n\t\tif ( value && elem.nodeType === 1 ) {\n\n\t\t\tattrNames = value.split( core_rspace );\n\n\t\t\tfor ( ; i < attrNames.length; i++ ) {\n\t\t\t\tname = attrNames[ i ];\n\n\t\t\t\tif ( name ) {\n\t\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\t\t\t\t\tisBool = rboolean.test( name );\n\n\t\t\t\t\t// See #9699 for explanation of this approach (setting first, then removal)\n\t\t\t\t\t// Do not do this for boolean attributes (see #10870)\n\t\t\t\t\tif ( !isBool ) {\n\t\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t\t}\n\t\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\n\t\t\t\t\t// Set corresponding property to false for boolean attributes\n\t\t\t\t\tif ( isBool && propName in elem ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\t// We can't allow the type property to be changed (since it causes problems in IE)\n\t\t\t\tif ( rtype.test( elem.nodeName ) && elem.parentNode ) {\n\t\t\t\t\tjQuery.error( \"type property can't be changed\" );\n\t\t\t\t} else if ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to it's default in case type is set after value\n\t\t\t\t\t// This is for element creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Use the value property for back compat\n\t\t// Use the nodeHook for button elements in IE6/7 (#1954)\n\t\tvalue: {\n\t\t\tget: function( elem, name ) {\n\t\t\t\tif ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\t\t\treturn nodeHook.get( elem, name );\n\t\t\t\t}\n\t\t\t\treturn name in elem ?\n\t\t\t\t\telem.value :\n\t\t\t\t\tnull;\n\t\t\t},\n\t\t\tset: function( elem, value, name ) {\n\t\t\t\tif ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\t\t\treturn nodeHook.set( elem, value, name );\n\t\t\t\t}\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.value = value;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\ttabindex: \"tabIndex\",\n\t\treadonly: \"readOnly\",\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\",\n\t\tmaxlength: \"maxLength\",\n\t\tcellspacing: \"cellSpacing\",\n\t\tcellpadding: \"cellPadding\",\n\t\trowspan: \"rowSpan\",\n\t\tcolspan: \"colSpan\",\n\t\tusemap: \"useMap\",\n\t\tframeborder: \"frameBorder\",\n\t\tcontenteditable: \"contentEditable\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\treturn ( elem[ name ] = value );\n\t\t\t}\n\n\t\t} else {\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\treturn elem[ name ];\n\t\t\t}\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\tvar attributeNode = elem.getAttributeNode(\"tabindex\");\n\n\t\t\t\treturn attributeNode && attributeNode.specified ?\n\t\t\t\t\tparseInt( attributeNode.value, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\tundefined;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hook for boolean attributes\nboolHook = {\n\tget: function( elem, name ) {\n\t\t// Align boolean attributes with corresponding properties\n\t\t// Fall back to attribute presence where some booleans are not supported\n\t\tvar attrNode,\n\t\t\tproperty = jQuery.prop( elem, name );\n\t\treturn property === true || typeof property !== \"boolean\" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?\n\t\t\tname.toLowerCase() :\n\t\t\tundefined;\n\t},\n\tset: function( elem, value, name ) {\n\t\tvar propName;\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\t// value is true since we know at this point it's type boolean and not false\n\t\t\t// Set boolean attributes to the same name and set the DOM property\n\t\t\tpropName = jQuery.propFix[ name ] || name;\n\t\t\tif ( propName in elem ) {\n\t\t\t\t// Only set the IDL specifically if it already exists on the element\n\t\t\t\telem[ propName ] = true;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, name.toLowerCase() );\n\t\t}\n\t\treturn name;\n\t}\n};\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n\tfixSpecified = {\n\t\tname: true,\n\t\tid: true,\n\t\tcoords: true\n\t};\n\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = jQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret;\n\t\t\tret = elem.getAttributeNode( name );\n\t\t\treturn ret && ( fixSpecified[ name ] ? ret.value !== \"\" : ret.specified ) ?\n\t\t\t\tret.value :\n\t\t\t\tundefined;\n\t\t},\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\tret = document.createAttribute( name );\n\t\t\t\telem.setAttributeNode( ret );\n\t\t\t}\n\t\t\treturn ( ret.value = value + \"\" );\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n\n\t// Set contenteditable to false on removals(#10429)\n\t// Setting to empty string throws an error as an invalid value\n\tjQuery.attrHooks.contenteditable = {\n\t\tget: nodeHook.get,\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( value === \"\" ) {\n\t\t\t\tvalue = \"false\";\n\t\t\t}\n\t\t\tnodeHook.set( elem, value, name );\n\t\t}\n\t};\n}\n\n\n// Some attributes require a special call on IE\nif ( !jQuery.support.hrefNormalized ) {\n\tjQuery.each([ \"href\", \"src\", \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar ret = elem.getAttribute( name, 2 );\n\t\t\t\treturn ret === null ? undefined : ret;\n\t\t\t}\n\t\t});\n\t});\n}\n\nif ( !jQuery.support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Normalize to lowercase since IE uppercases css property names\n\t\t\treturn elem.style.cssText.toLowerCase() || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n// Safari mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !jQuery.support.optSelected ) {\n\tjQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t});\n}\n\n// IE6/7 call enctype encoding\nif ( !jQuery.support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n// Radios and checkboxes getter/setter\nif ( !jQuery.support.checkOn ) {\n\tjQuery.each([ \"radio\", \"checkbox\" ], function() {\n\t\tjQuery.valHooks[ this ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\t// Handle the case where in Webkit \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t\t}\n\t\t};\n\t});\n}\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t});\n});\nvar rformElems = /^(?:textarea|input|select)$/i,\n\trtypenamespace = /^([^\\.]*|)(?:\\.(.+)|)$/,\n\trhoverHack = /(?:^|\\s)hover(\\.\\S+|)\\b/,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\thoverHack = function( events ) {\n\t\treturn jQuery.event.special.hover ? events : events.replace( rhoverHack, \"mouseenter$1 mouseleave$1\" );\n\t};\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar elemData, eventHandle, events,\n\t\t\tt, tns, type, namespaces, handleObj,\n\t\t\thandleObjIn, handlers, special;\n\n\t\t// Don't attach events to noData or text/comment nodes (allow plain objects tho)\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tevents = elemData.events;\n\t\tif ( !events ) {\n\t\t\telemData.events = events = {};\n\t\t}\n\t\teventHandle = elemData.handle;\n\t\tif ( !eventHandle ) {\n\t\t\telemData.handle = eventHandle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\t// jQuery(...).bind(\"mouseover mouseout\", fn);\n\t\ttypes = jQuery.trim( hoverHack(types) ).split( \" \" );\n\t\tfor ( t = 0; t < types.length; t++ ) {\n\n\t\t\ttns = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = tns[1];\n\t\t\tnamespaces = ( tns[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: tns[1],\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\thandlers = events[ type ];\n\t\t\tif ( !handlers ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\tglobal: {},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar t, tns, type, origType, namespaces, origCount,\n\t\t\tj, events, special, eventType, handleObj,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = jQuery.trim( hoverHack( types || \"\" ) ).split(\" \");\n\t\tfor ( t = 0; t < types.length; t++ ) {\n\t\t\ttns = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tns[1];\n\t\t\tnamespaces = tns[2];\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector? special.delegateType : special.bindType ) || type;\n\t\t\teventType = events[ type ] || [];\n\t\t\torigCount = eventType.length;\n\t\t\tnamespaces = namespaces ? new RegExp(\"(^|\\\\.)\" + namespaces.split(\".\").sort().join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n\n\t\t\t// Remove matching events\n\t\t\tfor ( j = 0; j < eventType.length; j++ ) {\n\t\t\t\thandleObj = eventType[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t ( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t ( !namespaces || namespaces.test( handleObj.namespace ) ) &&\n\t\t\t\t\t ( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\teventType.splice( j--, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\teventType.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( eventType.length === 0 && origCount !== eventType.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery.removeData( elem, \"events\", true );\n\t\t}\n\t},\n\n\t// Events that are safe to short-circuit if no handlers are attached.\n\t// Native DOM events should not be added, they may have inline handlers.\n\tcustomEvent: {\n\t\t\"getData\": true,\n\t\t\"setData\": true,\n\t\t\"changeData\": true\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Event object or event type\n\t\tvar cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,\n\t\t\ttype = event.type || event,\n\t\t\tnamespaces = [];\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \"!\" ) >= 0 ) {\n\t\t\t// Exclusive events trigger only for the exact event (no namespaces)\n\t\t\ttype = type.slice(0, -1);\n\t\t\texclusive = true;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\n\t\tif ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {\n\t\t\t// No jQuery handlers for this event type, and it can't have inline handlers\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an Event, Object, or just an event type string\n\t\tevent = typeof event === \"object\" ?\n\t\t\t// jQuery.Event object\n\t\t\tevent[ jQuery.expando ] ? event :\n\t\t\t// Object literal\n\t\t\tnew jQuery.Event( type, event ) :\n\t\t\t// Just the event type (string)\n\t\t\tnew jQuery.Event( type );\n\n\t\tevent.type = type;\n\t\tevent.isTrigger = true;\n\t\tevent.exclusive = exclusive;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.namespace_re = event.namespace? new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n\t\tontype = type.indexOf( \":\" ) < 0 ? \"on\" + type : \"\";\n\n\t\t// Handle a global trigger\n\t\tif ( !elem ) {\n\n\t\t\t// TODO: Stop taunting the data cache; remove global events and always attach to document\n\t\t\tcache = jQuery.cache;\n\t\t\tfor ( i in cache ) {\n\t\t\t\tif ( cache[ i ].events && cache[ i ].events[ type ] ) {\n\t\t\t\t\tjQuery.event.trigger( event, data, cache[ i ].handle.elem, true );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data != null ? jQuery.makeArray( data ) : [];\n\t\tdata.unshift( event );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\teventPath = [[ elem, special.bindType || type ]];\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tcur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;\n\t\t\tfor ( old = elem; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push([ cur, bubbleType ]);\n\t\t\t\told = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( old === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\tfor ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {\n\n\t\t\tcur = eventPath[i][0];\n\t\t\tevent.type = eventPath[i][1];\n\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\t\t\t// Note that this is a bare JS function and not a jQuery handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&\n\t\t\t\t!(type === \"click\" && jQuery.nodeName( elem, \"a\" )) && jQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486)\n\t\t\t\tif ( ontype && elem[ type ] && ((type !== \"focus\" && type !== \"blur\") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\told = elem[ ontype ];\n\n\t\t\t\t\tif ( old ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( old ) {\n\t\t\t\t\t\telem[ ontype ] = old;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event || window.event );\n\n\t\tvar i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,\n\t\t\thandlers = ( (jQuery._data( this, \"events\" ) || {} )[ event.type ] || []),\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\targs = core_slice.call( arguments ),\n\t\t\trun_all = !event.exclusive && !event.namespace,\n\t\t\tspecial = jQuery.event.special[ event.type ] || {},\n\t\t\thandlerQueue = [];\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers that should run if there are delegated events\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && !(event.button && event.type === \"click\") ) {\n\n\t\t\tfor ( cur = event.target; cur != this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.disabled !== true || event.type !== \"click\" ) {\n\t\t\t\t\tselMatch = {};\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\t\t\t\t\t\tsel = handleObj.selector;\n\n\t\t\t\t\t\tif ( selMatch[ sel ] === undefined ) {\n\t\t\t\t\t\t\tselMatch[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( selMatch[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, matches: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( handlers.length > delegateCount ) {\n\t\t\thandlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\tfor ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {\n\t\t\tmatched = handlerQueue[ i ];\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tfor ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {\n\t\t\t\thandleObj = matched.matches[ j ];\n\n\t\t\t\t// Triggered event must either 1) be non-exclusive and have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.data = handleObj.data;\n\t\t\t\t\tevent.handleObj = handleObj;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tevent.result = ret;\n\t\t\t\t\t\tif ( ret === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\t// *** attrChange attrName relatedNode srcElement  are not normalized, non-W3C, deprecated, will be removed in 1.8 ***\n\tprops: \"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar eventDoc, doc, body,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = jQuery.event.fixHooks[ event.type ] || {},\n\t\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = jQuery.Event( originalEvent );\n\n\t\tfor ( i = copy.length; i; ) {\n\t\t\tprop = copy[ --i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Target should not be a text node (#504, Safari)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\n\t\tfocus: {\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tsetup: function( data, namespaces, eventHandle ) {\n\t\t\t\t// We only want to do this special case on windows\n\t\t\t\tif ( jQuery.isWindow( this ) ) {\n\t\t\t\t\tthis.onbeforeunload = eventHandle;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tteardown: function( namespaces, eventHandle ) {\n\t\t\t\tif ( this.onbeforeunload === eventHandle ) {\n\t\t\t\t\tthis.onbeforeunload = null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{ type: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\n// Some plugins are using, but it's undocumented/deprecated and will be removed.\n// The 1.7 special event interface should provide all the hooks needed now.\njQuery.event.handle = jQuery.event.dispatch;\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === \"undefined\" ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||\n\t\t\tsrc.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\nfunction returnFalse() {\n\treturn false;\n}\nfunction returnTrue() {\n\treturn true;\n}\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tpreventDefault: function() {\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// if preventDefault exists run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// otherwise set the returnValue property of the original event to false (IE)\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// if stopPropagation exists run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t\t// otherwise set the cancelBubble property of the original event to true (IE)\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\t\tthis.stopPropagation();\n\t},\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj,\n\t\t\t\tselector = handleObj.selector;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"_submit_attached\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"_submit_attached\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !jQuery.support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"_change_attached\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"_change_attached\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !jQuery.support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler while someone wants focusin/focusout\n\t\tvar attaches = 0,\n\t\t\thandler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tif ( attaches++ === 0 ) {\n\t\t\t\t\tdocument.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tif ( --attaches === 0 ) {\n\t\t\t\t\tdocument.removeEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar origFn, type;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) { // && selector != null\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tlive: function( types, data, fn ) {\n\t\tjQuery( this.context ).on( types, this.selector, data, fn );\n\t\treturn this;\n\t},\n\tdie: function( types, fn ) {\n\t\tjQuery( this.context ).off( types, this.selector || \"**\", fn );\n\t\treturn this;\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tif ( this[0] ) {\n\t\t\treturn jQuery.event.trigger( type, data, this[0], true );\n\t\t}\n\t},\n\n\ttoggle: function( fn ) {\n\t\t// Save reference to arguments for access in closure\n\t\tvar args = arguments,\n\t\t\tguid = fn.guid || jQuery.guid++,\n\t\t\ti = 0,\n\t\t\ttoggler = function( event ) {\n\t\t\t\t// Figure out which function to execute\n\t\t\t\tvar lastToggle = ( jQuery._data( this, \"lastToggle\" + fn.guid ) || 0 ) % i;\n\t\t\t\tjQuery._data( this, \"lastToggle\" + fn.guid, lastToggle + 1 );\n\n\t\t\t\t// Make sure that clicks stop\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\t// and execute the function\n\t\t\t\treturn args[ lastToggle ].apply( this, arguments ) || false;\n\t\t\t};\n\n\t\t// link all the functions, so any of them can unbind this click handler\n\t\ttoggler.guid = guid;\n\t\twhile ( i < args.length ) {\n\t\t\targs[ i++ ].guid = guid;\n\t\t}\n\n\t\treturn this.click( toggler );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n});\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\tif ( fn == null ) {\n\t\t\tfn = data;\n\t\t\tdata = null;\n\t\t}\n\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n\n\tif ( rkeyEvent.test( name ) ) {\n\t\tjQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;\n\t}\n\n\tif ( rmouseEvent.test( name ) ) {\n\t\tjQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;\n\t}\n});\n/*!\r\n * Sizzle CSS Selector Engine\r\n * Copyright 2012 jQuery Foundation and other contributors\r\n * Released under the MIT license\r\n * http://sizzlejs.com/\r\n */\r\n(function( window, undefined ) {\r\n\r\nvar cachedruns,\r\n\tassertGetIdNotName,\r\n\tExpr,\r\n\tgetText,\r\n\tisXML,\r\n\tcontains,\r\n\tcompile,\r\n\tsortOrder,\r\n\thasDuplicate,\r\n\toutermostContext,\r\n\r\n\tbaseHasDuplicate = true,\r\n\tstrundefined = \"undefined\",\r\n\r\n\texpando = ( \"sizcache\" + Math.random() ).replace( \".\", \"\" ),\r\n\r\n\tToken = String,\r\n\tdocument = window.document,\r\n\tdocElem = document.documentElement,\r\n\tdirruns = 0,\r\n\tdone = 0,\r\n\tpop = [].pop,\r\n\tpush = [].push,\r\n\tslice = [].slice,\r\n\t// Use a stripped-down indexOf if a native one is unavailable\r\n\tindexOf = [].indexOf || function( elem ) {\r\n\t\tvar i = 0,\r\n\t\t\tlen = this.length;\r\n\t\tfor ( ; i < len; i++ ) {\r\n\t\t\tif ( this[i] === elem ) {\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn -1;\r\n\t},\r\n\r\n\t// Augment a function for special use by Sizzle\r\n\tmarkFunction = function( fn, value ) {\r\n\t\tfn[ expando ] = value == null || value;\r\n\t\treturn fn;\r\n\t},\r\n\r\n\tcreateCache = function() {\r\n\t\tvar cache = {},\r\n\t\t\tkeys = [];\r\n\r\n\t\treturn markFunction(function( key, value ) {\r\n\t\t\t// Only keep the most recent entries\r\n\t\t\tif ( keys.push( key ) > Expr.cacheLength ) {\r\n\t\t\t\tdelete cache[ keys.shift() ];\r\n\t\t\t}\r\n\r\n\t\t\t// Retrieve with (key + \" \") to avoid collision with native Object.prototype properties (see Issue #157)\r\n\t\t\treturn (cache[ key + \" \" ] = value);\r\n\t\t}, cache );\r\n\t},\r\n\r\n\tclassCache = createCache(),\r\n\ttokenCache = createCache(),\r\n\tcompilerCache = createCache(),\r\n\r\n\t// Regex\r\n\r\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\r\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\r\n\t// http://www.w3.org/TR/css3-syntax/#characters\r\n\tcharacterEncoding = \"(?:\\\\\\\\.|[-\\\\w]|[^\\\\x00-\\\\xa0])+\",\r\n\r\n\t// Loosely modeled on CSS identifier characters\r\n\t// An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)\r\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\r\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\r\n\r\n\t// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors\r\n\toperators = \"([*^$|!~]?=)\",\r\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")\" + whitespace +\r\n\t\t\"*(?:\" + operators + whitespace + \"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\" + identifier + \")|)|)\" + whitespace + \"*\\\\]\",\r\n\r\n\t// Prefer arguments not in parens/brackets,\r\n\t//   then attribute selectors and non-pseudos (denoted by :),\r\n\t//   then anything else\r\n\t// These preferences are here to reduce the number of selectors\r\n\t//   needing tokenize in the PSEUDO preFilter\r\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\2|([^()[\\\\]]*|(?:(?:\" + attributes + \")|[^:]|\\\\\\\\.)*|.*))\\\\)|)\",\r\n\r\n\t// For matchExpr.POS and matchExpr.needsContext\r\n\tpos = \":(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\r\n\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\",\r\n\r\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\r\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\r\n\r\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\r\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([\\\\x20\\\\t\\\\r\\\\n\\\\f>+~])\" + whitespace + \"*\" ),\r\n\trpseudo = new RegExp( pseudos ),\r\n\r\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\r\n\trquickExpr = /^(?:#([\\w\\-]+)|(\\w+)|\\.([\\w\\-]+))$/,\r\n\r\n\trnot = /^:not/,\r\n\trsibling = /[\\x20\\t\\r\\n\\f]*[+~]/,\r\n\trendsWithNot = /:not\\($/,\r\n\r\n\trheader = /h\\d/i,\r\n\trinputs = /input|select|textarea|button/i,\r\n\r\n\trbackslash = /\\\\(?!\\\\)/g,\r\n\r\n\tmatchExpr = {\r\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\r\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\r\n\t\t\"NAME\": new RegExp( \"^\\\\[name=['\\\"]?(\" + characterEncoding + \")['\\\"]?\\\\]\" ),\r\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\r\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\r\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\r\n\t\t\"POS\": new RegExp( pos, \"i\" ),\r\n\t\t\"CHILD\": new RegExp( \"^:(only|nth|first|last)-child(?:\\\\(\" + whitespace +\r\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\r\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\r\n\t\t// For use in libraries implementing .is()\r\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|\" + pos, \"i\" )\r\n\t},\r\n\r\n\t// Support\r\n\r\n\t// Used for testing something on an element\r\n\tassert = function( fn ) {\r\n\t\tvar div = document.createElement(\"div\");\r\n\r\n\t\ttry {\r\n\t\t\treturn fn( div );\r\n\t\t} catch (e) {\r\n\t\t\treturn false;\r\n\t\t} finally {\r\n\t\t\t// release memory in IE\r\n\t\t\tdiv = null;\r\n\t\t}\r\n\t},\r\n\r\n\t// Check if getElementsByTagName(\"*\") returns only elements\r\n\tassertTagNameNoComments = assert(function( div ) {\r\n\t\tdiv.appendChild( document.createComment(\"\") );\r\n\t\treturn !div.getElementsByTagName(\"*\").length;\r\n\t}),\r\n\r\n\t// Check if getAttribute returns normalized href attributes\r\n\tassertHrefNotNormalized = assert(function( div ) {\r\n\t\tdiv.innerHTML = \"<a href='#'></a>\";\r\n\t\treturn div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&\r\n\t\t\tdiv.firstChild.getAttribute(\"href\") === \"#\";\r\n\t}),\r\n\r\n\t// Check if attributes should be retrieved by attribute nodes\r\n\tassertAttributes = assert(function( div ) {\r\n\t\tdiv.innerHTML = \"<select></select>\";\r\n\t\tvar type = typeof div.lastChild.getAttribute(\"multiple\");\r\n\t\t// IE8 returns a string for some attributes even when not present\r\n\t\treturn type !== \"boolean\" && type !== \"string\";\r\n\t}),\r\n\r\n\t// Check if getElementsByClassName can be trusted\r\n\tassertUsableClassName = assert(function( div ) {\r\n\t\t// Opera can't find a second classname (in 9.6)\r\n\t\tdiv.innerHTML = \"<div class='hidden e'></div><div class='hidden'></div>\";\r\n\t\tif ( !div.getElementsByClassName || !div.getElementsByClassName(\"e\").length ) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t// Safari 3.2 caches class attributes and doesn't catch changes\r\n\t\tdiv.lastChild.className = \"e\";\r\n\t\treturn div.getElementsByClassName(\"e\").length === 2;\r\n\t}),\r\n\r\n\t// Check if getElementById returns elements by name\r\n\t// Check if getElementsByName privileges form controls or returns elements by ID\r\n\tassertUsableName = assert(function( div ) {\r\n\t\t// Inject content\r\n\t\tdiv.id = expando + 0;\r\n\t\tdiv.innerHTML = \"<a name='\" + expando + \"'></a><div name='\" + expando + \"'></div>\";\r\n\t\tdocElem.insertBefore( div, docElem.firstChild );\r\n\r\n\t\t// Test\r\n\t\tvar pass = document.getElementsByName &&\r\n\t\t\t// buggy browsers will return fewer than the correct 2\r\n\t\t\tdocument.getElementsByName( expando ).length === 2 +\r\n\t\t\t// buggy browsers will return more than the correct 0\r\n\t\t\tdocument.getElementsByName( expando + 0 ).length;\r\n\t\tassertGetIdNotName = !document.getElementById( expando );\r\n\r\n\t\t// Cleanup\r\n\t\tdocElem.removeChild( div );\r\n\r\n\t\treturn pass;\r\n\t});\r\n\r\n// If slice is not available, provide a backup\r\ntry {\r\n\tslice.call( docElem.childNodes, 0 )[0].nodeType;\r\n} catch ( e ) {\r\n\tslice = function( i ) {\r\n\t\tvar elem,\r\n\t\t\tresults = [];\r\n\t\tfor ( ; (elem = this[i]); i++ ) {\r\n\t\t\tresults.push( elem );\r\n\t\t}\r\n\t\treturn results;\r\n\t};\r\n}\r\n\r\nfunction Sizzle( selector, context, results, seed ) {\r\n\tresults = results || [];\r\n\tcontext = context || document;\r\n\tvar match, elem, xml, m,\r\n\t\tnodeType = context.nodeType;\r\n\r\n\tif ( !selector || typeof selector !== \"string\" ) {\r\n\t\treturn results;\r\n\t}\r\n\r\n\tif ( nodeType !== 1 && nodeType !== 9 ) {\r\n\t\treturn [];\r\n\t}\r\n\r\n\txml = isXML( context );\r\n\r\n\tif ( !xml && !seed ) {\r\n\t\tif ( (match = rquickExpr.exec( selector )) ) {\r\n\t\t\t// Speed-up: Sizzle(\"#ID\")\r\n\t\t\tif ( (m = match[1]) ) {\r\n\t\t\t\tif ( nodeType === 9 ) {\r\n\t\t\t\t\telem = context.getElementById( m );\r\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\r\n\t\t\t\t\t// nodes that are no longer in the document #6963\r\n\t\t\t\t\tif ( elem && elem.parentNode ) {\r\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\r\n\t\t\t\t\t\t// by name instead of ID\r\n\t\t\t\t\t\tif ( elem.id === m ) {\r\n\t\t\t\t\t\t\tresults.push( elem );\r\n\t\t\t\t\t\t\treturn results;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\treturn results;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// Context is not a document\r\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\r\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\r\n\t\t\t\t\t\tresults.push( elem );\r\n\t\t\t\t\t\treturn results;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t// Speed-up: Sizzle(\"TAG\")\r\n\t\t\t} else if ( match[2] ) {\r\n\t\t\t\tpush.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );\r\n\t\t\t\treturn results;\r\n\r\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\r\n\t\t\t} else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {\r\n\t\t\t\tpush.apply( results, slice.call(context.getElementsByClassName( m ), 0) );\r\n\t\t\t\treturn results;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// All others\r\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed, xml );\r\n}\r\n\r\nSizzle.matches = function( expr, elements ) {\r\n\treturn Sizzle( expr, null, null, elements );\r\n};\r\n\r\nSizzle.matchesSelector = function( elem, expr ) {\r\n\treturn Sizzle( expr, null, null, [ elem ] ).length > 0;\r\n};\r\n\r\n// Returns a function to use in pseudos for input types\r\nfunction createInputPseudo( type ) {\r\n\treturn function( elem ) {\r\n\t\tvar name = elem.nodeName.toLowerCase();\r\n\t\treturn name === \"input\" && elem.type === type;\r\n\t};\r\n}\r\n\r\n// Returns a function to use in pseudos for buttons\r\nfunction createButtonPseudo( type ) {\r\n\treturn function( elem ) {\r\n\t\tvar name = elem.nodeName.toLowerCase();\r\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\r\n\t};\r\n}\r\n\r\n// Returns a function to use in pseudos for positionals\r\nfunction createPositionalPseudo( fn ) {\r\n\treturn markFunction(function( argument ) {\r\n\t\targument = +argument;\r\n\t\treturn markFunction(function( seed, matches ) {\r\n\t\t\tvar j,\r\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\r\n\t\t\t\ti = matchIndexes.length;\r\n\r\n\t\t\t// Match elements found at the specified indexes\r\n\t\t\twhile ( i-- ) {\r\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\r\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t});\r\n}\r\n\r\n/**\r\n * Utility function for retrieving the text value of an array of DOM nodes\r\n * @param {Array|Element} elem\r\n */\r\ngetText = Sizzle.getText = function( elem ) {\r\n\tvar node,\r\n\t\tret = \"\",\r\n\t\ti = 0,\r\n\t\tnodeType = elem.nodeType;\r\n\r\n\tif ( nodeType ) {\r\n\t\tif ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\r\n\t\t\t// Use textContent for elements\r\n\t\t\t// innerText usage removed for consistency of new lines (see #11153)\r\n\t\t\tif ( typeof elem.textContent === \"string\" ) {\r\n\t\t\t\treturn elem.textContent;\r\n\t\t\t} else {\r\n\t\t\t\t// Traverse its children\r\n\t\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\r\n\t\t\t\t\tret += getText( elem );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else if ( nodeType === 3 || nodeType === 4 ) {\r\n\t\t\treturn elem.nodeValue;\r\n\t\t}\r\n\t\t// Do not include comment or processing instruction nodes\r\n\t} else {\r\n\r\n\t\t// If no nodeType, this is expected to be an array\r\n\t\tfor ( ; (node = elem[i]); i++ ) {\r\n\t\t\t// Do not traverse comment nodes\r\n\t\t\tret += getText( node );\r\n\t\t}\r\n\t}\r\n\treturn ret;\r\n};\r\n\r\nisXML = Sizzle.isXML = function( elem ) {\r\n\t// documentElement is verified for cases where it doesn't yet exist\r\n\t// (such as loading iframes in IE - #4833)\r\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\r\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\r\n};\r\n\r\n// Element contains another\r\ncontains = Sizzle.contains = docElem.contains ?\r\n\tfunction( a, b ) {\r\n\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\r\n\t\t\tbup = b && b.parentNode;\r\n\t\treturn a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );\r\n\t} :\r\n\tdocElem.compareDocumentPosition ?\r\n\tfunction( a, b ) {\r\n\t\treturn b && !!( a.compareDocumentPosition( b ) & 16 );\r\n\t} :\r\n\tfunction( a, b ) {\r\n\t\twhile ( (b = b.parentNode) ) {\r\n\t\t\tif ( b === a ) {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn false;\r\n\t};\r\n\r\nSizzle.attr = function( elem, name ) {\r\n\tvar val,\r\n\t\txml = isXML( elem );\r\n\r\n\tif ( !xml ) {\r\n\t\tname = name.toLowerCase();\r\n\t}\r\n\tif ( (val = Expr.attrHandle[ name ]) ) {\r\n\t\treturn val( elem );\r\n\t}\r\n\tif ( xml || assertAttributes ) {\r\n\t\treturn elem.getAttribute( name );\r\n\t}\r\n\tval = elem.getAttributeNode( name );\r\n\treturn val ?\r\n\t\ttypeof elem[ name ] === \"boolean\" ?\r\n\t\t\telem[ name ] ? name : null :\r\n\t\t\tval.specified ? val.value : null :\r\n\t\tnull;\r\n};\r\n\r\nExpr = Sizzle.selectors = {\r\n\r\n\t// Can be adjusted by the user\r\n\tcacheLength: 50,\r\n\r\n\tcreatePseudo: markFunction,\r\n\r\n\tmatch: matchExpr,\r\n\r\n\t// IE6/7 return a modified href\r\n\tattrHandle: assertHrefNotNormalized ?\r\n\t\t{} :\r\n\t\t{\r\n\t\t\t\"href\": function( elem ) {\r\n\t\t\t\treturn elem.getAttribute( \"href\", 2 );\r\n\t\t\t},\r\n\t\t\t\"type\": function( elem ) {\r\n\t\t\t\treturn elem.getAttribute(\"type\");\r\n\t\t\t}\r\n\t\t},\r\n\r\n\tfind: {\r\n\t\t\"ID\": assertGetIdNotName ?\r\n\t\t\tfunction( id, context, xml ) {\r\n\t\t\t\tif ( typeof context.getElementById !== strundefined && !xml ) {\r\n\t\t\t\t\tvar m = context.getElementById( id );\r\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\r\n\t\t\t\t\t// nodes that are no longer in the document #6963\r\n\t\t\t\t\treturn m && m.parentNode ? [m] : [];\r\n\t\t\t\t}\r\n\t\t\t} :\r\n\t\t\tfunction( id, context, xml ) {\r\n\t\t\t\tif ( typeof context.getElementById !== strundefined && !xml ) {\r\n\t\t\t\t\tvar m = context.getElementById( id );\r\n\r\n\t\t\t\t\treturn m ?\r\n\t\t\t\t\t\tm.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode(\"id\").value === id ?\r\n\t\t\t\t\t\t\t[m] :\r\n\t\t\t\t\t\t\tundefined :\r\n\t\t\t\t\t\t[];\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\"TAG\": assertTagNameNoComments ?\r\n\t\t\tfunction( tag, context ) {\r\n\t\t\t\tif ( typeof context.getElementsByTagName !== strundefined ) {\r\n\t\t\t\t\treturn context.getElementsByTagName( tag );\r\n\t\t\t\t}\r\n\t\t\t} :\r\n\t\t\tfunction( tag, context ) {\r\n\t\t\t\tvar results = context.getElementsByTagName( tag );\r\n\r\n\t\t\t\t// Filter out possible comments\r\n\t\t\t\tif ( tag === \"*\" ) {\r\n\t\t\t\t\tvar elem,\r\n\t\t\t\t\t\ttmp = [],\r\n\t\t\t\t\t\ti = 0;\r\n\r\n\t\t\t\t\tfor ( ; (elem = results[i]); i++ ) {\r\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\r\n\t\t\t\t\t\t\ttmp.push( elem );\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn tmp;\r\n\t\t\t\t}\r\n\t\t\t\treturn results;\r\n\t\t\t},\r\n\r\n\t\t\"NAME\": assertUsableName && function( tag, context ) {\r\n\t\t\tif ( typeof context.getElementsByName !== strundefined ) {\r\n\t\t\t\treturn context.getElementsByName( name );\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t\"CLASS\": assertUsableClassName && function( className, context, xml ) {\r\n\t\t\tif ( typeof context.getElementsByClassName !== strundefined && !xml ) {\r\n\t\t\t\treturn context.getElementsByClassName( className );\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\trelative: {\r\n\t\t\">\": { dir: \"parentNode\", first: true },\r\n\t\t\" \": { dir: \"parentNode\" },\r\n\t\t\"+\": { dir: \"previousSibling\", first: true },\r\n\t\t\"~\": { dir: \"previousSibling\" }\r\n\t},\r\n\r\n\tpreFilter: {\r\n\t\t\"ATTR\": function( match ) {\r\n\t\t\tmatch[1] = match[1].replace( rbackslash, \"\" );\r\n\r\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\r\n\t\t\tmatch[3] = ( match[4] || match[5] || \"\" ).replace( rbackslash, \"\" );\r\n\r\n\t\t\tif ( match[2] === \"~=\" ) {\r\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\r\n\t\t\t}\r\n\r\n\t\t\treturn match.slice( 0, 4 );\r\n\t\t},\r\n\r\n\t\t\"CHILD\": function( match ) {\r\n\t\t\t/* matches from matchExpr[\"CHILD\"]\r\n\t\t\t\t1 type (only|nth|...)\r\n\t\t\t\t2 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\r\n\t\t\t\t3 xn-component of xn+y argument ([+-]?\\d*n|)\r\n\t\t\t\t4 sign of xn-component\r\n\t\t\t\t5 x of xn-component\r\n\t\t\t\t6 sign of y-component\r\n\t\t\t\t7 y of y-component\r\n\t\t\t*/\r\n\t\t\tmatch[1] = match[1].toLowerCase();\r\n\r\n\t\t\tif ( match[1] === \"nth\" ) {\r\n\t\t\t\t// nth-child requires argument\r\n\t\t\t\tif ( !match[2] ) {\r\n\t\t\t\t\tSizzle.error( match[0] );\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\r\n\t\t\t\t// remember that false/true cast respectively to 0/1\r\n\t\t\t\tmatch[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === \"even\" || match[2] === \"odd\" ) );\r\n\t\t\t\tmatch[4] = +( ( match[6] + match[7] ) || match[2] === \"odd\" );\r\n\r\n\t\t\t// other types prohibit arguments\r\n\t\t\t} else if ( match[2] ) {\r\n\t\t\t\tSizzle.error( match[0] );\r\n\t\t\t}\r\n\r\n\t\t\treturn match;\r\n\t\t},\r\n\r\n\t\t\"PSEUDO\": function( match ) {\r\n\t\t\tvar unquoted, excess;\r\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t\tif ( match[3] ) {\r\n\t\t\t\tmatch[2] = match[3];\r\n\t\t\t} else if ( (unquoted = match[4]) ) {\r\n\t\t\t\t// Only check arguments that contain a pseudo\r\n\t\t\t\tif ( rpseudo.test(unquoted) &&\r\n\t\t\t\t\t// Get excess from tokenize (recursively)\r\n\t\t\t\t\t(excess = tokenize( unquoted, true )) &&\r\n\t\t\t\t\t// advance to the next closing parenthesis\r\n\t\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\r\n\r\n\t\t\t\t\t// excess is a negative index\r\n\t\t\t\t\tunquoted = unquoted.slice( 0, excess );\r\n\t\t\t\t\tmatch[0] = match[0].slice( 0, excess );\r\n\t\t\t\t}\r\n\t\t\t\tmatch[2] = unquoted;\r\n\t\t\t}\r\n\r\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\r\n\t\t\treturn match.slice( 0, 3 );\r\n\t\t}\r\n\t},\r\n\r\n\tfilter: {\r\n\t\t\"ID\": assertGetIdNotName ?\r\n\t\t\tfunction( id ) {\r\n\t\t\t\tid = id.replace( rbackslash, \"\" );\r\n\t\t\t\treturn function( elem ) {\r\n\t\t\t\t\treturn elem.getAttribute(\"id\") === id;\r\n\t\t\t\t};\r\n\t\t\t} :\r\n\t\t\tfunction( id ) {\r\n\t\t\t\tid = id.replace( rbackslash, \"\" );\r\n\t\t\t\treturn function( elem ) {\r\n\t\t\t\t\tvar node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\r\n\t\t\t\t\treturn node && node.value === id;\r\n\t\t\t\t};\r\n\t\t\t},\r\n\r\n\t\t\"TAG\": function( nodeName ) {\r\n\t\t\tif ( nodeName === \"*\" ) {\r\n\t\t\t\treturn function() { return true; };\r\n\t\t\t}\r\n\t\t\tnodeName = nodeName.replace( rbackslash, \"\" ).toLowerCase();\r\n\r\n\t\t\treturn function( elem ) {\r\n\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\r\n\t\t\t};\r\n\t\t},\r\n\r\n\t\t\"CLASS\": function( className ) {\r\n\t\t\tvar pattern = classCache[ expando ][ className + \" \" ];\r\n\r\n\t\t\treturn pattern ||\r\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\r\n\t\t\t\tclassCache( className, function( elem ) {\r\n\t\t\t\t\treturn pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\")) || \"\" );\r\n\t\t\t\t});\r\n\t\t},\r\n\r\n\t\t\"ATTR\": function( name, operator, check ) {\r\n\t\t\treturn function( elem, context ) {\r\n\t\t\t\tvar result = Sizzle.attr( elem, name );\r\n\r\n\t\t\t\tif ( result == null ) {\r\n\t\t\t\t\treturn operator === \"!=\";\r\n\t\t\t\t}\r\n\t\t\t\tif ( !operator ) {\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tresult += \"\";\r\n\r\n\t\t\t\treturn operator === \"=\" ? result === check :\r\n\t\t\t\t\toperator === \"!=\" ? result !== check :\r\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\r\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\r\n\t\t\t\t\toperator === \"$=\" ? check && result.substr( result.length - check.length ) === check :\r\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\r\n\t\t\t\t\toperator === \"|=\" ? result === check || result.substr( 0, check.length + 1 ) === check + \"-\" :\r\n\t\t\t\t\tfalse;\r\n\t\t\t};\r\n\t\t},\r\n\r\n\t\t\"CHILD\": function( type, argument, first, last ) {\r\n\r\n\t\t\tif ( type === \"nth\" ) {\r\n\t\t\t\treturn function( elem ) {\r\n\t\t\t\t\tvar node, diff,\r\n\t\t\t\t\t\tparent = elem.parentNode;\r\n\r\n\t\t\t\t\tif ( first === 1 && last === 0 ) {\r\n\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( parent ) {\r\n\t\t\t\t\t\tdiff = 0;\r\n\t\t\t\t\t\tfor ( node = parent.firstChild; node; node = node.nextSibling ) {\r\n\t\t\t\t\t\t\tif ( node.nodeType === 1 ) {\r\n\t\t\t\t\t\t\t\tdiff++;\r\n\t\t\t\t\t\t\t\tif ( elem === node ) {\r\n\t\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Incorporate the offset (or cast to NaN), then check against cycle size\r\n\t\t\t\t\tdiff -= last;\r\n\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\treturn function( elem ) {\r\n\t\t\t\tvar node = elem;\r\n\r\n\t\t\t\tswitch ( type ) {\r\n\t\t\t\t\tcase \"only\":\r\n\t\t\t\t\tcase \"first\":\r\n\t\t\t\t\t\twhile ( (node = node.previousSibling) ) {\r\n\t\t\t\t\t\t\tif ( node.nodeType === 1 ) {\r\n\t\t\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif ( type === \"first\" ) {\r\n\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tnode = elem;\r\n\r\n\t\t\t\t\t\t/* falls through */\r\n\t\t\t\t\tcase \"last\":\r\n\t\t\t\t\t\twhile ( (node = node.nextSibling) ) {\r\n\t\t\t\t\t\t\tif ( node.nodeType === 1 ) {\r\n\t\t\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t},\r\n\r\n\t\t\"PSEUDO\": function( pseudo, argument ) {\r\n\t\t\t// pseudo-class names are case-insensitive\r\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\r\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\r\n\t\t\t// Remember that setFilters inherits from pseudos\r\n\t\t\tvar args,\r\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\r\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\r\n\r\n\t\t\t// The user may use createPseudo to indicate that\r\n\t\t\t// arguments are needed to create the filter function\r\n\t\t\t// just as Sizzle does\r\n\t\t\tif ( fn[ expando ] ) {\r\n\t\t\t\treturn fn( argument );\r\n\t\t\t}\r\n\r\n\t\t\t// But maintain support for old signatures\r\n\t\t\tif ( fn.length > 1 ) {\r\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\r\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\r\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\r\n\t\t\t\t\t\tvar idx,\r\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\r\n\t\t\t\t\t\t\ti = matched.length;\r\n\t\t\t\t\t\twhile ( i-- ) {\r\n\t\t\t\t\t\t\tidx = indexOf.call( seed, matched[i] );\r\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}) :\r\n\t\t\t\t\tfunction( elem ) {\r\n\t\t\t\t\t\treturn fn( elem, 0, args );\r\n\t\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\treturn fn;\r\n\t\t}\r\n\t},\r\n\r\n\tpseudos: {\r\n\t\t\"not\": markFunction(function( selector ) {\r\n\t\t\t// Trim the selector passed to compile\r\n\t\t\t// to avoid treating leading and trailing\r\n\t\t\t// spaces as combinators\r\n\t\t\tvar input = [],\r\n\t\t\t\tresults = [],\r\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\r\n\r\n\t\t\treturn matcher[ expando ] ?\r\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\r\n\t\t\t\t\tvar elem,\r\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\r\n\t\t\t\t\t\ti = seed.length;\r\n\r\n\t\t\t\t\t// Match elements unmatched by `matcher`\r\n\t\t\t\t\twhile ( i-- ) {\r\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\r\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}) :\r\n\t\t\t\tfunction( elem, context, xml ) {\r\n\t\t\t\t\tinput[0] = elem;\r\n\t\t\t\t\tmatcher( input, null, xml, results );\r\n\t\t\t\t\treturn !results.pop();\r\n\t\t\t\t};\r\n\t\t}),\r\n\r\n\t\t\"has\": markFunction(function( selector ) {\r\n\t\t\treturn function( elem ) {\r\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\r\n\t\t\t};\r\n\t\t}),\r\n\r\n\t\t\"contains\": markFunction(function( text ) {\r\n\t\t\treturn function( elem ) {\r\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\r\n\t\t\t};\r\n\t\t}),\r\n\r\n\t\t\"enabled\": function( elem ) {\r\n\t\t\treturn elem.disabled === false;\r\n\t\t},\r\n\r\n\t\t\"disabled\": function( elem ) {\r\n\t\t\treturn elem.disabled === true;\r\n\t\t},\r\n\r\n\t\t\"checked\": function( elem ) {\r\n\t\t\t// In CSS3, :checked should return both checked and selected elements\r\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\r\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\r\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\r\n\t\t},\r\n\r\n\t\t\"selected\": function( elem ) {\r\n\t\t\t// Accessing this property makes selected-by-default\r\n\t\t\t// options in Safari work properly\r\n\t\t\tif ( elem.parentNode ) {\r\n\t\t\t\telem.parentNode.selectedIndex;\r\n\t\t\t}\r\n\r\n\t\t\treturn elem.selected === true;\r\n\t\t},\r\n\r\n\t\t\"parent\": function( elem ) {\r\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\r\n\t\t},\r\n\r\n\t\t\"empty\": function( elem ) {\r\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\r\n\t\t\t// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),\r\n\t\t\t//   not comment, processing instructions, or others\r\n\t\t\t// Thanks to Diego Perini for the nodeName shortcut\r\n\t\t\t//   Greater than \"@\" means alpha characters (specifically not starting with \"#\" or \"?\")\r\n\t\t\tvar nodeType;\r\n\t\t\telem = elem.firstChild;\r\n\t\t\twhile ( elem ) {\r\n\t\t\t\tif ( elem.nodeName > \"@\" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t\telem = elem.nextSibling;\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t},\r\n\r\n\t\t\"header\": function( elem ) {\r\n\t\t\treturn rheader.test( elem.nodeName );\r\n\t\t},\r\n\r\n\t\t\"text\": function( elem ) {\r\n\t\t\tvar type, attr;\r\n\t\t\t// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)\r\n\t\t\t// use getAttribute instead to test this case\r\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\r\n\t\t\t\t(type = elem.type) === \"text\" &&\r\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === type );\r\n\t\t},\r\n\r\n\t\t// Input types\r\n\t\t\"radio\": createInputPseudo(\"radio\"),\r\n\t\t\"checkbox\": createInputPseudo(\"checkbox\"),\r\n\t\t\"file\": createInputPseudo(\"file\"),\r\n\t\t\"password\": createInputPseudo(\"password\"),\r\n\t\t\"image\": createInputPseudo(\"image\"),\r\n\r\n\t\t\"submit\": createButtonPseudo(\"submit\"),\r\n\t\t\"reset\": createButtonPseudo(\"reset\"),\r\n\r\n\t\t\"button\": function( elem ) {\r\n\t\t\tvar name = elem.nodeName.toLowerCase();\r\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\r\n\t\t},\r\n\r\n\t\t\"input\": function( elem ) {\r\n\t\t\treturn rinputs.test( elem.nodeName );\r\n\t\t},\r\n\r\n\t\t\"focus\": function( elem ) {\r\n\t\t\tvar doc = elem.ownerDocument;\r\n\t\t\treturn elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\r\n\t\t},\r\n\r\n\t\t\"active\": function( elem ) {\r\n\t\t\treturn elem === elem.ownerDocument.activeElement;\r\n\t\t},\r\n\r\n\t\t// Positional types\r\n\t\t\"first\": createPositionalPseudo(function() {\r\n\t\t\treturn [ 0 ];\r\n\t\t}),\r\n\r\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\r\n\t\t\treturn [ length - 1 ];\r\n\t\t}),\r\n\r\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\r\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\r\n\t\t}),\r\n\r\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\r\n\t\t\tfor ( var i = 0; i < length; i += 2 ) {\r\n\t\t\t\tmatchIndexes.push( i );\r\n\t\t\t}\r\n\t\t\treturn matchIndexes;\r\n\t\t}),\r\n\r\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\r\n\t\t\tfor ( var i = 1; i < length; i += 2 ) {\r\n\t\t\t\tmatchIndexes.push( i );\r\n\t\t\t}\r\n\t\t\treturn matchIndexes;\r\n\t\t}),\r\n\r\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\r\n\t\t\tfor ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {\r\n\t\t\t\tmatchIndexes.push( i );\r\n\t\t\t}\r\n\t\t\treturn matchIndexes;\r\n\t\t}),\r\n\r\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\r\n\t\t\tfor ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {\r\n\t\t\t\tmatchIndexes.push( i );\r\n\t\t\t}\r\n\t\t\treturn matchIndexes;\r\n\t\t})\r\n\t}\r\n};\r\n\r\nfunction siblingCheck( a, b, ret ) {\r\n\tif ( a === b ) {\r\n\t\treturn ret;\r\n\t}\r\n\r\n\tvar cur = a.nextSibling;\r\n\r\n\twhile ( cur ) {\r\n\t\tif ( cur === b ) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\r\n\t\tcur = cur.nextSibling;\r\n\t}\r\n\r\n\treturn 1;\r\n}\r\n\r\nsortOrder = docElem.compareDocumentPosition ?\r\n\tfunction( a, b ) {\r\n\t\tif ( a === b ) {\r\n\t\t\thasDuplicate = true;\r\n\t\t\treturn 0;\r\n\t\t}\r\n\r\n\t\treturn ( !a.compareDocumentPosition || !b.compareDocumentPosition ?\r\n\t\t\ta.compareDocumentPosition :\r\n\t\t\ta.compareDocumentPosition(b) & 4\r\n\t\t) ? -1 : 1;\r\n\t} :\r\n\tfunction( a, b ) {\r\n\t\t// The nodes are identical, we can exit early\r\n\t\tif ( a === b ) {\r\n\t\t\thasDuplicate = true;\r\n\t\t\treturn 0;\r\n\r\n\t\t// Fallback to using sourceIndex (in IE) if it's available on both nodes\r\n\t\t} else if ( a.sourceIndex && b.sourceIndex ) {\r\n\t\t\treturn a.sourceIndex - b.sourceIndex;\r\n\t\t}\r\n\r\n\t\tvar al, bl,\r\n\t\t\tap = [],\r\n\t\t\tbp = [],\r\n\t\t\taup = a.parentNode,\r\n\t\t\tbup = b.parentNode,\r\n\t\t\tcur = aup;\r\n\r\n\t\t// If the nodes are siblings (or identical) we can do a quick check\r\n\t\tif ( aup === bup ) {\r\n\t\t\treturn siblingCheck( a, b );\r\n\r\n\t\t// If no parents were found then the nodes are disconnected\r\n\t\t} else if ( !aup ) {\r\n\t\t\treturn -1;\r\n\r\n\t\t} else if ( !bup ) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\r\n\t\t// Otherwise they're somewhere else in the tree so we need\r\n\t\t// to build up a full list of the parentNodes for comparison\r\n\t\twhile ( cur ) {\r\n\t\t\tap.unshift( cur );\r\n\t\t\tcur = cur.parentNode;\r\n\t\t}\r\n\r\n\t\tcur = bup;\r\n\r\n\t\twhile ( cur ) {\r\n\t\t\tbp.unshift( cur );\r\n\t\t\tcur = cur.parentNode;\r\n\t\t}\r\n\r\n\t\tal = ap.length;\r\n\t\tbl = bp.length;\r\n\r\n\t\t// Start walking down the tree looking for a discrepancy\r\n\t\tfor ( var i = 0; i < al && i < bl; i++ ) {\r\n\t\t\tif ( ap[i] !== bp[i] ) {\r\n\t\t\t\treturn siblingCheck( ap[i], bp[i] );\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// We ended someplace up the tree so do a sibling check\r\n\t\treturn i === al ?\r\n\t\t\tsiblingCheck( a, bp[i], -1 ) :\r\n\t\t\tsiblingCheck( ap[i], b, 1 );\r\n\t};\r\n\r\n// Always assume the presence of duplicates if sort doesn't\r\n// pass them to our comparison function (as in Google Chrome).\r\n[0, 0].sort( sortOrder );\r\nbaseHasDuplicate = !hasDuplicate;\r\n\r\n// Document sorting and removing duplicates\r\nSizzle.uniqueSort = function( results ) {\r\n\tvar elem,\r\n\t\tduplicates = [],\r\n\t\ti = 1,\r\n\t\tj = 0;\r\n\r\n\thasDuplicate = baseHasDuplicate;\r\n\tresults.sort( sortOrder );\r\n\r\n\tif ( hasDuplicate ) {\r\n\t\tfor ( ; (elem = results[i]); i++ ) {\r\n\t\t\tif ( elem === results[ i - 1 ] ) {\r\n\t\t\t\tj = duplicates.push( i );\r\n\t\t\t}\r\n\t\t}\r\n\t\twhile ( j-- ) {\r\n\t\t\tresults.splice( duplicates[ j ], 1 );\r\n\t\t}\r\n\t}\r\n\r\n\treturn results;\r\n};\r\n\r\nSizzle.error = function( msg ) {\r\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\r\n};\r\n\r\nfunction tokenize( selector, parseOnly ) {\r\n\tvar matched, match, tokens, type,\r\n\t\tsoFar, groups, preFilters,\r\n\t\tcached = tokenCache[ expando ][ selector + \" \" ];\r\n\r\n\tif ( cached ) {\r\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\r\n\t}\r\n\r\n\tsoFar = selector;\r\n\tgroups = [];\r\n\tpreFilters = Expr.preFilter;\r\n\r\n\twhile ( soFar ) {\r\n\r\n\t\t// Comma and first run\r\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\r\n\t\t\tif ( match ) {\r\n\t\t\t\t// Don't consume trailing commas as valid\r\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\r\n\t\t\t}\r\n\t\t\tgroups.push( tokens = [] );\r\n\t\t}\r\n\r\n\t\tmatched = false;\r\n\r\n\t\t// Combinators\r\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\r\n\t\t\ttokens.push( matched = new Token( match.shift() ) );\r\n\t\t\tsoFar = soFar.slice( matched.length );\r\n\r\n\t\t\t// Cast descendant combinators to space\r\n\t\t\tmatched.type = match[0].replace( rtrim, \" \" );\r\n\t\t}\r\n\r\n\t\t// Filters\r\n\t\tfor ( type in Expr.filter ) {\r\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\r\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\r\n\r\n\t\t\t\ttokens.push( matched = new Token( match.shift() ) );\r\n\t\t\t\tsoFar = soFar.slice( matched.length );\r\n\t\t\t\tmatched.type = type;\r\n\t\t\t\tmatched.matches = match;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif ( !matched ) {\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\t// Return the length of the invalid excess\r\n\t// if we're just parsing\r\n\t// Otherwise, throw an error or return tokens\r\n\treturn parseOnly ?\r\n\t\tsoFar.length :\r\n\t\tsoFar ?\r\n\t\t\tSizzle.error( selector ) :\r\n\t\t\t// Cache the tokens\r\n\t\t\ttokenCache( selector, groups ).slice( 0 );\r\n}\r\n\r\nfunction addCombinator( matcher, combinator, base ) {\r\n\tvar dir = combinator.dir,\r\n\t\tcheckNonElements = base && combinator.dir === \"parentNode\",\r\n\t\tdoneName = done++;\r\n\r\n\treturn combinator.first ?\r\n\t\t// Check against closest ancestor/preceding element\r\n\t\tfunction( elem, context, xml ) {\r\n\t\t\twhile ( (elem = elem[ dir ]) ) {\r\n\t\t\t\tif ( checkNonElements || elem.nodeType === 1  ) {\r\n\t\t\t\t\treturn matcher( elem, context, xml );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} :\r\n\r\n\t\t// Check against all ancestor/preceding elements\r\n\t\tfunction( elem, context, xml ) {\r\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\r\n\t\t\tif ( !xml ) {\r\n\t\t\t\tvar cache,\r\n\t\t\t\t\tdirkey = dirruns + \" \" + doneName + \" \",\r\n\t\t\t\t\tcachedkey = dirkey + cachedruns;\r\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\r\n\t\t\t\t\tif ( checkNonElements || elem.nodeType === 1 ) {\r\n\t\t\t\t\t\tif ( (cache = elem[ expando ]) === cachedkey ) {\r\n\t\t\t\t\t\t\treturn elem.sizset;\r\n\t\t\t\t\t\t} else if ( typeof cache === \"string\" && cache.indexOf(dirkey) === 0 ) {\r\n\t\t\t\t\t\t\tif ( elem.sizset ) {\r\n\t\t\t\t\t\t\t\treturn elem;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\telem[ expando ] = cachedkey;\r\n\t\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\r\n\t\t\t\t\t\t\t\telem.sizset = true;\r\n\t\t\t\t\t\t\t\treturn elem;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\telem.sizset = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\r\n\t\t\t\t\tif ( checkNonElements || elem.nodeType === 1 ) {\r\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\r\n\t\t\t\t\t\t\treturn elem;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n}\r\n\r\nfunction elementMatcher( matchers ) {\r\n\treturn matchers.length > 1 ?\r\n\t\tfunction( elem, context, xml ) {\r\n\t\t\tvar i = matchers.length;\r\n\t\t\twhile ( i-- ) {\r\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t} :\r\n\t\tmatchers[0];\r\n}\r\n\r\nfunction condense( unmatched, map, filter, context, xml ) {\r\n\tvar elem,\r\n\t\tnewUnmatched = [],\r\n\t\ti = 0,\r\n\t\tlen = unmatched.length,\r\n\t\tmapped = map != null;\r\n\r\n\tfor ( ; i < len; i++ ) {\r\n\t\tif ( (elem = unmatched[i]) ) {\r\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\r\n\t\t\t\tnewUnmatched.push( elem );\r\n\t\t\t\tif ( mapped ) {\r\n\t\t\t\t\tmap.push( i );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn newUnmatched;\r\n}\r\n\r\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\r\n\tif ( postFilter && !postFilter[ expando ] ) {\r\n\t\tpostFilter = setMatcher( postFilter );\r\n\t}\r\n\tif ( postFinder && !postFinder[ expando ] ) {\r\n\t\tpostFinder = setMatcher( postFinder, postSelector );\r\n\t}\r\n\treturn markFunction(function( seed, results, context, xml ) {\r\n\t\tvar temp, i, elem,\r\n\t\t\tpreMap = [],\r\n\t\t\tpostMap = [],\r\n\t\t\tpreexisting = results.length,\r\n\r\n\t\t\t// Get initial elements from seed or context\r\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\r\n\r\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\r\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\r\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\r\n\t\t\t\telems,\r\n\r\n\t\t\tmatcherOut = matcher ?\r\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\r\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\r\n\r\n\t\t\t\t\t// ...intermediate processing is necessary\r\n\t\t\t\t\t[] :\r\n\r\n\t\t\t\t\t// ...otherwise use results directly\r\n\t\t\t\t\tresults :\r\n\t\t\t\tmatcherIn;\r\n\r\n\t\t// Find primary matches\r\n\t\tif ( matcher ) {\r\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\r\n\t\t}\r\n\r\n\t\t// Apply postFilter\r\n\t\tif ( postFilter ) {\r\n\t\t\ttemp = condense( matcherOut, postMap );\r\n\t\t\tpostFilter( temp, [], context, xml );\r\n\r\n\t\t\t// Un-match failing elements by moving them back to matcherIn\r\n\t\t\ti = temp.length;\r\n\t\t\twhile ( i-- ) {\r\n\t\t\t\tif ( (elem = temp[i]) ) {\r\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif ( seed ) {\r\n\t\t\tif ( postFinder || preFilter ) {\r\n\t\t\t\tif ( postFinder ) {\r\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\r\n\t\t\t\t\ttemp = [];\r\n\t\t\t\t\ti = matcherOut.length;\r\n\t\t\t\t\twhile ( i-- ) {\r\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\r\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\r\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\r\n\t\t\t\ti = matcherOut.length;\r\n\t\t\t\twhile ( i-- ) {\r\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\r\n\t\t\t\t\t\t(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\r\n\r\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t// Add elements to results, through postFinder if defined\r\n\t\t} else {\r\n\t\t\tmatcherOut = condense(\r\n\t\t\t\tmatcherOut === results ?\r\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\r\n\t\t\t\t\tmatcherOut\r\n\t\t\t);\r\n\t\t\tif ( postFinder ) {\r\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\r\n\t\t\t} else {\r\n\t\t\t\tpush.apply( results, matcherOut );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n}\r\n\r\nfunction matcherFromTokens( tokens ) {\r\n\tvar checkContext, matcher, j,\r\n\t\tlen = tokens.length,\r\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\r\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\r\n\t\ti = leadingRelative ? 1 : 0,\r\n\r\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\r\n\t\tmatchContext = addCombinator( function( elem ) {\r\n\t\t\treturn elem === checkContext;\r\n\t\t}, implicitRelative, true ),\r\n\t\tmatchAnyContext = addCombinator( function( elem ) {\r\n\t\t\treturn indexOf.call( checkContext, elem ) > -1;\r\n\t\t}, implicitRelative, true ),\r\n\t\tmatchers = [ function( elem, context, xml ) {\r\n\t\t\treturn ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\r\n\t\t\t\t(checkContext = context).nodeType ?\r\n\t\t\t\t\tmatchContext( elem, context, xml ) :\r\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\r\n\t\t} ];\r\n\r\n\tfor ( ; i < len; i++ ) {\r\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\r\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\r\n\t\t} else {\r\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\r\n\r\n\t\t\t// Return special upon seeing a positional matcher\r\n\t\t\tif ( matcher[ expando ] ) {\r\n\t\t\t\t// Find the next relative operator (if any) for proper handling\r\n\t\t\t\tj = ++i;\r\n\t\t\t\tfor ( ; j < len; j++ ) {\r\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn setMatcher(\r\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\r\n\t\t\t\t\ti > 1 && tokens.slice( 0, i - 1 ).join(\"\").replace( rtrim, \"$1\" ),\r\n\t\t\t\t\tmatcher,\r\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\r\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\r\n\t\t\t\t\tj < len && tokens.join(\"\")\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\tmatchers.push( matcher );\r\n\t\t}\r\n\t}\r\n\r\n\treturn elementMatcher( matchers );\r\n}\r\n\r\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\r\n\tvar bySet = setMatchers.length > 0,\r\n\t\tbyElement = elementMatchers.length > 0,\r\n\t\tsuperMatcher = function( seed, context, xml, results, expandContext ) {\r\n\t\t\tvar elem, j, matcher,\r\n\t\t\t\tsetMatched = [],\r\n\t\t\t\tmatchedCount = 0,\r\n\t\t\t\ti = \"0\",\r\n\t\t\t\tunmatched = seed && [],\r\n\t\t\t\toutermost = expandContext != null,\r\n\t\t\t\tcontextBackup = outermostContext,\r\n\t\t\t\t// We must always have either seed elements or context\r\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", expandContext && context.parentNode || context ),\r\n\t\t\t\t// Nested matchers should use non-integer dirruns\r\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);\r\n\r\n\t\t\tif ( outermost ) {\r\n\t\t\t\toutermostContext = context !== document && context;\r\n\t\t\t\tcachedruns = superMatcher.el;\r\n\t\t\t}\r\n\r\n\t\t\t// Add elements passing elementMatchers directly to results\r\n\t\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\r\n\t\t\t\tif ( byElement && elem ) {\r\n\t\t\t\t\tfor ( j = 0; (matcher = elementMatchers[j]); j++ ) {\r\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\r\n\t\t\t\t\t\t\tresults.push( elem );\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif ( outermost ) {\r\n\t\t\t\t\t\tdirruns = dirrunsUnique;\r\n\t\t\t\t\t\tcachedruns = ++superMatcher.el;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Track unmatched elements for set filters\r\n\t\t\t\tif ( bySet ) {\r\n\t\t\t\t\t// They will have gone through all possible matchers\r\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\r\n\t\t\t\t\t\tmatchedCount--;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Lengthen the array for every element, matched or not\r\n\t\t\t\t\tif ( seed ) {\r\n\t\t\t\t\t\tunmatched.push( elem );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Apply set filters to unmatched elements\r\n\t\t\tmatchedCount += i;\r\n\t\t\tif ( bySet && i !== matchedCount ) {\r\n\t\t\t\tfor ( j = 0; (matcher = setMatchers[j]); j++ ) {\r\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif ( seed ) {\r\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\r\n\t\t\t\t\tif ( matchedCount > 0 ) {\r\n\t\t\t\t\t\twhile ( i-- ) {\r\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\r\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\r\n\t\t\t\t\tsetMatched = condense( setMatched );\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Add matches to results\r\n\t\t\t\tpush.apply( results, setMatched );\r\n\r\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\r\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\r\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\r\n\r\n\t\t\t\t\tSizzle.uniqueSort( results );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Override manipulation of globals by nested matchers\r\n\t\t\tif ( outermost ) {\r\n\t\t\t\tdirruns = dirrunsUnique;\r\n\t\t\t\toutermostContext = contextBackup;\r\n\t\t\t}\r\n\r\n\t\t\treturn unmatched;\r\n\t\t};\r\n\r\n\tsuperMatcher.el = 0;\r\n\treturn bySet ?\r\n\t\tmarkFunction( superMatcher ) :\r\n\t\tsuperMatcher;\r\n}\r\n\r\ncompile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\r\n\tvar i,\r\n\t\tsetMatchers = [],\r\n\t\telementMatchers = [],\r\n\t\tcached = compilerCache[ expando ][ selector + \" \" ];\r\n\r\n\tif ( !cached ) {\r\n\t\t// Generate a function of recursive functions that can be used to check each element\r\n\t\tif ( !group ) {\r\n\t\t\tgroup = tokenize( selector );\r\n\t\t}\r\n\t\ti = group.length;\r\n\t\twhile ( i-- ) {\r\n\t\t\tcached = matcherFromTokens( group[i] );\r\n\t\t\tif ( cached[ expando ] ) {\r\n\t\t\t\tsetMatchers.push( cached );\r\n\t\t\t} else {\r\n\t\t\t\telementMatchers.push( cached );\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Cache the compiled function\r\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\r\n\t}\r\n\treturn cached;\r\n};\r\n\r\nfunction multipleContexts( selector, contexts, results ) {\r\n\tvar i = 0,\r\n\t\tlen = contexts.length;\r\n\tfor ( ; i < len; i++ ) {\r\n\t\tSizzle( selector, contexts[i], results );\r\n\t}\r\n\treturn results;\r\n}\r\n\r\nfunction select( selector, context, results, seed, xml ) {\r\n\tvar i, tokens, token, type, find,\r\n\t\tmatch = tokenize( selector ),\r\n\t\tj = match.length;\r\n\r\n\tif ( !seed ) {\r\n\t\t// Try to minimize operations if there is only one group\r\n\t\tif ( match.length === 1 ) {\r\n\r\n\t\t\t// Take a shortcut and set the context if the root selector is an ID\r\n\t\t\ttokens = match[0] = match[0].slice( 0 );\r\n\t\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\r\n\t\t\t\t\tcontext.nodeType === 9 && !xml &&\r\n\t\t\t\t\tExpr.relative[ tokens[1].type ] ) {\r\n\r\n\t\t\t\tcontext = Expr.find[\"ID\"]( token.matches[0].replace( rbackslash, \"\" ), context, xml )[0];\r\n\t\t\t\tif ( !context ) {\r\n\t\t\t\t\treturn results;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tselector = selector.slice( tokens.shift().length );\r\n\t\t\t}\r\n\r\n\t\t\t// Fetch a seed set for right-to-left matching\r\n\t\t\tfor ( i = matchExpr[\"POS\"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {\r\n\t\t\t\ttoken = tokens[i];\r\n\r\n\t\t\t\t// Abort if we hit a combinator\r\n\t\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tif ( (find = Expr.find[ type ]) ) {\r\n\t\t\t\t\t// Search, expanding context for leading sibling combinators\r\n\t\t\t\t\tif ( (seed = find(\r\n\t\t\t\t\t\ttoken.matches[0].replace( rbackslash, \"\" ),\r\n\t\t\t\t\t\trsibling.test( tokens[0].type ) && context.parentNode || context,\r\n\t\t\t\t\t\txml\r\n\t\t\t\t\t)) ) {\r\n\r\n\t\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\r\n\t\t\t\t\t\ttokens.splice( i, 1 );\r\n\t\t\t\t\t\tselector = seed.length && tokens.join(\"\");\r\n\t\t\t\t\t\tif ( !selector ) {\r\n\t\t\t\t\t\t\tpush.apply( results, slice.call( seed, 0 ) );\r\n\t\t\t\t\t\t\treturn results;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Compile and execute a filtering function\r\n\t// Provide `match` to avoid retokenization if we modified the selector above\r\n\tcompile( selector, match )(\r\n\t\tseed,\r\n\t\tcontext,\r\n\t\txml,\r\n\t\tresults,\r\n\t\trsibling.test( selector )\r\n\t);\r\n\treturn results;\r\n}\r\n\r\nif ( document.querySelectorAll ) {\r\n\t(function() {\r\n\t\tvar disconnectedMatch,\r\n\t\t\toldSelect = select,\r\n\t\t\trescape = /'|\\\\/g,\r\n\t\t\trattributeQuotes = /\\=[\\x20\\t\\r\\n\\f]*([^'\"\\]]*)[\\x20\\t\\r\\n\\f]*\\]/g,\r\n\r\n\t\t\t// qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA\r\n\t\t\t// A support test would require too much code (would include document ready)\r\n\t\t\trbuggyQSA = [ \":focus\" ],\r\n\r\n\t\t\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\r\n\t\t\t// A support test would require too much code (would include document ready)\r\n\t\t\t// just skip matchesSelector for :active\r\n\t\t\trbuggyMatches = [ \":active\" ],\r\n\t\t\tmatches = docElem.matchesSelector ||\r\n\t\t\t\tdocElem.mozMatchesSelector ||\r\n\t\t\t\tdocElem.webkitMatchesSelector ||\r\n\t\t\t\tdocElem.oMatchesSelector ||\r\n\t\t\t\tdocElem.msMatchesSelector;\r\n\r\n\t\t// Build QSA regex\r\n\t\t// Regex strategy adopted from Diego Perini\r\n\t\tassert(function( div ) {\r\n\t\t\t// Select is set to empty string on purpose\r\n\t\t\t// This is to test IE's treatment of not explictly\r\n\t\t\t// setting a boolean content attribute,\r\n\t\t\t// since its presence should be enough\r\n\t\t\t// http://bugs.jquery.com/ticket/12359\r\n\t\t\tdiv.innerHTML = \"<select><option selected=''></option></select>\";\r\n\r\n\t\t\t// IE8 - Some boolean attributes are not treated correctly\r\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\r\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:checked|disabled|ismap|multiple|readonly|selected|value)\" );\r\n\t\t\t}\r\n\r\n\t\t\t// Webkit/Opera - :checked should return selected option elements\r\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\r\n\t\t\t// IE8 throws error here (do not put tests after this one)\r\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\r\n\t\t\t\trbuggyQSA.push(\":checked\");\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tassert(function( div ) {\r\n\r\n\t\t\t// Opera 10-12/IE9 - ^= $= *= and empty values\r\n\t\t\t// Should not select anything\r\n\t\t\tdiv.innerHTML = \"<p test=''></p>\";\r\n\t\t\tif ( div.querySelectorAll(\"[test^='']\").length ) {\r\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:\\\"\\\"|'')\" );\r\n\t\t\t}\r\n\r\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\r\n\t\t\t// IE8 throws error here (do not put tests after this one)\r\n\t\t\tdiv.innerHTML = \"<input type='hidden'/>\";\r\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\r\n\t\t\t\trbuggyQSA.push(\":enabled\", \":disabled\");\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// rbuggyQSA always contains :focus, so no need for a length check\r\n\t\trbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join(\"|\") );\r\n\r\n\t\tselect = function( selector, context, results, seed, xml ) {\r\n\t\t\t// Only use querySelectorAll when not filtering,\r\n\t\t\t// when this is not xml,\r\n\t\t\t// and when no QSA bugs apply\r\n\t\t\tif ( !seed && !xml && !rbuggyQSA.test( selector ) ) {\r\n\t\t\t\tvar groups, i,\r\n\t\t\t\t\told = true,\r\n\t\t\t\t\tnid = expando,\r\n\t\t\t\t\tnewContext = context,\r\n\t\t\t\t\tnewSelector = context.nodeType === 9 && selector;\r\n\r\n\t\t\t\t// qSA works strangely on Element-rooted queries\r\n\t\t\t\t// We can work around this by specifying an extra ID on the root\r\n\t\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\r\n\t\t\t\t// IE 8 doesn't work on object elements\r\n\t\t\t\tif ( context.nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\r\n\t\t\t\t\tgroups = tokenize( selector );\r\n\r\n\t\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\r\n\t\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tcontext.setAttribute( \"id\", nid );\r\n\t\t\t\t\t}\r\n\t\t\t\t\tnid = \"[id='\" + nid + \"'] \";\r\n\r\n\t\t\t\t\ti = groups.length;\r\n\t\t\t\t\twhile ( i-- ) {\r\n\t\t\t\t\t\tgroups[i] = nid + groups[i].join(\"\");\r\n\t\t\t\t\t}\r\n\t\t\t\t\tnewContext = rsibling.test( selector ) && context.parentNode || context;\r\n\t\t\t\t\tnewSelector = groups.join(\",\");\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif ( newSelector ) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tpush.apply( results, slice.call( newContext.querySelectorAll(\r\n\t\t\t\t\t\t\tnewSelector\r\n\t\t\t\t\t\t), 0 ) );\r\n\t\t\t\t\t\treturn results;\r\n\t\t\t\t\t} catch(qsaError) {\r\n\t\t\t\t\t} finally {\r\n\t\t\t\t\t\tif ( !old ) {\r\n\t\t\t\t\t\t\tcontext.removeAttribute(\"id\");\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn oldSelect( selector, context, results, seed, xml );\r\n\t\t};\r\n\r\n\t\tif ( matches ) {\r\n\t\t\tassert(function( div ) {\r\n\t\t\t\t// Check to see if it's possible to do matchesSelector\r\n\t\t\t\t// on a disconnected node (IE 9)\r\n\t\t\t\tdisconnectedMatch = matches.call( div, \"div\" );\r\n\r\n\t\t\t\t// This should fail with an exception\r\n\t\t\t\t// Gecko does not error, returns false instead\r\n\t\t\t\ttry {\r\n\t\t\t\t\tmatches.call( div, \"[test!='']:sizzle\" );\r\n\t\t\t\t\trbuggyMatches.push( \"!=\", pseudos );\r\n\t\t\t\t} catch ( e ) {}\r\n\t\t\t});\r\n\r\n\t\t\t// rbuggyMatches always contains :active and :focus, so no need for a length check\r\n\t\t\trbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join(\"|\") );\r\n\r\n\t\t\tSizzle.matchesSelector = function( elem, expr ) {\r\n\t\t\t\t// Make sure that attribute selectors are quoted\r\n\t\t\t\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\r\n\r\n\t\t\t\t// rbuggyMatches always contains :active, so no need for an existence check\r\n\t\t\t\tif ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tvar ret = matches.call( elem, expr );\r\n\r\n\t\t\t\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\r\n\t\t\t\t\t\tif ( ret || disconnectedMatch ||\r\n\t\t\t\t\t\t\t\t// As well, disconnected nodes are said to be in a document\r\n\t\t\t\t\t\t\t\t// fragment in IE 9\r\n\t\t\t\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\r\n\t\t\t\t\t\t\treturn ret;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} catch(e) {}\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn Sizzle( expr, null, null, [ elem ] ).length > 0;\r\n\t\t\t};\r\n\t\t}\r\n\t})();\r\n}\r\n\r\n// Deprecated\r\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\r\n\r\n// Back-compat\r\nfunction setFilters() {}\r\nExpr.filters = setFilters.prototype = Expr.pseudos;\r\nExpr.setFilters = new setFilters();\r\n\r\n// Override sizzle attribute retrieval\nSizzle.attr = jQuery.attr;\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\r\n\r\n})( window );\r\nvar runtil = /Until$/,\n\trparentsprev = /^(?:parents|prev(?:Until|All))/,\n\tisSimple = /^.[^:#\\[\\.,]*$/,\n\trneedsContext = jQuery.expr.match.needsContext,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i, l, length, n, r, ret,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0, l = self.length; i < l; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tret = this.pushStack( \"\", \"find\", selector );\n\n\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\tlength = ret.length;\n\t\t\tjQuery.find( selector, this[i], ret );\n\n\t\t\tif ( i > 0 ) {\n\t\t\t\t// Make sure that the results are unique\n\t\t\t\tfor ( n = length; n < ret.length; n++ ) {\n\t\t\t\t\tfor ( r = 0; r < length; r++ ) {\n\t\t\t\t\t\tif ( ret[r] === ret[n] ) {\n\t\t\t\t\t\t\tret.splice(n--, 1);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, false), \"not\", selector);\n\t},\n\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, true), \"filter\", selector );\n\t},\n\n\tis: function( selector ) {\n\t\treturn !!selector && (\n\t\t\ttypeof selector === \"string\" ?\n\t\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\t\trneedsContext.test( selector ) ?\n\t\t\t\t\tjQuery( selector, this.context ).index( this[0] ) >= 0 :\n\t\t\t\t\tjQuery.filter( selector, this ).length > 0 :\n\t\t\t\tthis.filter( selector ).length > 0 );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tret = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tcur = this[i];\n\n\t\t\twhile ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {\n\t\t\t\tif ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {\n\t\t\t\t\tret.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t}\n\n\t\tret = ret.length > 1 ? jQuery.unique( ret ) : ret;\n\n\t\treturn this.pushStack( ret, \"closest\", selectors );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\tvar set = typeof selector === \"string\" ?\n\t\t\t\tjQuery( selector, context ) :\n\t\t\t\tjQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n\t\t\tall = jQuery.merge( this.get(), set );\n\n\t\treturn this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?\n\t\t\tall :\n\t\t\tjQuery.unique( all ) );\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n// A painfully simple check to see if an element is disconnected\n// from a document (should be improved, where feasible).\nfunction isDisconnected( node ) {\n\treturn !node || !node.parentNode || node.parentNode.nodeType === 11;\n}\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( !runtil.test( name ) ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;\n\n\t\tif ( this.length > 1 && rparentsprev.test( name ) ) {\n\t\t\tret = ret.reverse();\n\t\t}\n\n\t\treturn this.pushStack( ret, name, core_slice.call( arguments ).join(\",\") );\n\t};\n});\n\njQuery.extend({\n\tfilter: function( expr, elems, not ) {\n\t\tif ( not ) {\n\t\t\texpr = \":not(\" + expr + \")\";\n\t\t}\n\n\t\treturn elems.length === 1 ?\n\t\t\tjQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :\n\t\t\tjQuery.find.matches(expr, elems);\n\t},\n\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, keep ) {\n\n\t// Can't pass null or undefined to indexOf in Firefox 4\n\t// Set to 0 to skip string check\n\tqualifier = qualifier || 0;\n\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\tvar retVal = !!qualifier.call( elem, i, elem );\n\t\t\treturn retVal === keep;\n\t\t});\n\n\t} else if ( qualifier.nodeType ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\treturn ( elem === qualifier ) === keep;\n\t\t});\n\n\t} else if ( typeof qualifier === \"string\" ) {\n\t\tvar filtered = jQuery.grep(elements, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t});\n\n\t\tif ( isSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter(qualifier, filtered, !keep);\n\t\t} else {\n\t\t\tqualifier = jQuery.filter( qualifier, filtered );\n\t\t}\n\t}\n\n\treturn jQuery.grep(elements, function( elem, i ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;\n\t});\n}\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\trnocache = /<(?:script|object|embed|option|style)/i,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trcheckableType = /^(?:checkbox|radio)$/,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /\\/(java|ecma)script/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|\\-\\-)|[\\]\\-]{2}>\\s*$/g,\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\t_default: [ 0, \"\", \"\" ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n// unless wrapped in a div with non-breaking characters in front of it.\nif ( !jQuery.support.htmlSerialize ) {\n\twrapMap._default = [ 1, \"X<div>\", \"</div>\" ];\n}\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn jQuery.access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 ) {\n\t\t\t\tthis.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 ) {\n\t\t\t\tthis.insertBefore( elem, this.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\tif ( !isDisconnected( this[0] ) ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t});\n\t\t}\n\n\t\tif ( arguments.length ) {\n\t\t\tvar set = jQuery.clean( arguments );\n\t\t\treturn this.pushStack( jQuery.merge( set, this ), \"before\", this.selector );\n\t\t}\n\t},\n\n\tafter: function() {\n\t\tif ( !isDisconnected( this[0] ) ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t});\n\t\t}\n\n\t\tif ( arguments.length ) {\n\t\t\tvar set = jQuery.clean( arguments );\n\t\t\treturn this.pushStack( jQuery.merge( this, set ), \"after\", this.selector );\n\t\t}\n\t},\n\n\t// keepData is for internal use only--do not document\n\tremove: function( selector, keepData ) {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( !selector || jQuery.filter( selector, [ elem ] ).length ) {\n\t\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t\t\tjQuery.cleanData( [ elem ] );\n\t\t\t\t}\n\n\t\t\t\tif ( elem.parentNode ) {\n\t\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function () {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn jQuery.access( this, function( value ) {\n\t\t\tvar elem = this[0] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [\"\", \"\"] )[1].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( elem.getElementsByTagName( \"*\" ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function( value ) {\n\t\tif ( !isDisconnected( this[0] ) ) {\n\t\t\t// Make sure that the elements are removed from the DOM before they are inserted\n\t\t\t// this can help fix replacing a parent with child elements\n\t\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\t\treturn this.each(function(i) {\n\t\t\t\t\tvar self = jQuery(this), old = self.html();\n\t\t\t\t\tself.replaceWith( value.call( this, i, old ) );\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( typeof value !== \"string\" ) {\n\t\t\t\tvalue = jQuery( value ).detach();\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\tvar next = this.nextSibling,\n\t\t\t\t\tparent = this.parentNode;\n\n\t\t\t\tjQuery( this ).remove();\n\n\t\t\t\tif ( next ) {\n\t\t\t\t\tjQuery(next).before( value );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery(parent).append( value );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn this.length ?\n\t\t\tthis.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), \"replaceWith\", value ) :\n\t\t\tthis;\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, table, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = [].concat.apply( [], args );\n\n\t\tvar results, first, fragment, iNoClone,\n\t\t\ti = 0,\n\t\t\tvalue = args[0],\n\t\t\tscripts = [],\n\t\t\tl = this.length;\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( !jQuery.support.checkClone && l > 1 && typeof value === \"string\" && rchecked.test( value ) ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery(this).domManip( args, table, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( jQuery.isFunction(value) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\targs[0] = value.call( this, i, table ? self.html() : undefined );\n\t\t\t\tself.domManip( args, table, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\tresults = jQuery.buildFragment( args, this, scripts );\n\t\t\tfragment = results.fragment;\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\ttable = table && jQuery.nodeName( first, \"tr\" );\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\t// Fragments from the fragment cache must always be cloned and never used in place.\n\t\t\t\tfor ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {\n\t\t\t\t\tcallback.call(\n\t\t\t\t\t\ttable && jQuery.nodeName( this[i], \"table\" ) ?\n\t\t\t\t\t\t\tfindOrAppend( this[i], \"tbody\" ) :\n\t\t\t\t\t\t\tthis[i],\n\t\t\t\t\t\ti === iNoClone ?\n\t\t\t\t\t\t\tfragment :\n\t\t\t\t\t\t\tjQuery.clone( fragment, true, true )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\tfragment = first = null;\n\n\t\t\tif ( scripts.length ) {\n\t\t\t\tjQuery.each( scripts, function( i, elem ) {\n\t\t\t\t\tif ( elem.src ) {\n\t\t\t\t\t\tif ( jQuery.ajax ) {\n\t\t\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\t\t\turl: elem.src,\n\t\t\t\t\t\t\t\ttype: \"GET\",\n\t\t\t\t\t\t\t\tdataType: \"script\",\n\t\t\t\t\t\t\t\tasync: false,\n\t\t\t\t\t\t\t\tglobal: false,\n\t\t\t\t\t\t\t\t\"throws\": true\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tjQuery.error(\"no ajax\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tjQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( elem.parentNode ) {\n\t\t\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\nfunction findOrAppend( elem, tag ) {\n\treturn elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction cloneFixAttributes( src, dest ) {\n\tvar nodeName;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// clearAttributes removes the attributes, which we don't want,\n\t// but also removes the attachEvent events, which we *do* want\n\tif ( dest.clearAttributes ) {\n\t\tdest.clearAttributes();\n\t}\n\n\t// mergeAttributes, in contrast, only merges back on the\n\t// original attributes, not the events\n\tif ( dest.mergeAttributes ) {\n\t\tdest.mergeAttributes( src );\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\tif ( nodeName === \"object\" ) {\n\t\t// IE6-10 improperly clones children of object elements using classid.\n\t\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\n\t// IE blanks contents when cloning scripts\n\t} else if ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdest.text = src.text;\n\t}\n\n\t// Event data gets referenced instead of copied if the expando\n\t// gets copied too\n\tdest.removeAttribute( jQuery.expando );\n}\n\njQuery.buildFragment = function( args, context, scripts ) {\n\tvar fragment, cacheable, cachehit,\n\t\tfirst = args[ 0 ];\n\n\t// Set context from what may come in as undefined or a jQuery collection or a node\n\t// Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &\n\t// also doubles as fix for #8950 where plain objects caused createDocumentFragment exception\n\tcontext = context || document;\n\tcontext = !context.nodeType && context[0] || context;\n\tcontext = context.ownerDocument || context;\n\n\t// Only cache \"small\" (1/2 KB) HTML strings that are associated with the main document\n\t// Cloning options loses the selected state, so don't cache them\n\t// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment\n\t// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache\n\t// Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501\n\tif ( args.length === 1 && typeof first === \"string\" && first.length < 512 && context === document &&\n\t\tfirst.charAt(0) === \"<\" && !rnocache.test( first ) &&\n\t\t(jQuery.support.checkClone || !rchecked.test( first )) &&\n\t\t(jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {\n\n\t\t// Mark cacheable and look for a hit\n\t\tcacheable = true;\n\t\tfragment = jQuery.fragments[ first ];\n\t\tcachehit = fragment !== undefined;\n\t}\n\n\tif ( !fragment ) {\n\t\tfragment = context.createDocumentFragment();\n\t\tjQuery.clean( args, context, fragment, scripts );\n\n\t\t// Update the cache, but only store false\n\t\t// unless this is a second parsing of the same content\n\t\tif ( cacheable ) {\n\t\t\tjQuery.fragments[ first ] = cachehit && fragment;\n\t\t}\n\t}\n\n\treturn { fragment: fragment, cacheable: cacheable };\n};\n\njQuery.fragments = {};\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tl = insert.length,\n\t\t\tparent = this.length === 1 && this[0].parentNode;\n\n\t\tif ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {\n\t\t\tinsert[ original ]( this[0] );\n\t\t\treturn this;\n\t\t} else {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\telems = ( i > 0 ? this.clone(true) : this ).get();\n\t\t\t\tjQuery( insert[i] )[ original ]( elems );\n\t\t\t\tret = ret.concat( elems );\n\t\t\t}\n\n\t\t\treturn this.pushStack( ret, name, insert.selector );\n\t\t}\n\t};\n});\n\nfunction getAll( elem ) {\n\tif ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n\t\treturn elem.getElementsByTagName( \"*\" );\n\n\t} else if ( typeof elem.querySelectorAll !== \"undefined\" ) {\n\t\treturn elem.querySelectorAll( \"*\" );\n\n\t} else {\n\t\treturn [];\n\t}\n}\n\n// Used in clean, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar srcElements,\n\t\t\tdestElements,\n\t\t\ti,\n\t\t\tclone;\n\n\t\tif ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\t\t\t// IE copies events bound via attachEvent when using cloneNode.\n\t\t\t// Calling detachEvent on the clone will also remove the events\n\t\t\t// from the original. In order to get around this, we use some\n\t\t\t// proprietary methods to clear the events. Thanks to MooTools\n\t\t\t// guys for this hotness.\n\n\t\t\tcloneFixAttributes( elem, clone );\n\n\t\t\t// Using Sizzle here is crazy slow, so we use getElementsByTagName instead\n\t\t\tsrcElements = getAll( elem );\n\t\t\tdestElements = getAll( clone );\n\n\t\t\t// Weird iteration because IE will replace the length property\n\t\t\t// with an element if you are cloning the body and one of the\n\t\t\t// elements on the page has a name or id of \"length\"\n\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tcloneFixAttributes( srcElements[i], destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tcloneCopyEvent( elem, clone );\n\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = getAll( elem );\n\t\t\t\tdestElements = getAll( clone );\n\n\t\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[i], destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsrcElements = destElements = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tclean: function( elems, context, fragment, scripts ) {\n\t\tvar i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,\n\t\t\tsafe = context === document && safeFragment,\n\t\t\tret = [];\n\n\t\t// Ensure that context is a document\n\t\tif ( !context || typeof context.createDocumentFragment === \"undefined\" ) {\n\t\t\tcontext = document;\n\t\t}\n\n\t\t// Use the already-created safe fragment if context permits\n\t\tfor ( i = 0; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( typeof elem === \"number\" ) {\n\t\t\t\telem += \"\";\n\t\t\t}\n\n\t\t\tif ( !elem ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Convert html string into DOM nodes\n\t\t\tif ( typeof elem === \"string\" ) {\n\t\t\t\tif ( !rhtml.test( elem ) ) {\n\t\t\t\t\telem = context.createTextNode( elem );\n\t\t\t\t} else {\n\t\t\t\t\t// Ensure a safe container in which to render the html\n\t\t\t\t\tsafe = safe || createSafeFragment( context );\n\t\t\t\t\tdiv = context.createElement(\"div\");\n\t\t\t\t\tsafe.appendChild( div );\n\n\t\t\t\t\t// Fix \"XHTML\"-style tags in all browsers\n\t\t\t\t\telem = elem.replace(rxhtmlTag, \"<$1></$2>\");\n\n\t\t\t\t\t// Go to html and back, then peel off extra wrappers\n\t\t\t\t\ttag = ( rtagName.exec( elem ) || [\"\", \"\"] )[1].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\t\tdepth = wrap[0];\n\t\t\t\t\tdiv.innerHTML = wrap[1] + elem + wrap[2];\n\n\t\t\t\t\t// Move to the right depth\n\t\t\t\t\twhile ( depth-- ) {\n\t\t\t\t\t\tdiv = div.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !jQuery.support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\thasBody = rtbody.test(elem);\n\t\t\t\t\t\t\ttbody = tag === \"table\" && !hasBody ?\n\t\t\t\t\t\t\t\tdiv.firstChild && div.firstChild.childNodes :\n\n\t\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\t\twrap[1] === \"<table>\" && !hasBody ?\n\t\t\t\t\t\t\t\t\tdiv.childNodes :\n\t\t\t\t\t\t\t\t\t[];\n\n\t\t\t\t\t\tfor ( j = tbody.length - 1; j >= 0 ; --j ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( tbody[ j ], \"tbody\" ) && !tbody[ j ].childNodes.length ) {\n\t\t\t\t\t\t\t\ttbody[ j ].parentNode.removeChild( tbody[ j ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// IE completely kills leading whitespace when innerHTML is used\n\t\t\t\t\tif ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tdiv.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\telem = div.childNodes;\n\n\t\t\t\t\t// Take out of fragment container (we need a fresh div each time)\n\t\t\t\t\tdiv.parentNode.removeChild( div );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( elem.nodeType ) {\n\t\t\t\tret.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( ret, elem );\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from safeFragment\n\t\tif ( div ) {\n\t\t\telem = div = safe = null;\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !jQuery.support.appendChecked ) {\n\t\t\tfor ( i = 0; (elem = ret[i]) != null; i++ ) {\n\t\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t\tfixDefaultChecked( elem );\n\t\t\t\t} else if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\t\tjQuery.grep( elem.getElementsByTagName(\"input\"), fixDefaultChecked );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Append elements to a provided document fragment\n\t\tif ( fragment ) {\n\t\t\t// Special handling of each script element\n\t\t\thandleScript = function( elem ) {\n\t\t\t\t// Check if we consider it executable\n\t\t\t\tif ( !elem.type || rscriptType.test( elem.type ) ) {\n\t\t\t\t\t// Detach the script and store it in the scripts array (if provided) or the fragment\n\t\t\t\t\t// Return truthy to indicate that it has been handled\n\t\t\t\t\treturn scripts ?\n\t\t\t\t\t\tscripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :\n\t\t\t\t\t\tfragment.appendChild( elem );\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tfor ( i = 0; (elem = ret[i]) != null; i++ ) {\n\t\t\t\t// Check if we're done after handling an executable script\n\t\t\t\tif ( !( jQuery.nodeName( elem, \"script\" ) && handleScript( elem ) ) ) {\n\t\t\t\t\t// Append to fragment and handle embedded scripts\n\t\t\t\t\tfragment.appendChild( elem );\n\t\t\t\t\tif ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\t\t\t// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration\n\t\t\t\t\t\tjsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName(\"script\") ), handleScript );\n\n\t\t\t\t\t\t// Splice the scripts into ret after their former ancestor and advance our index beyond them\n\t\t\t\t\t\tret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );\n\t\t\t\t\t\ti += jsTags.length;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar data, id, elem, type,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = jQuery.support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( elem.removeAttribute ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tjQuery.deletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n// Limit scope pollution from any deprecated API\n(function() {\n\nvar matched, browser;\n\n// Use of jQuery.browser is frowned upon.\n// More details: http://api.jquery.com/jQuery.browser\n// jQuery.uaMatch maintained for back-compat\njQuery.uaMatch = function( ua ) {\n\tua = ua.toLowerCase();\n\n\tvar match = /(chrome)[ \\/]([\\w.]+)/.exec( ua ) ||\n\t\t/(webkit)[ \\/]([\\w.]+)/.exec( ua ) ||\n\t\t/(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec( ua ) ||\n\t\t/(msie) ([\\w.]+)/.exec( ua ) ||\n\t\tua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec( ua ) ||\n\t\t[];\n\n\treturn {\n\t\tbrowser: match[ 1 ] || \"\",\n\t\tversion: match[ 2 ] || \"0\"\n\t};\n};\n\nmatched = jQuery.uaMatch( navigator.userAgent );\nbrowser = {};\n\nif ( matched.browser ) {\n\tbrowser[ matched.browser ] = true;\n\tbrowser.version = matched.version;\n}\n\n// Chrome is Webkit, but Webkit is also Safari.\nif ( browser.chrome ) {\n\tbrowser.webkit = true;\n} else if ( browser.webkit ) {\n\tbrowser.safari = true;\n}\n\njQuery.browser = browser;\n\njQuery.sub = function() {\n\tfunction jQuerySub( selector, context ) {\n\t\treturn new jQuerySub.fn.init( selector, context );\n\t}\n\tjQuery.extend( true, jQuerySub, this );\n\tjQuerySub.superclass = this;\n\tjQuerySub.fn = jQuerySub.prototype = this();\n\tjQuerySub.fn.constructor = jQuerySub;\n\tjQuerySub.sub = this.sub;\n\tjQuerySub.fn.init = function init( selector, context ) {\n\t\tif ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {\n\t\t\tcontext = jQuerySub( context );\n\t\t}\n\n\t\treturn jQuery.fn.init.call( this, selector, context, rootjQuerySub );\n\t};\n\tjQuerySub.fn.init.prototype = jQuerySub.fn;\n\tvar rootjQuerySub = jQuerySub(document);\n\treturn jQuerySub;\n};\n\n})();\nvar curCSS, iframe, iframeDoc,\n\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity=([^)]*)/,\n\trposition = /^(top|right|bottom|left)$/,\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trmargin = /^margin/,\n\trnumsplit = new RegExp( \"^(\" + core_pnum + \")(.*)$\", \"i\" ),\n\trnumnonpx = new RegExp( \"^(\" + core_pnum + \")(?!px)[a-z%]+$\", \"i\" ),\n\trrelNum = new RegExp( \"^([-+])=(\" + core_pnum + \")\", \"i\" ),\n\telemdisplay = { BODY: \"block\" },\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: 0,\n\t\tfontWeight: 400\n\t},\n\n\tcssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ],\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ],\n\n\teventsToggle = jQuery.fn.toggle;\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction isHidden( elem, el ) {\n\telem = el || elem;\n\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n}\n\nfunction showHide( elements, show ) {\n\tvar elem, display,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && elem.style.display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", css_defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\tdisplay = curCSS( elem, \"display\" );\n\n\t\t\tif ( !values[ index ] && display !== \"none\" ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn jQuery.access( this, function( elem, name, value ) {\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state, fn2 ) {\n\t\tvar bool = typeof state === \"boolean\";\n\n\t\tif ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {\n\t\t\treturn eventsToggle.apply( this, arguments );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( bool ? state : isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Exclude the following css properties to add px\n\tcssNumber: {\n\t\t\"fillOpacity\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that NaN and null values aren't set. See: #7116\n\t\t\tif ( value == null || type === \"number\" && isNaN( value ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\t\t\t\t// Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n\t\t\t\t// Fixes bug #5509\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, numeric, extra ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( numeric || extra !== undefined ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn numeric || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t},\n\n\t// A method for quickly swapping in/out CSS properties to get correct calculations\n\tswap: function( elem, options, callback ) {\n\t\tvar ret, name,\n\t\t\told = {};\n\n\t\t// Remember the old values, and insert the new ones\n\t\tfor ( name in options ) {\n\t\t\told[ name ] = elem.style[ name ];\n\t\t\telem.style[ name ] = options[ name ];\n\t\t}\n\n\t\tret = callback.call( elem );\n\n\t\t// Revert the old values\n\t\tfor ( name in options ) {\n\t\t\telem.style[ name ] = old[ name ];\n\t\t}\n\n\t\treturn ret;\n\t}\n});\n\n// NOTE: To any future maintainer, we've window.getComputedStyle\n// because jsdom on node.js will break without it.\nif ( window.getComputedStyle ) {\n\tcurCSS = function( elem, name ) {\n\t\tvar ret, width, minWidth, maxWidth,\n\t\t\tcomputed = window.getComputedStyle( elem, null ),\n\t\t\tstyle = elem.style;\n\n\t\tif ( computed ) {\n\n\t\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\n\t\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t\t// Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n\t\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tcurCSS = function( elem, name ) {\n\t\tvar left, rsLeft,\n\t\t\tret = elem.currentStyle && elem.currentStyle[ name ],\n\t\t\tstyle = elem.style;\n\n\t\t// Avoid setting ret to empty string here\n\t\t// so we don't default to auto\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\t// but not position css attributes, as those are proportional to the parent element instead\n\t\t// and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\t\t\trsLeft = elem.runtimeStyle && elem.runtimeStyle.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\treturn ret === \"\" ? \"auto\" : ret;\n\t};\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\t// we use jQuery.css instead of curCSS here\n\t\t\t// because of the reliableMarginRight CSS hook!\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true );\n\t\t}\n\n\t\t// From this point on we use curCSS for maximum performance (relevant in animations)\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar val = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tvalueIsBorderBox = true,\n\t\tisBorderBox = jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox\n\t\t)\n\t) + \"px\";\n}\n\n\n// Try to determine the default display value of an element\nfunction css_defaultDisplay( nodeName ) {\n\tif ( elemdisplay[ nodeName ] ) {\n\t\treturn elemdisplay[ nodeName ];\n\t}\n\n\tvar elem = jQuery( \"<\" + nodeName + \">\" ).appendTo( document.body ),\n\t\tdisplay = elem.css(\"display\");\n\telem.remove();\n\n\t// If the simple way fails,\n\t// get element's real default display by attaching it to a temp iframe\n\tif ( display === \"none\" || display === \"\" ) {\n\t\t// Use the already-created iframe if possible\n\t\tiframe = document.body.appendChild(\n\t\t\tiframe || jQuery.extend( document.createElement(\"iframe\"), {\n\t\t\t\tframeBorder: 0,\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t})\n\t\t);\n\n\t\t// Create a cacheable copy of the iframe document on first call.\n\t\t// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML\n\t\t// document to it; WebKit & Firefox won't allow reusing the iframe document.\n\t\tif ( !iframeDoc || !iframe.createElement ) {\n\t\t\tiframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;\n\t\t\tiframeDoc.write(\"<!doctype html><html><body>\");\n\t\t\tiframeDoc.close();\n\t\t}\n\n\t\telem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );\n\n\t\tdisplay = curCSS( elem, \"display\" );\n\t\tdocument.body.removeChild( iframe );\n\t}\n\n\t// Store the correct default display\n\telemdisplay[ nodeName ] = display;\n\n\treturn display;\n}\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\tif ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, \"display\" ) ) ) {\n\t\t\t\t\treturn jQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\"\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !jQuery.support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\tif ( value >= 1 && jQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\tstyle.removeAttribute ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there there is no filter style applied in a css rule, we are done\n\t\t\t\tif ( currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\n// These hooks cannot be added until DOM ready because the support test\n// for it is not run until after DOM ready\njQuery(function() {\n\tif ( !jQuery.support.reliableMarginRight ) {\n\t\tjQuery.cssHooks.marginRight = {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" }, function() {\n\t\t\t\t\tif ( computed ) {\n\t\t\t\t\t\treturn curCSS( elem, \"marginRight\" );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\t}\n\n\t// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n\t// getComputedStyle returns percent when specified for top/left/bottom/right\n\t// rather than make the css module depend on the offset module, we just check for it here\n\tif ( !jQuery.support.pixelPosition && jQuery.fn.position ) {\n\t\tjQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\t\t\tjQuery.cssHooks[ prop ] = {\n\t\t\t\tget: function( elem, computed ) {\n\t\t\t\t\tif ( computed ) {\n\t\t\t\t\t\tvar ret = curCSS( elem, prop );\n\t\t\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\t\t\treturn rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + \"px\" : ret;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\t}\n\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.hidden = function( elem ) {\n\t\treturn ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, \"display\" )) === \"none\");\n\t};\n\n\tjQuery.expr.filters.visible = function( elem ) {\n\t\treturn !jQuery.expr.filters.hidden( elem );\n\t};\n}\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i,\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ],\n\t\t\t\texpanded = {};\n\n\t\t\tfor ( i = 0; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,\n\trselectTextarea = /^(?:select|textarea)/i;\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function(){\n\t\t\treturn this.elements ? jQuery.makeArray( this.elements ) : this;\n\t\t})\n\t\t.filter(function(){\n\t\t\treturn this.name && !this.disabled &&\n\t\t\t\t( this.checked || rselectTextarea.test( this.nodeName ) ||\n\t\t\t\t\trinput.test( this.type ) );\n\t\t})\n\t\t.map(function( i, elem ){\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val, i ){\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n//Serialize an array of form elements or a set of\n//key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// If array item is non-scalar (array or object), encode its\n\t\t\t\t// numeric index to resolve deserialization ambiguity issues.\n\t\t\t\t// Note that rack (as of 1.0.0) can't currently deserialize\n\t\t\t\t// nested arrays properly, and attempting to do so may cause\n\t\t\t\t// a server error. Possible fixes are to modify rack's\n\t\t\t\t// deserialization algorithm or to provide an option or flag\n\t\t\t\t// to force array serialization to be shallow.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app\\-storage|.+\\-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trquery = /\\?/,\n\trscript = /<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi,\n\trts = /([?&])_=[^&]*/,\n\trurl = /^([\\w\\+\\.\\-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t// Keep a copy of the old load method\n\t_load = jQuery.fn.load,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = [\"*/\"] + [\"*\"];\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType, list, placeBefore,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),\n\t\t\ti = 0,\n\t\t\tlength = dataTypes.length;\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tdataType = dataTypes[ i ];\n\t\t\t\t// We control if we're asked to add before\n\t\t\t\t// any existing element\n\t\t\t\tplaceBefore = /^\\+/.test( dataType );\n\t\t\t\tif ( placeBefore ) {\n\t\t\t\t\tdataType = dataType.substr( 1 ) || \"*\";\n\t\t\t\t}\n\t\t\t\tlist = structure[ dataType ] = structure[ dataType ] || [];\n\t\t\t\t// then we add to the structure accordingly\n\t\t\t\tlist[ placeBefore ? \"unshift\" : \"push\" ]( func );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,\n\t\tdataType /* internal */, inspected /* internal */ ) {\n\n\tdataType = dataType || options.dataTypes[ 0 ];\n\tinspected = inspected || {};\n\n\tinspected[ dataType ] = true;\n\n\tvar selection,\n\t\tlist = structure[ dataType ],\n\t\ti = 0,\n\t\tlength = list ? list.length : 0,\n\t\texecuteOnly = ( structure === prefilters );\n\n\tfor ( ; i < length && ( executeOnly || !selection ); i++ ) {\n\t\tselection = list[ i ]( options, originalOptions, jqXHR );\n\t\t// If we got redirected to another dataType\n\t\t// we try there if executing only and not done already\n\t\tif ( typeof selection === \"string\" ) {\n\t\t\tif ( !executeOnly || inspected[ selection ] ) {\n\t\t\t\tselection = undefined;\n\t\t\t} else {\n\t\t\t\toptions.dataTypes.unshift( selection );\n\t\t\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\t\t\tstructure, options, originalOptions, jqXHR, selection, inspected );\n\t\t\t}\n\t\t}\n\t}\n\t// If we're only executing or nothing was selected\n\t// we try the catchall dataType if not done already\n\tif ( ( executeOnly || !selection ) && !inspected[ \"*\" ] ) {\n\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\tstructure, options, originalOptions, jqXHR, \"*\", inspected );\n\t}\n\t// unnecessary when only executing (prefilters)\n\t// but it'll be ignored by the caller in that case\n\treturn selection;\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n}\n\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\t// Don't do a request if no elements are being requested\n\tif ( !this.length ) {\n\t\treturn this;\n\t}\n\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = url.slice( off, url.length );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// Request the remote document\n\tjQuery.ajax({\n\t\turl: url,\n\n\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\ttype: type,\n\t\tdataType: \"html\",\n\t\tdata: params,\n\t\tcomplete: function( jqXHR, status ) {\n\t\t\tif ( callback ) {\n\t\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t}\n\t\t}\n\t}).done(function( responseText ) {\n\n\t\t// Save response for use in complete callback\n\t\tresponse = arguments;\n\n\t\t// See if a selector was specified\n\t\tself.html( selector ?\n\n\t\t\t// Create a dummy div to hold the results\n\t\t\tjQuery(\"<div>\")\n\n\t\t\t\t// inject the contents of the document in, removing the scripts\n\t\t\t\t// to avoid any 'Permission Denied' errors in IE\n\t\t\t\t.append( responseText.replace( rscript, \"\" ) )\n\n\t\t\t\t// Locate the specified elements\n\t\t\t\t.find( selector ) :\n\n\t\t\t// If not, just inject the full result\n\t\t\tresponseText );\n\n\t});\n\n\treturn this;\n};\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( \"ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend\".split( \" \" ), function( i, o ){\n\tjQuery.fn[ o ] = function( f ){\n\t\treturn this.on( o, f );\n\t};\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\ttype: method,\n\t\t\turl: url,\n\t\t\tdata: data,\n\t\t\tsuccess: callback,\n\t\t\tdataType: type\n\t\t});\n\t};\n});\n\njQuery.extend({\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\tif ( settings ) {\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( target, jQuery.ajaxSettings );\n\t\t} else {\n\t\t\t// Extending ajaxSettings\n\t\t\tsettings = target;\n\t\t\ttarget = jQuery.ajaxSettings;\n\t\t}\n\t\tajaxExtend( target, settings );\n\t\treturn target;\n\t},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\ttype: \"GET\",\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\tprocessData: true,\n\t\tasync: true,\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\thtml: \"text/html\",\n\t\t\ttext: \"text/plain\",\n\t\t\tjson: \"application/json, text/javascript\",\n\t\t\t\"*\": allTypes\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\"\n\t\t},\n\n\t\t// List of data converters\n\t\t// 1) key format is \"source_type destination_type\" (a single space in-between)\n\t\t// 2) the catchall symbol \"*\" can be used for source_type\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": window.String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\tcontext: true,\n\t\t\turl: true\n\t\t}\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // ifModified key\n\t\t\tifModifiedKey,\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\t\t\t// transport\n\t\t\ttransport,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\t\t\t// Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events\n\t\t\t// It's the callbackContext if one was provided in the options\n\t\t\t// and if it's a DOM node or a jQuery collection\n\t\t\tglobalEventContext = callbackContext !== s &&\n\t\t\t\t( callbackContext.nodeType || callbackContext instanceof jQuery ) ?\n\t\t\t\t\t\tjQuery( callbackContext ) : jQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match === undefined ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tstatusText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( statusText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, statusText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Callback for when everything is done\n\t\t// It is defined here because jslint complains if it is declared\n\t\t// at the end of the function (which would be more logical and readable)\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( status >= 200 && status < 300 || status === 304 ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ ifModifiedKey ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ ifModifiedKey ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If not modified\n\t\t\t\tif ( status === 304 ) {\n\n\t\t\t\t\tstatusText = \"notmodified\";\n\t\t\t\t\tisSuccess = true;\n\n\t\t\t\t// If we have data\n\t\t\t\t} else {\n\n\t\t\t\t\tisSuccess = ajaxConvert( s, response );\n\t\t\t\t\tstatusText = isSuccess.state;\n\t\t\t\t\tsuccess = isSuccess.data;\n\t\t\t\t\terror = isSuccess.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( !statusText || status ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajax\" + ( isSuccess ? \"Success\" : \"Error\" ),\n\t\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\t\tjqXHR.complete = completeDeferred.add;\n\n\t\t// Status-dependent callbacks\n\t\tjqXHR.statusCode = function( map ) {\n\t\t\tif ( map ) {\n\t\t\t\tvar tmp;\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tfor ( tmp in map ) {\n\t\t\t\t\t\tstatusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttmp = map[ jqXHR.status ];\n\t\t\t\t\tjqXHR.always( tmp );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t};\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().split( core_rspace );\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? 80 : 443 ) ) !=\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? 80 : 443 ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\tfireGlobals = s.global;\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.data;\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Get ifModifiedKey before adding the anti-cache parameter\n\t\t\tifModifiedKey = s.url;\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\n\t\t\t\tvar ts = jQuery.now(),\n\t\t\t\t\t// try replacing _= if it is there\n\t\t\t\t\tret = s.url.replace( rts, \"$1_=\" + ts );\n\n\t\t\t\t// if nothing was replaced, add timestamp to the end\n\t\t\t\ts.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? \"&\" : \"?\" ) + \"_=\" + ts : \"\" );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tifModifiedKey = ifModifiedKey || s.url;\n\t\t\tif ( jQuery.lastModified[ ifModifiedKey ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ ifModifiedKey ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ ifModifiedKey ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ ifModifiedKey ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t\t// Abort if not done already and return\n\t\t\t\treturn jqXHR.abort();\n\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout( function(){\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch (e) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {}\n\n});\n\n/* Handles responses to an ajax request:\n * - sets all responseXXX fields accordingly\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes,\n\t\tresponseFields = s.responseFields;\n\n\t// Fill responseXXX fields\n\tfor ( type in responseFields ) {\n\t\tif ( type in responses ) {\n\t\t\tjqXHR[ responseFields[type] ] = responses[ type ];\n\t\t}\n\t}\n\n\t// Remove auto dataType and get content-type in the process\n\twhile( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"content-type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n// Chain conversions given the request and the original response\nfunction ajaxConvert( s, response ) {\n\n\tvar conv, conv2, current, tmp,\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice(),\n\t\tprev = dataTypes[ 0 ],\n\t\tconverters = {},\n\t\ti = 0;\n\n\t// Apply the dataFilter if provided\n\tif ( s.dataFilter ) {\n\t\tresponse = s.dataFilter( response, s.dataType );\n\t}\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\t// Convert to each sequential dataType, tolerating list modification\n\tfor ( ; (current = dataTypes[++i]); ) {\n\n\t\t// There's only work to do if current dataType is non-auto\n\t\tif ( current !== \"*\" ) {\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\tif ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split(\" \");\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.splice( i--, 0, current );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[\"throws\"] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update prev for next iteration\n\t\t\tprev = current;\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\nvar oldCallbacks = [],\n\trquestion = /\\?/,\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/,\n\tnonce = jQuery.now();\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tdata = s.data,\n\t\turl = s.url,\n\t\thasCallback = s.jsonp !== false,\n\t\treplaceInUrl = hasCallback && rjsonp.test( url ),\n\t\treplaceInData = hasCallback && !replaceInUrl && typeof data === \"string\" &&\n\t\t\t!( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") &&\n\t\t\trjsonp.test( data );\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( s.dataTypes[ 0 ] === \"jsonp\" || replaceInUrl || replaceInData ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\t\toverwritten = window[ callbackName ];\n\n\t\t// Insert callback into url or form data\n\t\tif ( replaceInUrl ) {\n\t\t\ts.url = url.replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( replaceInData ) {\n\t\t\ts.data = data.replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( hasCallback ) {\n\t\t\ts.url += ( rquestion.test( url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /javascript|ecmascript/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || document.getElementsByTagName( \"head\" )[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement( \"script\" );\n\n\t\t\t\tscript.async = \"async\";\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( head && script.parentNode ) {\n\t\t\t\t\t\t\thead.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = undefined;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\t// Use insertBefore instead of appendChild  to circumvent an IE6 bug.\n\t\t\t\t// This arises when a base node is used (#2709 and #4378).\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( 0, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\nvar xhrCallbacks,\n\t// #5280: Internet Explorer will keep connections alive if we don't abort on unload\n\txhrOnUnloadAbort = window.ActiveXObject ? function() {\n\t\t// Abort all pending requests\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( 0, 1 );\n\t\t}\n\t} : false,\n\txhrId = 0;\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n\t/* Microsoft failed to properly\n\t * implement the XMLHttpRequest in IE7 (can't request local files),\n\t * so we use the ActiveXObject when it is available\n\t * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n\t * we need a fallback.\n\t */\n\tfunction() {\n\t\treturn !this.isLocal && createStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\n// Determine support properties\n(function( xhr ) {\n\tjQuery.extend( jQuery.support, {\n\t\tajax: !!xhr,\n\t\tcors: !!xhr && ( \"withCredentials\" in xhr )\n\t});\n})( jQuery.ajaxSettings.xhr() );\n\n// Create transport if the browser can provide an xhr\nif ( jQuery.support.ajax ) {\n\n\tjQuery.ajaxTransport(function( s ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !s.crossDomain || jQuery.support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\n\t\t\t\t\t// Get a new xhr\n\t\t\t\t\tvar handle, i,\n\t\t\t\t\t\txhr = s.xhr();\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\t// Passing null username, generates a login popup on Opera (#2865)\n\t\t\t\t\tif ( s.username ) {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async, s.username, s.password );\n\t\t\t\t\t} else {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( s.xhrFields ) {\n\t\t\t\t\t\tfor ( i in s.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = s.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( s.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( s.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !s.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Need an extra try/catch for cross domain requests in Firefox 3\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch( _ ) {}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( s.hasContent && s.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\n\t\t\t\t\t\tvar status,\n\t\t\t\t\t\t\tstatusText,\n\t\t\t\t\t\t\tresponseHeaders,\n\t\t\t\t\t\t\tresponses,\n\t\t\t\t\t\t\txml;\n\n\t\t\t\t\t\t// Firefox throws exceptions when accessing properties\n\t\t\t\t\t\t// of an xhr when a network error occurred\n\t\t\t\t\t\t// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n\t\t\t\t\t\ttry {\n\n\t\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n\t\t\t\t\t\t\t\t// Only called once\n\t\t\t\t\t\t\t\tcallback = undefined;\n\n\t\t\t\t\t\t\t\t// Do not keep as active anymore\n\t\t\t\t\t\t\t\tif ( handle ) {\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\t\t\t\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t\t\t\tdelete xhrCallbacks[ handle ];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// If it's an abort\n\t\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\t\t// Abort it manually if needed\n\t\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tstatus = xhr.status;\n\t\t\t\t\t\t\t\t\tresponseHeaders = xhr.getAllResponseHeaders();\n\t\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\t\txml = xhr.responseXML;\n\n\t\t\t\t\t\t\t\t\t// Construct response list\n\t\t\t\t\t\t\t\t\tif ( xml && xml.documentElement /* #4958 */ ) {\n\t\t\t\t\t\t\t\t\t\tresponses.xml = xml;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// When requesting binary data, IE6-9 will throw an exception\n\t\t\t\t\t\t\t\t\t// on any attempt to access responseText (#11426)\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\t\tif ( !status && s.isLocal && !s.crossDomain ) {\n\t\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch( firefoxAccessException ) {\n\t\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\t\tcomplete( -1, firefoxAccessException );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, responseHeaders );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !s.async ) {\n\t\t\t\t\t\t// if we're in sync mode we fire the callback\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t// (IE6 & IE7) if it's in cache and has been\n\t\t\t\t\t\t// retrieved directly we need to fire the callback\n\t\t\t\t\t\tsetTimeout( callback, 0 );\n\t\t\t\t\t} else {\n\t\t\t\t\t\thandle = ++xhrId;\n\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t// Create the active xhrs callbacks list if needed\n\t\t\t\t\t\t\t// and attach the unload handler\n\t\t\t\t\t\t\tif ( !xhrCallbacks ) {\n\t\t\t\t\t\t\t\txhrCallbacks = {};\n\t\t\t\t\t\t\t\tjQuery( window ).unload( xhrOnUnloadAbort );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Add to list of active xhrs callbacks\n\t\t\t\t\t\t\txhrCallbacks[ handle ] = callback;\n\t\t\t\t\t\t}\n\t\t\t\t\t\txhr.onreadystatechange = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback(0,1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\nvar fxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([-+])=|)(\" + core_pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [function( prop, value ) {\n\t\t\tvar end, unit,\n\t\t\t\ttween = this.createTween( prop, value ),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tstart = +target || 0,\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( parts ) {\n\t\t\t\tend = +parts[2];\n\t\t\t\tunit = parts[3] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\n\t\t\t\t// We need to compute starting value\n\t\t\t\tif ( unit !== \"px\" && start ) {\n\t\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\t\t// Prefer the current property, because this process will be trivial if it uses the same units\n\t\t\t\t\t// Fallback to end or a simple constant\n\t\t\t\t\tstart = jQuery.css( tween.elem, prop, true ) || end || 1;\n\n\t\t\t\t\tdo {\n\t\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t\t// Adjust and apply\n\t\t\t\t\t\tstart = start / scale;\n\t\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t\t}\n\n\t\t\t\ttween.unit = unit;\n\t\t\t\ttween.start = start;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;\n\t\t\t}\n\t\t\treturn tween;\n\t\t}]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t}, 0 );\n\treturn ( fxNow = jQuery.now() );\n}\n\nfunction createTweens( animation, props ) {\n\tjQuery.each( props, function( prop, value ) {\n\t\tvar collection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\t\tindex = 0,\n\t\t\tlength = collection.length;\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tif ( collection[ index ].call( animation, prop, value ) ) {\n\n\t\t\t\t// we're done with this property\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tindex = 0,\n\t\ttweenerIndex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end, easing ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tcreateTweens( animation, props );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue,\n\t\t\telem: elem\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,\n\t\tanim = this,\n\t\tstyle = elem.style,\n\t\torig = {},\n\t\thandled = [],\n\t\thidden = elem.nodeType && isHidden( elem );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE does not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tif ( jQuery.css( elem, \"display\" ) === \"inline\" &&\n\t\t\t\tjQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t// inline-level elements accept inline-block;\n\t\t\t// block-level elements need to be inline with layout\n\t\t\tif ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !jQuery.support.shrinkWrapBlocks ) {\n\t\t\tanim.done(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\n\n\t// show/hide pass\n\tfor ( index in props ) {\n\t\tvalue = props[ index ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ index ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\thandled.push( index );\n\t\t}\n\t}\n\n\tlength = handled.length;\n\tif ( length ) {\n\t\tdataShow = jQuery._data( elem, \"fxshow\" ) || jQuery._data( elem, \"fxshow\", {} );\n\t\tif ( \"hidden\" in dataShow ) {\n\t\t\thidden = dataShow.hidden;\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery.removeData( elem, \"fxshow\", true );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( index = 0 ; index < length ; index++ ) {\n\t\t\tprop = handled[ index ];\n\t\t\ttween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );\n\t\t\torig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing any value as a 4th parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, false, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Remove in 2.0 - this supports IE8's panic based approach\n// to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ||\n\t\t\t// special check for .toggle( handler, handler, ... )\n\t\t\t( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations resolve immediately\n\t\t\t\tif ( empty ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t}\n});\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth? 1 : 0;\n\tfor( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p*Math.PI ) / 2;\n\t}\n};\n\njQuery.timers = [];\njQuery.fx = Tween.prototype.init;\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tif ( timer() && jQuery.timers.push( timer ) && !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.animated = function( elem ) {\n\t\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\t\treturn elem === fn.elem;\n\t\t}).length;\n\t};\n}\nvar rroot = /^(?:body|html)$/i;\n\njQuery.fn.offset = function( options ) {\n\tif ( arguments.length ) {\n\t\treturn options === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t}\n\n\tvar docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,\n\t\tbox = { top: 0, left: 0 },\n\t\telem = this[ 0 ],\n\t\tdoc = elem && elem.ownerDocument;\n\n\tif ( !doc ) {\n\t\treturn;\n\t}\n\n\tif ( (body = doc.body) === elem ) {\n\t\treturn jQuery.offset.bodyOffset( elem );\n\t}\n\n\tdocElem = doc.documentElement;\n\n\t// Make sure it's not a disconnected DOM node\n\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\treturn box;\n\t}\n\n\t// If we don't have gBCR, just use 0,0 rather than error\n\t// BlackBerry 5, iOS 3 (original iPhone)\n\tif ( typeof elem.getBoundingClientRect !== \"undefined\" ) {\n\t\tbox = elem.getBoundingClientRect();\n\t}\n\twin = getWindow( doc );\n\tclientTop  = docElem.clientTop  || body.clientTop  || 0;\n\tclientLeft = docElem.clientLeft || body.clientLeft || 0;\n\tscrollTop  = win.pageYOffset || docElem.scrollTop;\n\tscrollLeft = win.pageXOffset || docElem.scrollLeft;\n\treturn {\n\t\ttop: box.top  + scrollTop  - clientTop,\n\t\tleft: box.left + scrollLeft - clientLeft\n\t};\n};\n\njQuery.offset = {\n\n\tbodyOffset: function( body ) {\n\t\tvar top = body.offsetTop,\n\t\t\tleft = body.offsetLeft;\n\n\t\tif ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {\n\t\t\ttop  += parseFloat( jQuery.css(body, \"marginTop\") ) || 0;\n\t\t\tleft += parseFloat( jQuery.css(body, \"marginLeft\") ) || 0;\n\t\t}\n\n\t\treturn { top: top, left: left };\n\t},\n\n\tsetOffset: function( elem, options, i ) {\n\t\tvar position = jQuery.css( elem, \"position\" );\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tvar curElem = jQuery( elem ),\n\t\t\tcurOffset = curElem.offset(),\n\t\t\tcurCSSTop = jQuery.css( elem, \"top\" ),\n\t\t\tcurCSSLeft = jQuery.css( elem, \"left\" ),\n\t\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) && jQuery.inArray(\"auto\", [curCSSTop, curCSSLeft]) > -1,\n\t\t\tprops = {}, curPosition = {}, curTop, curLeft;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\n\njQuery.fn.extend({\n\n\tposition: function() {\n\t\tif ( !this[0] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar elem = this[0],\n\n\t\t// Get *real* offsetParent\n\t\toffsetParent = this.offsetParent(),\n\n\t\t// Get correct offsets\n\t\toffset       = this.offset(),\n\t\tparentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();\n\n\t\t// Subtract element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\toffset.top  -= parseFloat( jQuery.css(elem, \"marginTop\") ) || 0;\n\t\toffset.left -= parseFloat( jQuery.css(elem, \"marginLeft\") ) || 0;\n\n\t\t// Add offsetParent borders\n\t\tparentOffset.top  += parseFloat( jQuery.css(offsetParent[0], \"borderTopWidth\") ) || 0;\n\t\tparentOffset.left += parseFloat( jQuery.css(offsetParent[0], \"borderLeftWidth\") ) || 0;\n\n\t\t// Subtract the two offsets\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top,\n\t\t\tleft: offset.left - parentOffset.left\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || document.body;\n\t\t\twhile ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, \"position\") === \"static\") ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || document.body;\n\t\t});\n\t}\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( {scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn jQuery.access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\t top ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn jQuery.access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n\t\t\t\t\t// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, value, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n// Expose jQuery to the global object\nwindow.jQuery = window.$ = jQuery;\n\n// Expose jQuery as an AMD module, but only for AMD loaders that\n// understand the issues with loading multiple versions of jQuery\n// in a page that all might call define(). The loader will indicate\n// they have special allowances for multiple jQuery versions by\n// specifying define.amd.jQuery = true. Register as a named module,\n// since jQuery can be concatenated with other files that may use define,\n// but not use a proper concatenation script that understands anonymous\n// AMD modules. A named AMD is safest and most robust way to register.\n// Lowercase jquery is used because AMD module names are derived from\n// file names, and jQuery is normally delivered in a lowercase file name.\n// Do this after creating the global so that if an AMD module wants to call\n// noConflict to hide this version of jQuery, it will work.\nif ( typeof define === \"function\" && define.amd && define.amd.jQuery ) {\n\tdefine( \"jquery\", [], function () { return jQuery; } );\n}\n\n})( window );\n"
  },
  {
    "path": "test/vendor/json2.js",
    "content": "/*\n    http://www.JSON.org/json2.js\n    2009-09-29\n\n    Public Domain.\n\n    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.\n\n    See http://www.JSON.org/js.html\n\n\n    This code should be minified before deployment.\n    See http://javascript.crockford.com/jsmin.html\n\n    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO\n    NOT CONTROL.\n\n\n    This file creates a global JSON object containing two methods: stringify\n    and parse.\n\n        JSON.stringify(value, replacer, space)\n            value       any JavaScript value, usually an object or array.\n\n            replacer    an optional parameter that determines how object\n                        values are stringified for objects. It can be a\n                        function or an array of strings.\n\n            space       an optional parameter that specifies the indentation\n                        of nested structures. If it is omitted, the text will\n                        be packed without extra whitespace. If it is a number,\n                        it will specify the number of spaces to indent at each\n                        level. If it is a string (such as '\\t' or '&nbsp;'),\n                        it contains the characters used to indent at each level.\n\n            This method produces a JSON text from a JavaScript value.\n\n            When an object value is found, if the object contains a toJSON\n            method, its toJSON method will be called and the result will be\n            stringified. A toJSON method does not serialize: it returns the\n            value represented by the name/value pair that should be serialized,\n            or undefined if nothing should be serialized. The toJSON method\n            will be passed the key associated with the value, and this will be\n            bound to the value\n\n            For example, this would serialize Dates as ISO strings.\n\n                Date.prototype.toJSON = function (key) {\n                    function f(n) {\n                        // Format integers to have at least two digits.\n                        return n < 10 ? '0' + n : n;\n                    }\n\n                    return this.getUTCFullYear()   + '-' +\n                         f(this.getUTCMonth() + 1) + '-' +\n                         f(this.getUTCDate())      + 'T' +\n                         f(this.getUTCHours())     + ':' +\n                         f(this.getUTCMinutes())   + ':' +\n                         f(this.getUTCSeconds())   + 'Z';\n                };\n\n            You can provide an optional replacer method. It will be passed the\n            key and value of each member, with this bound to the containing\n            object. The value that is returned from your method will be\n            serialized. If your method returns undefined, then the member will\n            be excluded from the serialization.\n\n            If the replacer parameter is an array of strings, then it will be\n            used to select the members to be serialized. It filters the results\n            such that only members with keys listed in the replacer array are\n            stringified.\n\n            Values that do not have JSON representations, such as undefined or\n            functions, will not be serialized. Such values in objects will be\n            dropped; in arrays they will be replaced with null. You can use\n            a replacer function to replace those with JSON values.\n            JSON.stringify(undefined) returns undefined.\n\n            The optional space parameter produces a stringification of the\n            value that is filled with line breaks and indentation to make it\n            easier to read.\n\n            If the space parameter is a non-empty string, then that string will\n            be used for indentation. If the space parameter is a number, then\n            the indentation will be that many spaces.\n\n            Example:\n\n            text = JSON.stringify(['e', {pluribus: 'unum'}]);\n            // text is '[\"e\",{\"pluribus\":\"unum\"}]'\n\n\n            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\\t');\n            // text is '[\\n\\t\"e\",\\n\\t{\\n\\t\\t\"pluribus\": \"unum\"\\n\\t}\\n]'\n\n            text = JSON.stringify([new Date()], function (key, value) {\n                return this[key] instanceof Date ?\n                    'Date(' + this[key] + ')' : value;\n            });\n            // text is '[\"Date(---current time---)\"]'\n\n\n        JSON.parse(text, reviver)\n            This method parses a JSON text to produce an object or array.\n            It can throw a SyntaxError exception.\n\n            The optional reviver parameter is a function that can filter and\n            transform the results. It receives each of the keys and values,\n            and its return value is used instead of the original value.\n            If it returns what it received, then the structure is not modified.\n            If it returns undefined then the member is deleted.\n\n            Example:\n\n            // Parse the text. Values that look like ISO date strings will\n            // be converted to Date objects.\n\n            myData = JSON.parse(text, function (key, value) {\n                var a;\n                if (typeof value === 'string') {\n                    a =\n/^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d*)?)Z$/.exec(value);\n                    if (a) {\n                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],\n                            +a[5], +a[6]));\n                    }\n                }\n                return value;\n            });\n\n            myData = JSON.parse('[\"Date(09/09/2001)\"]', function (key, value) {\n                var d;\n                if (typeof value === 'string' &&\n                        value.slice(0, 5) === 'Date(' &&\n                        value.slice(-1) === ')') {\n                    d = new Date(value.slice(5, -1));\n                    if (d) {\n                        return d;\n                    }\n                }\n                return value;\n            });\n\n\n    This is a reference implementation. You are free to copy, modify, or\n    redistribute.\n*/\n\n/*jslint evil: true, strict: false */\n\n/*members \"\", \"\\b\", \"\\t\", \"\\n\", \"\\f\", \"\\r\", \"\\\"\", JSON, \"\\\\\", apply,\n    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,\n    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,\n    lastIndex, length, parse, prototype, push, replace, slice, stringify,\n    test, toJSON, toString, valueOf\n*/\n\n\n// Create a JSON object only if one does not already exist. We create the\n// methods in a closure to avoid creating global variables.\n\nif (!this.JSON) {\n    this.JSON = {};\n}\n\n(function () {\n\n    function f(n) {\n        // Format integers to have at least two digits.\n        return n < 10 ? '0' + n : n;\n    }\n\n    if (typeof Date.prototype.toJSON !== 'function') {\n\n        Date.prototype.toJSON = function (key) {\n\n            return isFinite(this.valueOf()) ?\n                   this.getUTCFullYear()   + '-' +\n                 f(this.getUTCMonth() + 1) + '-' +\n                 f(this.getUTCDate())      + 'T' +\n                 f(this.getUTCHours())     + ':' +\n                 f(this.getUTCMinutes())   + ':' +\n                 f(this.getUTCSeconds())   + 'Z' : null;\n        };\n\n        String.prototype.toJSON =\n        Number.prototype.toJSON =\n        Boolean.prototype.toJSON = function (key) {\n            return this.valueOf();\n        };\n    }\n\n    var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n        escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n        gap,\n        indent,\n        meta = {    // table of character substitutions\n            '\\b': '\\\\b',\n            '\\t': '\\\\t',\n            '\\n': '\\\\n',\n            '\\f': '\\\\f',\n            '\\r': '\\\\r',\n            '\"' : '\\\\\"',\n            '\\\\': '\\\\\\\\'\n        },\n        rep;\n\n\n    function quote(string) {\n\n// If the string contains no control characters, no quote characters, and no\n// backslash characters, then we can safely slap some quotes around it.\n// Otherwise we must also replace the offending characters with safe escape\n// sequences.\n\n        escapable.lastIndex = 0;\n        return escapable.test(string) ?\n            '\"' + string.replace(escapable, function (a) {\n                var c = meta[a];\n                return typeof c === 'string' ? c :\n                    '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n            }) + '\"' :\n            '\"' + string + '\"';\n    }\n\n\n    function str(key, holder) {\n\n// Produce a string from holder[key].\n\n        var i,          // The loop counter.\n            k,          // The member key.\n            v,          // The member value.\n            length,\n            mind = gap,\n            partial,\n            value = holder[key];\n\n// If the value has a toJSON method, call it to obtain a replacement value.\n\n        if (value && typeof value === 'object' &&\n                typeof value.toJSON === 'function') {\n            value = value.toJSON(key);\n        }\n\n// If we were called with a replacer function, then call the replacer to\n// obtain a replacement value.\n\n        if (typeof rep === 'function') {\n            value = rep.call(holder, key, value);\n        }\n\n// What happens next depends on the value's type.\n\n        switch (typeof value) {\n        case 'string':\n            return quote(value);\n\n        case 'number':\n\n// JSON numbers must be finite. Encode non-finite numbers as null.\n\n            return isFinite(value) ? String(value) : 'null';\n\n        case 'boolean':\n        case 'null':\n\n// If the value is a boolean or null, convert it to a string. Note:\n// typeof null does not produce 'null'. The case is included here in\n// the remote chance that this gets fixed someday.\n\n            return String(value);\n\n// If the type is 'object', we might be dealing with an object or an array or\n// null.\n\n        case 'object':\n\n// Due to a specification blunder in ECMAScript, typeof null is 'object',\n// so watch out for that case.\n\n            if (!value) {\n                return 'null';\n            }\n\n// Make an array to hold the partial results of stringifying this object value.\n\n            gap += indent;\n            partial = [];\n\n// Is the value an array?\n\n            if (Object.prototype.toString.apply(value) === '[object Array]') {\n\n// The value is an array. Stringify every element. Use null as a placeholder\n// for non-JSON values.\n\n                length = value.length;\n                for (i = 0; i < length; i += 1) {\n                    partial[i] = str(i, value) || 'null';\n                }\n\n// Join all of the elements together, separated with commas, and wrap them in\n// brackets.\n\n                v = partial.length === 0 ? '[]' :\n                    gap ? '[\\n' + gap +\n                            partial.join(',\\n' + gap) + '\\n' +\n                                mind + ']' :\n                          '[' + partial.join(',') + ']';\n                gap = mind;\n                return v;\n            }\n\n// If the replacer is an array, use it to select the members to be stringified.\n\n            if (rep && typeof rep === 'object') {\n                length = rep.length;\n                for (i = 0; i < length; i += 1) {\n                    k = rep[i];\n                    if (typeof k === 'string') {\n                        v = str(k, value);\n                        if (v) {\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\n                        }\n                    }\n                }\n            } else {\n\n// Otherwise, iterate through all of the keys in the object.\n\n                for (k in value) {\n                    if (Object.hasOwnProperty.call(value, k)) {\n                        v = str(k, value);\n                        if (v) {\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\n                        }\n                    }\n                }\n            }\n\n// Join all of the member texts together, separated with commas,\n// and wrap them in braces.\n\n            v = partial.length === 0 ? '{}' :\n                gap ? '{\\n' + gap + partial.join(',\\n' + gap) + '\\n' +\n                        mind + '}' : '{' + partial.join(',') + '}';\n            gap = mind;\n            return v;\n        }\n    }\n\n// If the JSON object does not yet have a stringify method, give it one.\n\n    if (typeof JSON.stringify !== 'function') {\n        JSON.stringify = function (value, replacer, space) {\n\n// The stringify method takes a value and an optional replacer, and an optional\n// space parameter, and returns a JSON text. The replacer can be a function\n// that can replace values, or an array of strings that will select the keys.\n// A default replacer method can be provided. Use of the space parameter can\n// produce text that is more easily readable.\n\n            var i;\n            gap = '';\n            indent = '';\n\n// If the space parameter is a number, make an indent string containing that\n// many spaces.\n\n            if (typeof space === 'number') {\n                for (i = 0; i < space; i += 1) {\n                    indent += ' ';\n                }\n\n// If the space parameter is a string, it will be used as the indent string.\n\n            } else if (typeof space === 'string') {\n                indent = space;\n            }\n\n// If there is a replacer, it must be a function or an array.\n// Otherwise, throw an error.\n\n            rep = replacer;\n            if (replacer && typeof replacer !== 'function' &&\n                    (typeof replacer !== 'object' ||\n                     typeof replacer.length !== 'number')) {\n                throw new Error('JSON.stringify');\n            }\n\n// Make a fake root object containing our value under the key of ''.\n// Return the result of stringifying the value.\n\n            return str('', {'': value});\n        };\n    }\n\n\n// If the JSON object does not yet have a parse method, give it one.\n\n    if (typeof JSON.parse !== 'function') {\n        JSON.parse = function (text, reviver) {\n\n// The parse method takes a text and an optional reviver function, and returns\n// a JavaScript value if the text is a valid JSON text.\n\n            var j;\n\n            function walk(holder, key) {\n\n// The walk method is used to recursively walk the resulting structure so\n// that modifications can be made.\n\n                var k, v, value = holder[key];\n                if (value && typeof value === 'object') {\n                    for (k in value) {\n                        if (Object.hasOwnProperty.call(value, k)) {\n                            v = walk(value, k);\n                            if (v !== undefined) {\n                                value[k] = v;\n                            } else {\n                                delete value[k];\n                            }\n                        }\n                    }\n                }\n                return reviver.call(holder, key, value);\n            }\n\n\n// Parsing happens in four stages. In the first stage, we replace certain\n// Unicode characters with escape sequences. JavaScript handles many characters\n// incorrectly, either silently deleting them, or treating them as line endings.\n\n            cx.lastIndex = 0;\n            if (cx.test(text)) {\n                text = text.replace(cx, function (a) {\n                    return '\\\\u' +\n                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n                });\n            }\n\n// In the second stage, we run the text against regular expressions that look\n// for non-JSON patterns. We are especially concerned with '()' and 'new'\n// because they can cause invocation, and '=' because it can cause mutation.\n// But just to be safe, we want to reject all unexpected forms.\n\n// We split the second stage into 4 regexp operations in order to work around\n// crippling inefficiencies in IE's and Safari's regexp engines. First we\n// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we\n// replace all simple value tokens with ']' characters. Third, we delete all\n// open brackets that follow a colon or comma or that begin the text. Finally,\n// we look to see that the remaining characters are only whitespace or ']' or\n// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\n\n            if (/^[\\],:{}\\s]*$/.\ntest(text.replace(/\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').\nreplace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g, ']').\nreplace(/(?:^|:|,)(?:\\s*\\[)+/g, ''))) {\n\n// In the third stage we use the eval function to compile the text into a\n// JavaScript structure. The '{' operator is subject to a syntactic ambiguity\n// in JavaScript: it can begin a block or an object literal. We wrap the text\n// in parens to eliminate the ambiguity.\n\n                j = eval('(' + text + ')');\n\n// In the optional fourth stage, we recursively walk the new structure, passing\n// each name/value pair to a reviver function for possible transformation.\n\n                return typeof reviver === 'function' ?\n                    walk({'': j}, '') : j;\n            }\n\n// If the text is not JSON parseable, then a SyntaxError is thrown.\n\n            throw new SyntaxError('JSON.parse');\n        };\n    }\n}());"
  },
  {
    "path": "test/vendor/qunit.css",
    "content": "/*!\n * QUnit 1.21.0\n * https://qunitjs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2016-02-01T13:07Z\n */\n\n/** Font Family and Sizes */\n\n#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult {\n\tfont-family: \"Helvetica Neue Light\", \"HelveticaNeue-Light\", \"Helvetica Neue\", Calibri, Helvetica, Arial, sans-serif;\n}\n\n#qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }\n#qunit-tests { font-size: smaller; }\n\n\n/** Resets */\n\n#qunit-tests, #qunit-header, #qunit-banner, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {\n\tmargin: 0;\n\tpadding: 0;\n}\n\n\n/** Header */\n\n#qunit-header {\n\tpadding: 0.5em 0 0.5em 1em;\n\n\tcolor: #8699A4;\n\tbackground-color: #0D3349;\n\n\tfont-size: 1.5em;\n\tline-height: 1em;\n\tfont-weight: 400;\n\n\tborder-radius: 5px 5px 0 0;\n}\n\n#qunit-header a {\n\ttext-decoration: none;\n\tcolor: #C2CCD1;\n}\n\n#qunit-header a:hover,\n#qunit-header a:focus {\n\tcolor: #FFF;\n}\n\n#qunit-testrunner-toolbar label {\n\tdisplay: inline-block;\n\tpadding: 0 0.5em 0 0.1em;\n}\n\n#qunit-banner {\n\theight: 5px;\n}\n\n#qunit-testrunner-toolbar {\n\tpadding: 0.5em 1em 0.5em 1em;\n\tcolor: #5E740B;\n\tbackground-color: #EEE;\n\toverflow: hidden;\n}\n\n#qunit-filteredTest {\n\tpadding: 0.5em 1em 0.5em 1em;\n\tbackground-color: #F4FF77;\n\tcolor: #366097;\n}\n\n#qunit-userAgent {\n\tpadding: 0.5em 1em 0.5em 1em;\n\tbackground-color: #2B81AF;\n\tcolor: #FFF;\n\ttext-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;\n}\n\n#qunit-modulefilter-container {\n\tfloat: right;\n\tpadding: 0.2em;\n}\n\n.qunit-url-config {\n\tdisplay: inline-block;\n\tpadding: 0.1em;\n}\n\n.qunit-filter {\n\tdisplay: block;\n\tfloat: right;\n\tmargin-left: 1em;\n}\n\n/** Tests: Pass/Fail */\n\n#qunit-tests {\n\tlist-style-position: inside;\n}\n\n#qunit-tests li {\n\tpadding: 0.4em 1em 0.4em 1em;\n\tborder-bottom: 1px solid #FFF;\n\tlist-style-position: inside;\n}\n\n#qunit-tests > li {\n\tdisplay: none;\n}\n\n#qunit-tests li.running,\n#qunit-tests li.pass,\n#qunit-tests li.fail,\n#qunit-tests li.skipped {\n\tdisplay: list-item;\n}\n\n#qunit-tests.hidepass {\n\tposition: relative;\n}\n\n#qunit-tests.hidepass li.running,\n#qunit-tests.hidepass li.pass {\n\tvisibility: hidden;\n\tposition: absolute;\n\twidth:   0;\n\theight:  0;\n\tpadding: 0;\n\tborder:  0;\n\tmargin:  0;\n}\n\n#qunit-tests li strong {\n\tcursor: pointer;\n}\n\n#qunit-tests li.skipped strong {\n\tcursor: default;\n}\n\n#qunit-tests li a {\n\tpadding: 0.5em;\n\tcolor: #C2CCD1;\n\ttext-decoration: none;\n}\n\n#qunit-tests li p a {\n\tpadding: 0.25em;\n\tcolor: #6B6464;\n}\n#qunit-tests li a:hover,\n#qunit-tests li a:focus {\n\tcolor: #000;\n}\n\n#qunit-tests li .runtime {\n\tfloat: right;\n\tfont-size: smaller;\n}\n\n.qunit-assert-list {\n\tmargin-top: 0.5em;\n\tpadding: 0.5em;\n\n\tbackground-color: #FFF;\n\n\tborder-radius: 5px;\n}\n\n.qunit-source {\n\tmargin: 0.6em 0 0.3em;\n}\n\n.qunit-collapsed {\n\tdisplay: none;\n}\n\n#qunit-tests table {\n\tborder-collapse: collapse;\n\tmargin-top: 0.2em;\n}\n\n#qunit-tests th {\n\ttext-align: right;\n\tvertical-align: top;\n\tpadding: 0 0.5em 0 0;\n}\n\n#qunit-tests td {\n\tvertical-align: top;\n}\n\n#qunit-tests pre {\n\tmargin: 0;\n\twhite-space: pre-wrap;\n\tword-wrap: break-word;\n}\n\n#qunit-tests del {\n\tbackground-color: #E0F2BE;\n\tcolor: #374E0C;\n\ttext-decoration: none;\n}\n\n#qunit-tests ins {\n\tbackground-color: #FFCACA;\n\tcolor: #500;\n\ttext-decoration: none;\n}\n\n/*** Test Counts */\n\n#qunit-tests b.counts                       { color: #000; }\n#qunit-tests b.passed                       { color: #5E740B; }\n#qunit-tests b.failed                       { color: #710909; }\n\n#qunit-tests li li {\n\tpadding: 5px;\n\tbackground-color: #FFF;\n\tborder-bottom: none;\n\tlist-style-position: inside;\n}\n\n/*** Passing Styles */\n\n#qunit-tests li li.pass {\n\tcolor: #3C510C;\n\tbackground-color: #FFF;\n\tborder-left: 10px solid #C6E746;\n}\n\n#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }\n#qunit-tests .pass .test-name               { color: #366097; }\n\n#qunit-tests .pass .test-actual,\n#qunit-tests .pass .test-expected           { color: #999; }\n\n#qunit-banner.qunit-pass                    { background-color: #C6E746; }\n\n/*** Failing Styles */\n\n#qunit-tests li li.fail {\n\tcolor: #710909;\n\tbackground-color: #FFF;\n\tborder-left: 10px solid #EE5757;\n\twhite-space: pre;\n}\n\n#qunit-tests > li:last-child {\n\tborder-radius: 0 0 5px 5px;\n}\n\n#qunit-tests .fail                          { color: #000; background-color: #EE5757; }\n#qunit-tests .fail .test-name,\n#qunit-tests .fail .module-name             { color: #000; }\n\n#qunit-tests .fail .test-actual             { color: #EE5757; }\n#qunit-tests .fail .test-expected           { color: #008000; }\n\n#qunit-banner.qunit-fail                    { background-color: #EE5757; }\n\n/*** Skipped tests */\n\n#qunit-tests .skipped {\n\tbackground-color: #EBECE9;\n}\n\n#qunit-tests .qunit-skipped-label {\n\tbackground-color: #F4FF77;\n\tdisplay: inline-block;\n\tfont-style: normal;\n\tcolor: #366097;\n\tline-height: 1.8em;\n\tpadding: 0 0.5em;\n\tmargin: -0.4em 0.4em -0.4em 0;\n}\n\n/** Result */\n\n#qunit-testresult {\n\tpadding: 0.5em 1em 0.5em 1em;\n\n\tcolor: #2B81AF;\n\tbackground-color: #D2E0E6;\n\n\tborder-bottom: 1px solid #FFF;\n}\n#qunit-testresult .module-name {\n\tfont-weight: 700;\n}\n\n/** Fixture */\n\n#qunit-fixture {\n\tposition: absolute;\n\ttop: -10000px;\n\tleft: -10000px;\n\twidth: 1000px;\n\theight: 1000px;\n}\n"
  },
  {
    "path": "test/vendor/qunit.js",
    "content": "/*!\n * QUnit 1.21.0\n * https://qunitjs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2016-02-01T13:07Z\n */\n\n(function( global ) {\n\nvar QUnit = {};\n\nvar Date = global.Date;\nvar now = Date.now || function() {\n\treturn new Date().getTime();\n};\n\nvar setTimeout = global.setTimeout;\nvar clearTimeout = global.clearTimeout;\n\n// Store a local window from the global to allow direct references.\nvar window = global.window;\n\nvar defined = {\n\tdocument: window && window.document !== undefined,\n\tsetTimeout: setTimeout !== undefined,\n\tsessionStorage: (function() {\n\t\tvar x = \"qunit-test-string\";\n\t\ttry {\n\t\t\tsessionStorage.setItem( x, x );\n\t\t\tsessionStorage.removeItem( x );\n\t\t\treturn true;\n\t\t} catch ( e ) {\n\t\t\treturn false;\n\t\t}\n\t}() )\n};\n\nvar fileName = ( sourceFromStacktrace( 0 ) || \"\" ).replace( /(:\\d+)+\\)?/, \"\" ).replace( /.+\\//, \"\" );\nvar globalStartCalled = false;\nvar runStarted = false;\n\nvar toString = Object.prototype.toString,\n\thasOwn = Object.prototype.hasOwnProperty;\n\n// returns a new Array with the elements that are in a but not in b\nfunction diff( a, b ) {\n\tvar i, j,\n\t\tresult = a.slice();\n\n\tfor ( i = 0; i < result.length; i++ ) {\n\t\tfor ( j = 0; j < b.length; j++ ) {\n\t\t\tif ( result[ i ] === b[ j ] ) {\n\t\t\t\tresult.splice( i, 1 );\n\t\t\t\ti--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\n// from jquery.js\nfunction inArray( elem, array ) {\n\tif ( array.indexOf ) {\n\t\treturn array.indexOf( elem );\n\t}\n\n\tfor ( var i = 0, length = array.length; i < length; i++ ) {\n\t\tif ( array[ i ] === elem ) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\n/**\n * Makes a clone of an object using only Array or Object as base,\n * and copies over the own enumerable properties.\n *\n * @param {Object} obj\n * @return {Object} New object with only the own properties (recursively).\n */\nfunction objectValues ( obj ) {\n\tvar key, val,\n\t\tvals = QUnit.is( \"array\", obj ) ? [] : {};\n\tfor ( key in obj ) {\n\t\tif ( hasOwn.call( obj, key ) ) {\n\t\t\tval = obj[ key ];\n\t\t\tvals[ key ] = val === Object( val ) ? objectValues( val ) : val;\n\t\t}\n\t}\n\treturn vals;\n}\n\nfunction extend( a, b, undefOnly ) {\n\tfor ( var prop in b ) {\n\t\tif ( hasOwn.call( b, prop ) ) {\n\n\t\t\t// Avoid \"Member not found\" error in IE8 caused by messing with window.constructor\n\t\t\t// This block runs on every environment, so `global` is being used instead of `window`\n\t\t\t// to avoid errors on node.\n\t\t\tif ( prop !== \"constructor\" || a !== global ) {\n\t\t\t\tif ( b[ prop ] === undefined ) {\n\t\t\t\t\tdelete a[ prop ];\n\t\t\t\t} else if ( !( undefOnly && typeof a[ prop ] !== \"undefined\" ) ) {\n\t\t\t\t\ta[ prop ] = b[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a;\n}\n\nfunction objectType( obj ) {\n\tif ( typeof obj === \"undefined\" ) {\n\t\treturn \"undefined\";\n\t}\n\n\t// Consider: typeof null === object\n\tif ( obj === null ) {\n\t\treturn \"null\";\n\t}\n\n\tvar match = toString.call( obj ).match( /^\\[object\\s(.*)\\]$/ ),\n\t\ttype = match && match[ 1 ];\n\n\tswitch ( type ) {\n\t\tcase \"Number\":\n\t\t\tif ( isNaN( obj ) ) {\n\t\t\t\treturn \"nan\";\n\t\t\t}\n\t\t\treturn \"number\";\n\t\tcase \"String\":\n\t\tcase \"Boolean\":\n\t\tcase \"Array\":\n\t\tcase \"Set\":\n\t\tcase \"Map\":\n\t\tcase \"Date\":\n\t\tcase \"RegExp\":\n\t\tcase \"Function\":\n\t\tcase \"Symbol\":\n\t\t\treturn type.toLowerCase();\n\t}\n\tif ( typeof obj === \"object\" ) {\n\t\treturn \"object\";\n\t}\n}\n\n// Safe object type checking\nfunction is( type, obj ) {\n\treturn QUnit.objectType( obj ) === type;\n}\n\nvar getUrlParams = function() {\n\tvar i, current;\n\tvar urlParams = {};\n\tvar location = window.location;\n\tvar params = location.search.slice( 1 ).split( \"&\" );\n\tvar length = params.length;\n\n\tif ( params[ 0 ] ) {\n\t\tfor ( i = 0; i < length; i++ ) {\n\t\t\tcurrent = params[ i ].split( \"=\" );\n\t\t\tcurrent[ 0 ] = decodeURIComponent( current[ 0 ] );\n\n\t\t\t// allow just a key to turn on a flag, e.g., test.html?noglobals\n\t\t\tcurrent[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;\n\t\t\tif ( urlParams[ current[ 0 ] ] ) {\n\t\t\t\turlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] );\n\t\t\t} else {\n\t\t\t\turlParams[ current[ 0 ] ] = current[ 1 ];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn urlParams;\n};\n\n// Doesn't support IE6 to IE9, it will return undefined on these browsers\n// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack\nfunction extractStacktrace( e, offset ) {\n\toffset = offset === undefined ? 4 : offset;\n\n\tvar stack, include, i;\n\n\tif ( e.stack ) {\n\t\tstack = e.stack.split( \"\\n\" );\n\t\tif ( /^error$/i.test( stack[ 0 ] ) ) {\n\t\t\tstack.shift();\n\t\t}\n\t\tif ( fileName ) {\n\t\t\tinclude = [];\n\t\t\tfor ( i = offset; i < stack.length; i++ ) {\n\t\t\t\tif ( stack[ i ].indexOf( fileName ) !== -1 ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tinclude.push( stack[ i ] );\n\t\t\t}\n\t\t\tif ( include.length ) {\n\t\t\t\treturn include.join( \"\\n\" );\n\t\t\t}\n\t\t}\n\t\treturn stack[ offset ];\n\n\t// Support: Safari <=6 only\n\t} else if ( e.sourceURL ) {\n\n\t\t// exclude useless self-reference for generated Error objects\n\t\tif ( /qunit.js$/.test( e.sourceURL ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// for actual exceptions, this is useful\n\t\treturn e.sourceURL + \":\" + e.line;\n\t}\n}\n\nfunction sourceFromStacktrace( offset ) {\n\tvar error = new Error();\n\n\t// Support: Safari <=7 only, IE <=10 - 11 only\n\t// Not all browsers generate the `stack` property for `new Error()`, see also #636\n\tif ( !error.stack ) {\n\t\ttry {\n\t\t\tthrow error;\n\t\t} catch ( err ) {\n\t\t\terror = err;\n\t\t}\n\t}\n\n\treturn extractStacktrace( error, offset );\n}\n\n/**\n * Config object: Maintain internal state\n * Later exposed as QUnit.config\n * `config` initialized at top of scope\n */\nvar config = {\n\t// The queue of tests to run\n\tqueue: [],\n\n\t// block until document ready\n\tblocking: true,\n\n\t// by default, run previously failed tests first\n\t// very useful in combination with \"Hide passed tests\" checked\n\treorder: true,\n\n\t// by default, modify document.title when suite is done\n\taltertitle: true,\n\n\t// HTML Reporter: collapse every test except the first failing test\n\t// If false, all failing tests will be expanded\n\tcollapse: true,\n\n\t// by default, scroll to top of the page when suite is done\n\tscrolltop: true,\n\n\t// depth up-to which object will be dumped\n\tmaxDepth: 5,\n\n\t// when enabled, all tests must call expect()\n\trequireExpects: false,\n\n\t// add checkboxes that are persisted in the query-string\n\t// when enabled, the id is set to `true` as a `QUnit.config` property\n\turlConfig: [\n\t\t{\n\t\t\tid: \"hidepassed\",\n\t\t\tlabel: \"Hide passed tests\",\n\t\t\ttooltip: \"Only show tests and assertions that fail. Stored as query-strings.\"\n\t\t},\n\t\t{\n\t\t\tid: \"noglobals\",\n\t\t\tlabel: \"Check for Globals\",\n\t\t\ttooltip: \"Enabling this will test if any test introduces new properties on the \" +\n\t\t\t\t\"global object (`window` in Browsers). Stored as query-strings.\"\n\t\t},\n\t\t{\n\t\t\tid: \"notrycatch\",\n\t\t\tlabel: \"No try-catch\",\n\t\t\ttooltip: \"Enabling this will run tests outside of a try-catch block. Makes debugging \" +\n\t\t\t\t\"exceptions in IE reasonable. Stored as query-strings.\"\n\t\t}\n\t],\n\n\t// Set of all modules.\n\tmodules: [],\n\n\t// Stack of nested modules\n\tmoduleStack: [],\n\n\t// The first unnamed module\n\tcurrentModule: {\n\t\tname: \"\",\n\t\ttests: []\n\t},\n\n\tcallbacks: {}\n};\n\nvar urlParams = defined.document ? getUrlParams() : {};\n\n// Push a loose unnamed module to the modules collection\nconfig.modules.push( config.currentModule );\n\nif ( urlParams.filter === true ) {\n\tdelete urlParams.filter;\n}\n\n// String search anywhere in moduleName+testName\nconfig.filter = urlParams.filter;\n\nconfig.testId = [];\nif ( urlParams.testId ) {\n\t// Ensure that urlParams.testId is an array\n\turlParams.testId = decodeURIComponent( urlParams.testId ).split( \",\" );\n\tfor (var i = 0; i < urlParams.testId.length; i++ ) {\n\t\tconfig.testId.push( urlParams.testId[ i ] );\n\t}\n}\n\nvar loggingCallbacks = {};\n\n// Register logging callbacks\nfunction registerLoggingCallbacks( obj ) {\n\tvar i, l, key,\n\t\tcallbackNames = [ \"begin\", \"done\", \"log\", \"testStart\", \"testDone\",\n\t\t\t\"moduleStart\", \"moduleDone\" ];\n\n\tfunction registerLoggingCallback( key ) {\n\t\tvar loggingCallback = function( callback ) {\n\t\t\tif ( objectType( callback ) !== \"function\" ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"QUnit logging methods require a callback function as their first parameters.\"\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconfig.callbacks[ key ].push( callback );\n\t\t};\n\n\t\t// DEPRECATED: This will be removed on QUnit 2.0.0+\n\t\t// Stores the registered functions allowing restoring\n\t\t// at verifyLoggingCallbacks() if modified\n\t\tloggingCallbacks[ key ] = loggingCallback;\n\n\t\treturn loggingCallback;\n\t}\n\n\tfor ( i = 0, l = callbackNames.length; i < l; i++ ) {\n\t\tkey = callbackNames[ i ];\n\n\t\t// Initialize key collection of logging callback\n\t\tif ( objectType( config.callbacks[ key ] ) === \"undefined\" ) {\n\t\t\tconfig.callbacks[ key ] = [];\n\t\t}\n\n\t\tobj[ key ] = registerLoggingCallback( key );\n\t}\n}\n\nfunction runLoggingCallbacks( key, args ) {\n\tvar i, l, callbacks;\n\n\tcallbacks = config.callbacks[ key ];\n\tfor ( i = 0, l = callbacks.length; i < l; i++ ) {\n\t\tcallbacks[ i ]( args );\n\t}\n}\n\n// DEPRECATED: This will be removed on 2.0.0+\n// This function verifies if the loggingCallbacks were modified by the user\n// If so, it will restore it, assign the given callback and print a console warning\nfunction verifyLoggingCallbacks() {\n\tvar loggingCallback, userCallback;\n\n\tfor ( loggingCallback in loggingCallbacks ) {\n\t\tif ( QUnit[ loggingCallback ] !== loggingCallbacks[ loggingCallback ] ) {\n\n\t\t\tuserCallback = QUnit[ loggingCallback ];\n\n\t\t\t// Restore the callback function\n\t\t\tQUnit[ loggingCallback ] = loggingCallbacks[ loggingCallback ];\n\n\t\t\t// Assign the deprecated given callback\n\t\t\tQUnit[ loggingCallback ]( userCallback );\n\n\t\t\tif ( global.console && global.console.warn ) {\n\t\t\t\tglobal.console.warn(\n\t\t\t\t\t\"QUnit.\" + loggingCallback + \" was replaced with a new value.\\n\" +\n\t\t\t\t\t\"Please, check out the documentation on how to apply logging callbacks.\\n\" +\n\t\t\t\t\t\"Reference: https://api.qunitjs.com/category/callbacks/\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\n( function() {\n\tif ( !defined.document ) {\n\t\treturn;\n\t}\n\n\t// `onErrorFnPrev` initialized at top of scope\n\t// Preserve other handlers\n\tvar onErrorFnPrev = window.onerror;\n\n\t// Cover uncaught exceptions\n\t// Returning true will suppress the default browser handler,\n\t// returning false will let it run.\n\twindow.onerror = function( error, filePath, linerNr ) {\n\t\tvar ret = false;\n\t\tif ( onErrorFnPrev ) {\n\t\t\tret = onErrorFnPrev( error, filePath, linerNr );\n\t\t}\n\n\t\t// Treat return value as window.onerror itself does,\n\t\t// Only do our handling if not suppressed.\n\t\tif ( ret !== true ) {\n\t\t\tif ( QUnit.config.current ) {\n\t\t\t\tif ( QUnit.config.current.ignoreGlobalErrors ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tQUnit.pushFailure( error, filePath + \":\" + linerNr );\n\t\t\t} else {\n\t\t\t\tQUnit.test( \"global failure\", extend(function() {\n\t\t\t\t\tQUnit.pushFailure( error, filePath + \":\" + linerNr );\n\t\t\t\t}, { validTest: true } ) );\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\treturn ret;\n\t};\n} )();\n\nQUnit.urlParams = urlParams;\n\n// Figure out if we're running the tests from a server or not\nQUnit.isLocal = !( defined.document && window.location.protocol !== \"file:\" );\n\n// Expose the current QUnit version\nQUnit.version = \"1.21.0\";\n\nextend( QUnit, {\n\n\t// call on start of module test to prepend name to all tests\n\tmodule: function( name, testEnvironment, executeNow ) {\n\t\tvar module, moduleFns;\n\t\tvar currentModule = config.currentModule;\n\n\t\tif ( arguments.length === 2 ) {\n\t\t\tif ( testEnvironment instanceof Function ) {\n\t\t\t\texecuteNow = testEnvironment;\n\t\t\t\ttestEnvironment = undefined;\n\t\t\t}\n\t\t}\n\n\t\t// DEPRECATED: handles setup/teardown functions,\n\t\t// beforeEach and afterEach should be used instead\n\t\tif ( testEnvironment && testEnvironment.setup ) {\n\t\t\ttestEnvironment.beforeEach = testEnvironment.setup;\n\t\t\tdelete testEnvironment.setup;\n\t\t}\n\t\tif ( testEnvironment && testEnvironment.teardown ) {\n\t\t\ttestEnvironment.afterEach = testEnvironment.teardown;\n\t\t\tdelete testEnvironment.teardown;\n\t\t}\n\n\t\tmodule = createModule();\n\n\t\tmoduleFns = {\n\t\t\tbeforeEach: setHook( module, \"beforeEach\" ),\n\t\t\tafterEach: setHook( module, \"afterEach\" )\n\t\t};\n\n\t\tif ( executeNow instanceof Function ) {\n\t\t\tconfig.moduleStack.push( module );\n\t\t\tsetCurrentModule( module );\n\t\t\texecuteNow.call( module.testEnvironment, moduleFns );\n\t\t\tconfig.moduleStack.pop();\n\t\t\tmodule = module.parentModule || currentModule;\n\t\t}\n\n\t\tsetCurrentModule( module );\n\n\t\tfunction createModule() {\n\t\t\tvar parentModule = config.moduleStack.length ?\n\t\t\t\tconfig.moduleStack.slice( -1 )[ 0 ] : null;\n\t\t\tvar moduleName = parentModule !== null ?\n\t\t\t\t[ parentModule.name, name ].join( \" > \" ) : name;\n\t\t\tvar module = {\n\t\t\t\tname: moduleName,\n\t\t\t\tparentModule: parentModule,\n\t\t\t\ttests: []\n\t\t\t};\n\n\t\t\tvar env = {};\n\t\t\tif ( parentModule ) {\n\t\t\t\textend( env, parentModule.testEnvironment );\n\t\t\t\tdelete env.beforeEach;\n\t\t\t\tdelete env.afterEach;\n\t\t\t}\n\t\t\textend( env, testEnvironment );\n\t\t\tmodule.testEnvironment = env;\n\n\t\t\tconfig.modules.push( module );\n\t\t\treturn module;\n\t\t}\n\n\t\tfunction setCurrentModule( module ) {\n\t\t\tconfig.currentModule = module;\n\t\t}\n\n\t},\n\n\t// DEPRECATED: QUnit.asyncTest() will be removed in QUnit 2.0.\n\tasyncTest: asyncTest,\n\n\ttest: test,\n\n\tskip: skip,\n\n\tonly: only,\n\n\t// DEPRECATED: The functionality of QUnit.start() will be altered in QUnit 2.0.\n\t// In QUnit 2.0, invoking it will ONLY affect the `QUnit.config.autostart` blocking behavior.\n\tstart: function( count ) {\n\t\tvar globalStartAlreadyCalled = globalStartCalled;\n\n\t\tif ( !config.current ) {\n\t\t\tglobalStartCalled = true;\n\n\t\t\tif ( runStarted ) {\n\t\t\t\tthrow new Error( \"Called start() outside of a test context while already started\" );\n\t\t\t} else if ( globalStartAlreadyCalled || count > 1 ) {\n\t\t\t\tthrow new Error( \"Called start() outside of a test context too many times\" );\n\t\t\t} else if ( config.autostart ) {\n\t\t\t\tthrow new Error( \"Called start() outside of a test context when \" +\n\t\t\t\t\t\"QUnit.config.autostart was true\" );\n\t\t\t} else if ( !config.pageLoaded ) {\n\n\t\t\t\t// The page isn't completely loaded yet, so bail out and let `QUnit.load` handle it\n\t\t\t\tconfig.autostart = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\n\t\t\t// If a test is running, adjust its semaphore\n\t\t\tconfig.current.semaphore -= count || 1;\n\n\t\t\t// If semaphore is non-numeric, throw error\n\t\t\tif ( isNaN( config.current.semaphore ) ) {\n\t\t\t\tconfig.current.semaphore = 0;\n\n\t\t\t\tQUnit.pushFailure(\n\t\t\t\t\t\"Called start() with a non-numeric decrement.\",\n\t\t\t\t\tsourceFromStacktrace( 2 )\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Don't start until equal number of stop-calls\n\t\t\tif ( config.current.semaphore > 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// throw an Error if start is called more often than stop\n\t\t\tif ( config.current.semaphore < 0 ) {\n\t\t\t\tconfig.current.semaphore = 0;\n\n\t\t\t\tQUnit.pushFailure(\n\t\t\t\t\t\"Called start() while already started (test's semaphore was 0 already)\",\n\t\t\t\t\tsourceFromStacktrace( 2 )\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tresumeProcessing();\n\t},\n\n\t// DEPRECATED: QUnit.stop() will be removed in QUnit 2.0.\n\tstop: function( count ) {\n\n\t\t// If there isn't a test running, don't allow QUnit.stop() to be called\n\t\tif ( !config.current ) {\n\t\t\tthrow new Error( \"Called stop() outside of a test context\" );\n\t\t}\n\n\t\t// If a test is running, adjust its semaphore\n\t\tconfig.current.semaphore += count || 1;\n\n\t\tpauseProcessing();\n\t},\n\n\tconfig: config,\n\n\tis: is,\n\n\tobjectType: objectType,\n\n\textend: extend,\n\n\tload: function() {\n\t\tconfig.pageLoaded = true;\n\n\t\t// Initialize the configuration options\n\t\textend( config, {\n\t\t\tstats: { all: 0, bad: 0 },\n\t\t\tmoduleStats: { all: 0, bad: 0 },\n\t\t\tstarted: 0,\n\t\t\tupdateRate: 1000,\n\t\t\tautostart: true,\n\t\t\tfilter: \"\"\n\t\t}, true );\n\n\t\tconfig.blocking = false;\n\n\t\tif ( config.autostart ) {\n\t\t\tresumeProcessing();\n\t\t}\n\t},\n\n\tstack: function( offset ) {\n\t\toffset = ( offset || 0 ) + 2;\n\t\treturn sourceFromStacktrace( offset );\n\t}\n});\n\nregisterLoggingCallbacks( QUnit );\n\nfunction begin() {\n\tvar i, l,\n\t\tmodulesLog = [];\n\n\t// If the test run hasn't officially begun yet\n\tif ( !config.started ) {\n\n\t\t// Record the time of the test run's beginning\n\t\tconfig.started = now();\n\n\t\tverifyLoggingCallbacks();\n\n\t\t// Delete the loose unnamed module if unused.\n\t\tif ( config.modules[ 0 ].name === \"\" && config.modules[ 0 ].tests.length === 0 ) {\n\t\t\tconfig.modules.shift();\n\t\t}\n\n\t\t// Avoid unnecessary information by not logging modules' test environments\n\t\tfor ( i = 0, l = config.modules.length; i < l; i++ ) {\n\t\t\tmodulesLog.push({\n\t\t\t\tname: config.modules[ i ].name,\n\t\t\t\ttests: config.modules[ i ].tests\n\t\t\t});\n\t\t}\n\n\t\t// The test run is officially beginning now\n\t\trunLoggingCallbacks( \"begin\", {\n\t\t\ttotalTests: Test.count,\n\t\t\tmodules: modulesLog\n\t\t});\n\t}\n\n\tconfig.blocking = false;\n\tprocess( true );\n}\n\nfunction process( last ) {\n\tfunction next() {\n\t\tprocess( last );\n\t}\n\tvar start = now();\n\tconfig.depth = ( config.depth || 0 ) + 1;\n\n\twhile ( config.queue.length && !config.blocking ) {\n\t\tif ( !defined.setTimeout || config.updateRate <= 0 ||\n\t\t\t\t( ( now() - start ) < config.updateRate ) ) {\n\t\t\tif ( config.current ) {\n\n\t\t\t\t// Reset async tracking for each phase of the Test lifecycle\n\t\t\t\tconfig.current.usedAsync = false;\n\t\t\t}\n\t\t\tconfig.queue.shift()();\n\t\t} else {\n\t\t\tsetTimeout( next, 13 );\n\t\t\tbreak;\n\t\t}\n\t}\n\tconfig.depth--;\n\tif ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {\n\t\tdone();\n\t}\n}\n\nfunction pauseProcessing() {\n\tconfig.blocking = true;\n\n\tif ( config.testTimeout && defined.setTimeout ) {\n\t\tclearTimeout( config.timeout );\n\t\tconfig.timeout = setTimeout(function() {\n\t\t\tif ( config.current ) {\n\t\t\t\tconfig.current.semaphore = 0;\n\t\t\t\tQUnit.pushFailure( \"Test timed out\", sourceFromStacktrace( 2 ) );\n\t\t\t} else {\n\t\t\t\tthrow new Error( \"Test timed out\" );\n\t\t\t}\n\t\t\tresumeProcessing();\n\t\t}, config.testTimeout );\n\t}\n}\n\nfunction resumeProcessing() {\n\trunStarted = true;\n\n\t// A slight delay to allow this iteration of the event loop to finish (more assertions, etc.)\n\tif ( defined.setTimeout ) {\n\t\tsetTimeout(function() {\n\t\t\tif ( config.current && config.current.semaphore > 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( config.timeout ) {\n\t\t\t\tclearTimeout( config.timeout );\n\t\t\t}\n\n\t\t\tbegin();\n\t\t}, 13 );\n\t} else {\n\t\tbegin();\n\t}\n}\n\nfunction done() {\n\tvar runtime, passed;\n\n\tconfig.autorun = true;\n\n\t// Log the last module results\n\tif ( config.previousModule ) {\n\t\trunLoggingCallbacks( \"moduleDone\", {\n\t\t\tname: config.previousModule.name,\n\t\t\ttests: config.previousModule.tests,\n\t\t\tfailed: config.moduleStats.bad,\n\t\t\tpassed: config.moduleStats.all - config.moduleStats.bad,\n\t\t\ttotal: config.moduleStats.all,\n\t\t\truntime: now() - config.moduleStats.started\n\t\t});\n\t}\n\tdelete config.previousModule;\n\n\truntime = now() - config.started;\n\tpassed = config.stats.all - config.stats.bad;\n\n\trunLoggingCallbacks( \"done\", {\n\t\tfailed: config.stats.bad,\n\t\tpassed: passed,\n\t\ttotal: config.stats.all,\n\t\truntime: runtime\n\t});\n}\n\nfunction setHook( module, hookName ) {\n\tif ( module.testEnvironment === undefined ) {\n\t\tmodule.testEnvironment = {};\n\t}\n\n\treturn function( callback ) {\n\t\tmodule.testEnvironment[ hookName ] = callback;\n\t};\n}\n\nvar focused = false;\nvar priorityCount = 0;\n\nfunction Test( settings ) {\n\tvar i, l;\n\n\t++Test.count;\n\n\textend( this, settings );\n\tthis.assertions = [];\n\tthis.semaphore = 0;\n\tthis.usedAsync = false;\n\tthis.module = config.currentModule;\n\tthis.stack = sourceFromStacktrace( 3 );\n\n\t// Register unique strings\n\tfor ( i = 0, l = this.module.tests; i < l.length; i++ ) {\n\t\tif ( this.module.tests[ i ].name === this.testName ) {\n\t\t\tthis.testName += \" \";\n\t\t}\n\t}\n\n\tthis.testId = generateHash( this.module.name, this.testName );\n\n\tthis.module.tests.push({\n\t\tname: this.testName,\n\t\ttestId: this.testId\n\t});\n\n\tif ( settings.skip ) {\n\n\t\t// Skipped tests will fully ignore any sent callback\n\t\tthis.callback = function() {};\n\t\tthis.async = false;\n\t\tthis.expected = 0;\n\t} else {\n\t\tthis.assert = new Assert( this );\n\t}\n}\n\nTest.count = 0;\n\nTest.prototype = {\n\tbefore: function() {\n\t\tif (\n\n\t\t\t// Emit moduleStart when we're switching from one module to another\n\t\t\tthis.module !== config.previousModule ||\n\n\t\t\t\t// They could be equal (both undefined) but if the previousModule property doesn't\n\t\t\t\t// yet exist it means this is the first test in a suite that isn't wrapped in a\n\t\t\t\t// module, in which case we'll just emit a moduleStart event for 'undefined'.\n\t\t\t\t// Without this, reporters can get testStart before moduleStart  which is a problem.\n\t\t\t\t!hasOwn.call( config, \"previousModule\" )\n\t\t) {\n\t\t\tif ( hasOwn.call( config, \"previousModule\" ) ) {\n\t\t\t\trunLoggingCallbacks( \"moduleDone\", {\n\t\t\t\t\tname: config.previousModule.name,\n\t\t\t\t\ttests: config.previousModule.tests,\n\t\t\t\t\tfailed: config.moduleStats.bad,\n\t\t\t\t\tpassed: config.moduleStats.all - config.moduleStats.bad,\n\t\t\t\t\ttotal: config.moduleStats.all,\n\t\t\t\t\truntime: now() - config.moduleStats.started\n\t\t\t\t});\n\t\t\t}\n\t\t\tconfig.previousModule = this.module;\n\t\t\tconfig.moduleStats = { all: 0, bad: 0, started: now() };\n\t\t\trunLoggingCallbacks( \"moduleStart\", {\n\t\t\t\tname: this.module.name,\n\t\t\t\ttests: this.module.tests\n\t\t\t});\n\t\t}\n\n\t\tconfig.current = this;\n\n\t\tif ( this.module.testEnvironment ) {\n\t\t\tdelete this.module.testEnvironment.beforeEach;\n\t\t\tdelete this.module.testEnvironment.afterEach;\n\t\t}\n\t\tthis.testEnvironment = extend( {}, this.module.testEnvironment );\n\n\t\tthis.started = now();\n\t\trunLoggingCallbacks( \"testStart\", {\n\t\t\tname: this.testName,\n\t\t\tmodule: this.module.name,\n\t\t\ttestId: this.testId\n\t\t});\n\n\t\tif ( !config.pollution ) {\n\t\t\tsaveGlobal();\n\t\t}\n\t},\n\n\trun: function() {\n\t\tvar promise;\n\n\t\tconfig.current = this;\n\n\t\tif ( this.async ) {\n\t\t\tQUnit.stop();\n\t\t}\n\n\t\tthis.callbackStarted = now();\n\n\t\tif ( config.notrycatch ) {\n\t\t\trunTest( this );\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\trunTest( this );\n\t\t} catch ( e ) {\n\t\t\tthis.pushFailure( \"Died on test #\" + ( this.assertions.length + 1 ) + \" \" +\n\t\t\t\tthis.stack + \": \" + ( e.message || e ), extractStacktrace( e, 0 ) );\n\n\t\t\t// else next test will carry the responsibility\n\t\t\tsaveGlobal();\n\n\t\t\t// Restart the tests if they're blocking\n\t\t\tif ( config.blocking ) {\n\t\t\t\tQUnit.start();\n\t\t\t}\n\t\t}\n\n\t\tfunction runTest( test ) {\n\t\t\tpromise = test.callback.call( test.testEnvironment, test.assert );\n\t\t\ttest.resolvePromise( promise );\n\t\t}\n\t},\n\n\tafter: function() {\n\t\tcheckPollution();\n\t},\n\n\tqueueHook: function( hook, hookName ) {\n\t\tvar promise,\n\t\t\ttest = this;\n\t\treturn function runHook() {\n\t\t\tconfig.current = test;\n\t\t\tif ( config.notrycatch ) {\n\t\t\t\tcallHook();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tcallHook();\n\t\t\t} catch ( error ) {\n\t\t\t\ttest.pushFailure( hookName + \" failed on \" + test.testName + \": \" +\n\t\t\t\t( error.message || error ), extractStacktrace( error, 0 ) );\n\t\t\t}\n\n\t\t\tfunction callHook() {\n\t\t\t\tpromise = hook.call( test.testEnvironment, test.assert );\n\t\t\t\ttest.resolvePromise( promise, hookName );\n\t\t\t}\n\t\t};\n\t},\n\n\t// Currently only used for module level hooks, can be used to add global level ones\n\thooks: function( handler ) {\n\t\tvar hooks = [];\n\n\t\tfunction processHooks( test, module ) {\n\t\t\tif ( module.parentModule ) {\n\t\t\t\tprocessHooks( test, module.parentModule );\n\t\t\t}\n\t\t\tif ( module.testEnvironment &&\n\t\t\t\tQUnit.objectType( module.testEnvironment[ handler ] ) === \"function\" ) {\n\t\t\t\thooks.push( test.queueHook( module.testEnvironment[ handler ], handler ) );\n\t\t\t}\n\t\t}\n\n\t\t// Hooks are ignored on skipped tests\n\t\tif ( !this.skip ) {\n\t\t\tprocessHooks( this, this.module );\n\t\t}\n\t\treturn hooks;\n\t},\n\n\tfinish: function() {\n\t\tconfig.current = this;\n\t\tif ( config.requireExpects && this.expected === null ) {\n\t\t\tthis.pushFailure( \"Expected number of assertions to be defined, but expect() was \" +\n\t\t\t\t\"not called.\", this.stack );\n\t\t} else if ( this.expected !== null && this.expected !== this.assertions.length ) {\n\t\t\tthis.pushFailure( \"Expected \" + this.expected + \" assertions, but \" +\n\t\t\t\tthis.assertions.length + \" were run\", this.stack );\n\t\t} else if ( this.expected === null && !this.assertions.length ) {\n\t\t\tthis.pushFailure( \"Expected at least one assertion, but none were run - call \" +\n\t\t\t\t\"expect(0) to accept zero assertions.\", this.stack );\n\t\t}\n\n\t\tvar i,\n\t\t\tbad = 0;\n\n\t\tthis.runtime = now() - this.started;\n\t\tconfig.stats.all += this.assertions.length;\n\t\tconfig.moduleStats.all += this.assertions.length;\n\n\t\tfor ( i = 0; i < this.assertions.length; i++ ) {\n\t\t\tif ( !this.assertions[ i ].result ) {\n\t\t\t\tbad++;\n\t\t\t\tconfig.stats.bad++;\n\t\t\t\tconfig.moduleStats.bad++;\n\t\t\t}\n\t\t}\n\n\t\trunLoggingCallbacks( \"testDone\", {\n\t\t\tname: this.testName,\n\t\t\tmodule: this.module.name,\n\t\t\tskipped: !!this.skip,\n\t\t\tfailed: bad,\n\t\t\tpassed: this.assertions.length - bad,\n\t\t\ttotal: this.assertions.length,\n\t\t\truntime: this.runtime,\n\n\t\t\t// HTML Reporter use\n\t\t\tassertions: this.assertions,\n\t\t\ttestId: this.testId,\n\n\t\t\t// Source of Test\n\t\t\tsource: this.stack,\n\n\t\t\t// DEPRECATED: this property will be removed in 2.0.0, use runtime instead\n\t\t\tduration: this.runtime\n\t\t});\n\n\t\t// QUnit.reset() is deprecated and will be replaced for a new\n\t\t// fixture reset function on QUnit 2.0/2.1.\n\t\t// It's still called here for backwards compatibility handling\n\t\tQUnit.reset();\n\n\t\tconfig.current = undefined;\n\t},\n\n\tqueue: function() {\n\t\tvar priority,\n\t\t\ttest = this;\n\n\t\tif ( !this.valid() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfunction run() {\n\n\t\t\t// each of these can by async\n\t\t\tsynchronize([\n\t\t\t\tfunction() {\n\t\t\t\t\ttest.before();\n\t\t\t\t},\n\n\t\t\t\ttest.hooks( \"beforeEach\" ),\n\t\t\t\tfunction() {\n\t\t\t\t\ttest.run();\n\t\t\t\t},\n\n\t\t\t\ttest.hooks( \"afterEach\" ).reverse(),\n\n\t\t\t\tfunction() {\n\t\t\t\t\ttest.after();\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\ttest.finish();\n\t\t\t\t}\n\t\t\t]);\n\t\t}\n\n\t\t// Prioritize previously failed tests, detected from sessionStorage\n\t\tpriority = QUnit.config.reorder && defined.sessionStorage &&\n\t\t\t\t+sessionStorage.getItem( \"qunit-test-\" + this.module.name + \"-\" + this.testName );\n\n\t\treturn synchronize( run, priority );\n\t},\n\n\tpush: function( result, actual, expected, message, negative ) {\n\t\tvar source,\n\t\t\tdetails = {\n\t\t\t\tmodule: this.module.name,\n\t\t\t\tname: this.testName,\n\t\t\t\tresult: result,\n\t\t\t\tmessage: message,\n\t\t\t\tactual: actual,\n\t\t\t\texpected: expected,\n\t\t\t\ttestId: this.testId,\n\t\t\t\tnegative: negative || false,\n\t\t\t\truntime: now() - this.started\n\t\t\t};\n\n\t\tif ( !result ) {\n\t\t\tsource = sourceFromStacktrace();\n\n\t\t\tif ( source ) {\n\t\t\t\tdetails.source = source;\n\t\t\t}\n\t\t}\n\n\t\trunLoggingCallbacks( \"log\", details );\n\n\t\tthis.assertions.push({\n\t\t\tresult: !!result,\n\t\t\tmessage: message\n\t\t});\n\t},\n\n\tpushFailure: function( message, source, actual ) {\n\t\tif ( !( this instanceof Test ) ) {\n\t\t\tthrow new Error( \"pushFailure() assertion outside test context, was \" +\n\t\t\t\tsourceFromStacktrace( 2 ) );\n\t\t}\n\n\t\tvar details = {\n\t\t\t\tmodule: this.module.name,\n\t\t\t\tname: this.testName,\n\t\t\t\tresult: false,\n\t\t\t\tmessage: message || \"error\",\n\t\t\t\tactual: actual || null,\n\t\t\t\ttestId: this.testId,\n\t\t\t\truntime: now() - this.started\n\t\t\t};\n\n\t\tif ( source ) {\n\t\t\tdetails.source = source;\n\t\t}\n\n\t\trunLoggingCallbacks( \"log\", details );\n\n\t\tthis.assertions.push({\n\t\t\tresult: false,\n\t\t\tmessage: message\n\t\t});\n\t},\n\n\tresolvePromise: function( promise, phase ) {\n\t\tvar then, message,\n\t\t\ttest = this;\n\t\tif ( promise != null ) {\n\t\t\tthen = promise.then;\n\t\t\tif ( QUnit.objectType( then ) === \"function\" ) {\n\t\t\t\tQUnit.stop();\n\t\t\t\tthen.call(\n\t\t\t\t\tpromise,\n\t\t\t\t\tfunction() { QUnit.start(); },\n\t\t\t\t\tfunction( error ) {\n\t\t\t\t\t\tmessage = \"Promise rejected \" +\n\t\t\t\t\t\t\t( !phase ? \"during\" : phase.replace( /Each$/, \"\" ) ) +\n\t\t\t\t\t\t\t\" \" + test.testName + \": \" + ( error.message || error );\n\t\t\t\t\t\ttest.pushFailure( message, extractStacktrace( error, 0 ) );\n\n\t\t\t\t\t\t// else next test will carry the responsibility\n\t\t\t\t\t\tsaveGlobal();\n\n\t\t\t\t\t\t// Unblock\n\t\t\t\t\t\tQUnit.start();\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t},\n\n\tvalid: function() {\n\t\tvar filter = config.filter,\n\t\t\tregexFilter = /^(!?)\\/([\\w\\W]*)\\/(i?$)/.exec( filter ),\n\t\t\tmodule = QUnit.urlParams.module && QUnit.urlParams.module.toLowerCase(),\n\t\t\tfullName = ( this.module.name + \": \" + this.testName );\n\n\t\tfunction testInModuleChain( testModule ) {\n\t\t\tvar testModuleName = testModule.name ? testModule.name.toLowerCase() : null;\n\t\t\tif ( testModuleName === module ) {\n\t\t\t\treturn true;\n\t\t\t} else if ( testModule.parentModule ) {\n\t\t\t\treturn testInModuleChain( testModule.parentModule );\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Internally-generated tests are always valid\n\t\tif ( this.callback && this.callback.validTest ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( config.testId.length > 0 && inArray( this.testId, config.testId ) < 0 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( module && !testInModuleChain( this.module ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !filter ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn regexFilter ?\n\t\t\tthis.regexFilter( !!regexFilter[1], regexFilter[2], regexFilter[3], fullName ) :\n\t\t\tthis.stringFilter( filter, fullName );\n\t},\n\n\tregexFilter: function( exclude, pattern, flags, fullName ) {\n\t\tvar regex = new RegExp( pattern, flags );\n\t\tvar match = regex.test( fullName );\n\n\t\treturn match !== exclude;\n\t},\n\n\tstringFilter: function( filter, fullName ) {\n\t\tfilter = filter.toLowerCase();\n\t\tfullName = fullName.toLowerCase();\n\n\t\tvar include = filter.charAt( 0 ) !== \"!\";\n\t\tif ( !include ) {\n\t\t\tfilter = filter.slice( 1 );\n\t\t}\n\n\t\t// If the filter matches, we need to honour include\n\t\tif ( fullName.indexOf( filter ) !== -1 ) {\n\t\t\treturn include;\n\t\t}\n\n\t\t// Otherwise, do the opposite\n\t\treturn !include;\n\t}\n};\n\n// Resets the test setup. Useful for tests that modify the DOM.\n/*\nDEPRECATED: Use multiple tests instead of resetting inside a test.\nUse testStart or testDone for custom cleanup.\nThis method will throw an error in 2.0, and will be removed in 2.1\n*/\nQUnit.reset = function() {\n\n\t// Return on non-browser environments\n\t// This is necessary to not break on node tests\n\tif ( !defined.document ) {\n\t\treturn;\n\t}\n\n\tvar fixture = defined.document && document.getElementById &&\n\t\t\tdocument.getElementById( \"qunit-fixture\" );\n\n\tif ( fixture ) {\n\t\tfixture.innerHTML = config.fixture;\n\t}\n};\n\nQUnit.pushFailure = function() {\n\tif ( !QUnit.config.current ) {\n\t\tthrow new Error( \"pushFailure() assertion outside test context, in \" +\n\t\t\tsourceFromStacktrace( 2 ) );\n\t}\n\n\t// Gets current test obj\n\tvar currentTest = QUnit.config.current;\n\n\treturn currentTest.pushFailure.apply( currentTest, arguments );\n};\n\n// Based on Java's String.hashCode, a simple but not\n// rigorously collision resistant hashing function\nfunction generateHash( module, testName ) {\n\tvar hex,\n\t\ti = 0,\n\t\thash = 0,\n\t\tstr = module + \"\\x1C\" + testName,\n\t\tlen = str.length;\n\n\tfor ( ; i < len; i++ ) {\n\t\thash  = ( ( hash << 5 ) - hash ) + str.charCodeAt( i );\n\t\thash |= 0;\n\t}\n\n\t// Convert the possibly negative integer hash code into an 8 character hex string, which isn't\n\t// strictly necessary but increases user understanding that the id is a SHA-like hash\n\thex = ( 0x100000000 + hash ).toString( 16 );\n\tif ( hex.length < 8 ) {\n\t\thex = \"0000000\" + hex;\n\t}\n\n\treturn hex.slice( -8 );\n}\n\nfunction synchronize( callback, priority ) {\n\tvar last = !priority;\n\n\tif ( QUnit.objectType( callback ) === \"array\" ) {\n\t\twhile ( callback.length ) {\n\t\t\tsynchronize( callback.shift() );\n\t\t}\n\t\treturn;\n\t}\n\n\tif ( priority ) {\n\t\tconfig.queue.splice( priorityCount++, 0, callback );\n\t} else {\n\t\tconfig.queue.push( callback );\n\t}\n\n\tif ( config.autorun && !config.blocking ) {\n\t\tprocess( last );\n\t}\n}\n\nfunction saveGlobal() {\n\tconfig.pollution = [];\n\n\tif ( config.noglobals ) {\n\t\tfor ( var key in global ) {\n\t\t\tif ( hasOwn.call( global, key ) ) {\n\n\t\t\t\t// in Opera sometimes DOM element ids show up here, ignore them\n\t\t\t\tif ( /^qunit-test-output/.test( key ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconfig.pollution.push( key );\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction checkPollution() {\n\tvar newGlobals,\n\t\tdeletedGlobals,\n\t\told = config.pollution;\n\n\tsaveGlobal();\n\n\tnewGlobals = diff( config.pollution, old );\n\tif ( newGlobals.length > 0 ) {\n\t\tQUnit.pushFailure( \"Introduced global variable(s): \" + newGlobals.join( \", \" ) );\n\t}\n\n\tdeletedGlobals = diff( old, config.pollution );\n\tif ( deletedGlobals.length > 0 ) {\n\t\tQUnit.pushFailure( \"Deleted global variable(s): \" + deletedGlobals.join( \", \" ) );\n\t}\n}\n\n// Will be exposed as QUnit.asyncTest\nfunction asyncTest( testName, expected, callback ) {\n\tif ( arguments.length === 2 ) {\n\t\tcallback = expected;\n\t\texpected = null;\n\t}\n\n\tQUnit.test( testName, expected, callback, true );\n}\n\n// Will be exposed as QUnit.test\nfunction test( testName, expected, callback, async ) {\n\tif ( focused )  { return; }\n\n\tvar newTest;\n\n\tif ( arguments.length === 2 ) {\n\t\tcallback = expected;\n\t\texpected = null;\n\t}\n\n\tnewTest = new Test({\n\t\ttestName: testName,\n\t\texpected: expected,\n\t\tasync: async,\n\t\tcallback: callback\n\t});\n\n\tnewTest.queue();\n}\n\n// Will be exposed as QUnit.skip\nfunction skip( testName ) {\n\tif ( focused )  { return; }\n\n\tvar test = new Test({\n\t\ttestName: testName,\n\t\tskip: true\n\t});\n\n\ttest.queue();\n}\n\n// Will be exposed as QUnit.only\nfunction only( testName, expected, callback, async ) {\n\tvar newTest;\n\n\tif ( focused )  { return; }\n\n\tQUnit.config.queue.length = 0;\n\tfocused = true;\n\n\tif ( arguments.length === 2 ) {\n\t\tcallback = expected;\n\t\texpected = null;\n\t}\n\n\tnewTest = new Test({\n\t\ttestName: testName,\n\t\texpected: expected,\n\t\tasync: async,\n\t\tcallback: callback\n\t});\n\n\tnewTest.queue();\n}\n\nfunction Assert( testContext ) {\n\tthis.test = testContext;\n}\n\n// Assert helpers\nQUnit.assert = Assert.prototype = {\n\n\t// Specify the number of expected assertions to guarantee that failed test\n\t// (no assertions are run at all) don't slip through.\n\texpect: function( asserts ) {\n\t\tif ( arguments.length === 1 ) {\n\t\t\tthis.test.expected = asserts;\n\t\t} else {\n\t\t\treturn this.test.expected;\n\t\t}\n\t},\n\n\t// Increment this Test's semaphore counter, then return a function that\n\t// decrements that counter a maximum of once.\n\tasync: function( count ) {\n\t\tvar test = this.test,\n\t\t\tpopped = false,\n\t\t\tacceptCallCount = count;\n\n\t\tif ( typeof acceptCallCount === \"undefined\" ) {\n\t\t\tacceptCallCount = 1;\n\t\t}\n\n\t\ttest.semaphore += 1;\n\t\ttest.usedAsync = true;\n\t\tpauseProcessing();\n\n\t\treturn function done() {\n\n\t\t\tif ( popped ) {\n\t\t\t\ttest.pushFailure( \"Too many calls to the `assert.async` callback\",\n\t\t\t\t\tsourceFromStacktrace( 2 ) );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tacceptCallCount -= 1;\n\t\t\tif ( acceptCallCount > 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttest.semaphore -= 1;\n\t\t\tpopped = true;\n\t\t\tresumeProcessing();\n\t\t};\n\t},\n\n\t// Exports test.push() to the user API\n\tpush: function( /* result, actual, expected, message, negative */ ) {\n\t\tvar assert = this,\n\t\t\tcurrentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;\n\n\t\t// Backwards compatibility fix.\n\t\t// Allows the direct use of global exported assertions and QUnit.assert.*\n\t\t// Although, it's use is not recommended as it can leak assertions\n\t\t// to other tests from async tests, because we only get a reference to the current test,\n\t\t// not exactly the test where assertion were intended to be called.\n\t\tif ( !currentTest ) {\n\t\t\tthrow new Error( \"assertion outside test context, in \" + sourceFromStacktrace( 2 ) );\n\t\t}\n\n\t\tif ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) {\n\t\t\tcurrentTest.pushFailure( \"Assertion after the final `assert.async` was resolved\",\n\t\t\t\tsourceFromStacktrace( 2 ) );\n\n\t\t\t// Allow this assertion to continue running anyway...\n\t\t}\n\n\t\tif ( !( assert instanceof Assert ) ) {\n\t\t\tassert = currentTest.assert;\n\t\t}\n\t\treturn assert.test.push.apply( assert.test, arguments );\n\t},\n\n\tok: function( result, message ) {\n\t\tmessage = message || ( result ? \"okay\" : \"failed, expected argument to be truthy, was: \" +\n\t\t\tQUnit.dump.parse( result ) );\n\t\tthis.push( !!result, result, true, message );\n\t},\n\n\tnotOk: function( result, message ) {\n\t\tmessage = message || ( !result ? \"okay\" : \"failed, expected argument to be falsy, was: \" +\n\t\t\tQUnit.dump.parse( result ) );\n\t\tthis.push( !result, result, false, message );\n\t},\n\n\tequal: function( actual, expected, message ) {\n\t\t/*jshint eqeqeq:false */\n\t\tthis.push( expected == actual, actual, expected, message );\n\t},\n\n\tnotEqual: function( actual, expected, message ) {\n\t\t/*jshint eqeqeq:false */\n\t\tthis.push( expected != actual, actual, expected, message, true );\n\t},\n\n\tpropEqual: function( actual, expected, message ) {\n\t\tactual = objectValues( actual );\n\t\texpected = objectValues( expected );\n\t\tthis.push( QUnit.equiv( actual, expected ), actual, expected, message );\n\t},\n\n\tnotPropEqual: function( actual, expected, message ) {\n\t\tactual = objectValues( actual );\n\t\texpected = objectValues( expected );\n\t\tthis.push( !QUnit.equiv( actual, expected ), actual, expected, message, true );\n\t},\n\n\tdeepEqual: function( actual, expected, message ) {\n\t\tthis.push( QUnit.equiv( actual, expected ), actual, expected, message );\n\t},\n\n\tnotDeepEqual: function( actual, expected, message ) {\n\t\tthis.push( !QUnit.equiv( actual, expected ), actual, expected, message, true );\n\t},\n\n\tstrictEqual: function( actual, expected, message ) {\n\t\tthis.push( expected === actual, actual, expected, message );\n\t},\n\n\tnotStrictEqual: function( actual, expected, message ) {\n\t\tthis.push( expected !== actual, actual, expected, message, true );\n\t},\n\n\t\"throws\": function( block, expected, message ) {\n\t\tvar actual, expectedType,\n\t\t\texpectedOutput = expected,\n\t\t\tok = false,\n\t\t\tcurrentTest = ( this instanceof Assert && this.test ) || QUnit.config.current;\n\n\t\t// 'expected' is optional unless doing string comparison\n\t\tif ( message == null && typeof expected === \"string\" ) {\n\t\t\tmessage = expected;\n\t\t\texpected = null;\n\t\t}\n\n\t\tcurrentTest.ignoreGlobalErrors = true;\n\t\ttry {\n\t\t\tblock.call( currentTest.testEnvironment );\n\t\t} catch (e) {\n\t\t\tactual = e;\n\t\t}\n\t\tcurrentTest.ignoreGlobalErrors = false;\n\n\t\tif ( actual ) {\n\t\t\texpectedType = QUnit.objectType( expected );\n\n\t\t\t// we don't want to validate thrown error\n\t\t\tif ( !expected ) {\n\t\t\t\tok = true;\n\t\t\t\texpectedOutput = null;\n\n\t\t\t// expected is a regexp\n\t\t\t} else if ( expectedType === \"regexp\" ) {\n\t\t\t\tok = expected.test( errorString( actual ) );\n\n\t\t\t// expected is a string\n\t\t\t} else if ( expectedType === \"string\" ) {\n\t\t\t\tok = expected === errorString( actual );\n\n\t\t\t// expected is a constructor, maybe an Error constructor\n\t\t\t} else if ( expectedType === \"function\" && actual instanceof expected ) {\n\t\t\t\tok = true;\n\n\t\t\t// expected is an Error object\n\t\t\t} else if ( expectedType === \"object\" ) {\n\t\t\t\tok = actual instanceof expected.constructor &&\n\t\t\t\t\tactual.name === expected.name &&\n\t\t\t\t\tactual.message === expected.message;\n\n\t\t\t// expected is a validation function which returns true if validation passed\n\t\t\t} else if ( expectedType === \"function\" && expected.call( {}, actual ) === true ) {\n\t\t\t\texpectedOutput = null;\n\t\t\t\tok = true;\n\t\t\t}\n\t\t}\n\n\t\tcurrentTest.assert.push( ok, actual, expectedOutput, message );\n\t}\n};\n\n// Provide an alternative to assert.throws(), for environments that consider throws a reserved word\n// Known to us are: Closure Compiler, Narwhal\n(function() {\n\t/*jshint sub:true */\n\tAssert.prototype.raises = Assert.prototype[ \"throws\" ];\n}());\n\nfunction errorString( error ) {\n\tvar name, message,\n\t\tresultErrorString = error.toString();\n\tif ( resultErrorString.substring( 0, 7 ) === \"[object\" ) {\n\t\tname = error.name ? error.name.toString() : \"Error\";\n\t\tmessage = error.message ? error.message.toString() : \"\";\n\t\tif ( name && message ) {\n\t\t\treturn name + \": \" + message;\n\t\t} else if ( name ) {\n\t\t\treturn name;\n\t\t} else if ( message ) {\n\t\t\treturn message;\n\t\t} else {\n\t\t\treturn \"Error\";\n\t\t}\n\t} else {\n\t\treturn resultErrorString;\n\t}\n}\n\n// Test for equality any JavaScript type.\n// Author: Philippe Rathé <prathe@gmail.com>\nQUnit.equiv = (function() {\n\n\t// Stack to decide between skip/abort functions\n\tvar callers = [];\n\n\t// Stack to avoiding loops from circular referencing\n\tvar parents = [];\n\tvar parentsB = [];\n\n\tvar getProto = Object.getPrototypeOf || function( obj ) {\n\n\t\t/*jshint proto: true */\n\t\treturn obj.__proto__;\n\t};\n\n\tfunction useStrictEquality( b, a ) {\n\n\t\t// To catch short annotation VS 'new' annotation of a declaration. e.g.:\n\t\t// `var i = 1;`\n\t\t// `var j = new Number(1);`\n\t\tif ( typeof a === \"object\" ) {\n\t\t\ta = a.valueOf();\n\t\t}\n\t\tif ( typeof b === \"object\" ) {\n\t\t\tb = b.valueOf();\n\t\t}\n\n\t\treturn a === b;\n\t}\n\n\tfunction compareConstructors( a, b ) {\n\t\tvar protoA = getProto( a );\n\t\tvar protoB = getProto( b );\n\n\t\t// Comparing constructors is more strict than using `instanceof`\n\t\tif ( a.constructor === b.constructor ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Ref #851\n\t\t// If the obj prototype descends from a null constructor, treat it\n\t\t// as a null prototype.\n\t\tif ( protoA && protoA.constructor === null ) {\n\t\t\tprotoA = null;\n\t\t}\n\t\tif ( protoB && protoB.constructor === null ) {\n\t\t\tprotoB = null;\n\t\t}\n\n\t\t// Allow objects with no prototype to be equivalent to\n\t\t// objects with Object as their constructor.\n\t\tif ( ( protoA === null && protoB === Object.prototype ) ||\n\t\t\t\t( protoB === null && protoA === Object.prototype ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfunction getRegExpFlags( regexp ) {\n\t\treturn \"flags\" in regexp ? regexp.flags : regexp.toString().match( /[gimuy]*$/ )[ 0 ];\n\t}\n\n\tvar callbacks = {\n\t\t\"string\": useStrictEquality,\n\t\t\"boolean\": useStrictEquality,\n\t\t\"number\": useStrictEquality,\n\t\t\"null\": useStrictEquality,\n\t\t\"undefined\": useStrictEquality,\n\t\t\"symbol\": useStrictEquality,\n\t\t\"date\": useStrictEquality,\n\n\t\t\"nan\": function() {\n\t\t\treturn true;\n\t\t},\n\n\t\t\"regexp\": function( b, a ) {\n\t\t\treturn a.source === b.source &&\n\n\t\t\t\t// Include flags in the comparison\n\t\t\t\tgetRegExpFlags( a ) === getRegExpFlags( b );\n\t\t},\n\n\t\t// - skip when the property is a method of an instance (OOP)\n\t\t// - abort otherwise,\n\t\t// initial === would have catch identical references anyway\n\t\t\"function\": function() {\n\t\t\tvar caller = callers[ callers.length - 1 ];\n\t\t\treturn caller !== Object && typeof caller !== \"undefined\";\n\t\t},\n\n\t\t\"array\": function( b, a ) {\n\t\t\tvar i, j, len, loop, aCircular, bCircular;\n\n\t\t\tlen = a.length;\n\t\t\tif ( len !== b.length ) {\n\t\t\t\t// safe and faster\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Track reference to avoid circular references\n\t\t\tparents.push( a );\n\t\t\tparentsB.push( b );\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tloop = false;\n\t\t\t\tfor ( j = 0; j < parents.length; j++ ) {\n\t\t\t\t\taCircular = parents[ j ] === a[ i ];\n\t\t\t\t\tbCircular = parentsB[ j ] === b[ i ];\n\t\t\t\t\tif ( aCircular || bCircular ) {\n\t\t\t\t\t\tif ( a[ i ] === b[ i ] || aCircular && bCircular ) {\n\t\t\t\t\t\t\tloop = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tparents.pop();\n\t\t\t\t\t\t\tparentsB.pop();\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {\n\t\t\t\t\tparents.pop();\n\t\t\t\t\tparentsB.pop();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tparents.pop();\n\t\t\tparentsB.pop();\n\t\t\treturn true;\n\t\t},\n\n\t\t\"set\": function( b, a ) {\n\t\t\tvar aArray, bArray;\n\n\t\t\taArray = [];\n\t\t\ta.forEach( function( v ) {\n\t\t\t\taArray.push( v );\n\t\t\t});\n\t\t\tbArray = [];\n\t\t\tb.forEach( function( v ) {\n\t\t\t\tbArray.push( v );\n\t\t\t});\n\n\t\t\treturn innerEquiv( bArray, aArray );\n\t\t},\n\n\t\t\"map\": function( b, a ) {\n\t\t\tvar aArray, bArray;\n\n\t\t\taArray = [];\n\t\t\ta.forEach( function( v, k ) {\n\t\t\t\taArray.push( [ k, v ] );\n\t\t\t});\n\t\t\tbArray = [];\n\t\t\tb.forEach( function( v, k ) {\n\t\t\t\tbArray.push( [ k, v ] );\n\t\t\t});\n\n\t\t\treturn innerEquiv( bArray, aArray );\n\t\t},\n\n\t\t\"object\": function( b, a ) {\n\t\t\tvar i, j, loop, aCircular, bCircular;\n\n\t\t\t// Default to true\n\t\t\tvar eq = true;\n\t\t\tvar aProperties = [];\n\t\t\tvar bProperties = [];\n\n\t\t\tif ( compareConstructors( a, b ) === false ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Stack constructor before traversing properties\n\t\t\tcallers.push( a.constructor );\n\n\t\t\t// Track reference to avoid circular references\n\t\t\tparents.push( a );\n\t\t\tparentsB.push( b );\n\n\t\t\t// Be strict: don't ensure hasOwnProperty and go deep\n\t\t\tfor ( i in a ) {\n\t\t\t\tloop = false;\n\t\t\t\tfor ( j = 0; j < parents.length; j++ ) {\n\t\t\t\t\taCircular = parents[ j ] === a[ i ];\n\t\t\t\t\tbCircular = parentsB[ j ] === b[ i ];\n\t\t\t\t\tif ( aCircular || bCircular ) {\n\t\t\t\t\t\tif ( a[ i ] === b[ i ] || aCircular && bCircular ) {\n\t\t\t\t\t\t\tloop = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\teq = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\taProperties.push( i );\n\t\t\t\tif ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {\n\t\t\t\t\teq = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tparents.pop();\n\t\t\tparentsB.pop();\n\n\t\t\t// Unstack, we are done\n\t\t\tcallers.pop();\n\n\t\t\tfor ( i in b ) {\n\n\t\t\t\t// Collect b's properties\n\t\t\t\tbProperties.push( i );\n\t\t\t}\n\n\t\t\t// Ensures identical properties name\n\t\t\treturn eq && innerEquiv( aProperties.sort(), bProperties.sort() );\n\t\t}\n\t};\n\n\tfunction typeEquiv( a, b ) {\n\t\tvar type = QUnit.objectType( a );\n\t\treturn QUnit.objectType( b ) === type && callbacks[ type ]( b, a );\n\t}\n\n\t// The real equiv function\n\tfunction innerEquiv( a, b ) {\n\n\t\t// We're done when there's nothing more to compare\n\t\tif ( arguments.length < 2 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Require type-specific equality\n\t\treturn ( a === b || typeEquiv( a, b ) ) &&\n\n\t\t\t// ...across all consecutive argument pairs\n\t\t\t( arguments.length === 2 || innerEquiv.apply( this, [].slice.call( arguments, 1 ) ) );\n\t}\n\n\treturn innerEquiv;\n}());\n\n// Based on jsDump by Ariel Flesler\n// http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html\nQUnit.dump = (function() {\n\tfunction quote( str ) {\n\t\treturn \"\\\"\" + str.toString().replace( /\\\\/g, \"\\\\\\\\\" ).replace( /\"/g, \"\\\\\\\"\" ) + \"\\\"\";\n\t}\n\tfunction literal( o ) {\n\t\treturn o + \"\";\n\t}\n\tfunction join( pre, arr, post ) {\n\t\tvar s = dump.separator(),\n\t\t\tbase = dump.indent(),\n\t\t\tinner = dump.indent( 1 );\n\t\tif ( arr.join ) {\n\t\t\tarr = arr.join( \",\" + s + inner );\n\t\t}\n\t\tif ( !arr ) {\n\t\t\treturn pre + post;\n\t\t}\n\t\treturn [ pre, inner + arr, base + post ].join( s );\n\t}\n\tfunction array( arr, stack ) {\n\t\tvar i = arr.length,\n\t\t\tret = new Array( i );\n\n\t\tif ( dump.maxDepth && dump.depth > dump.maxDepth ) {\n\t\t\treturn \"[object Array]\";\n\t\t}\n\n\t\tthis.up();\n\t\twhile ( i-- ) {\n\t\t\tret[ i ] = this.parse( arr[ i ], undefined, stack );\n\t\t}\n\t\tthis.down();\n\t\treturn join( \"[\", ret, \"]\" );\n\t}\n\n\tvar reName = /^function (\\w+)/,\n\t\tdump = {\n\n\t\t\t// objType is used mostly internally, you can fix a (custom) type in advance\n\t\t\tparse: function( obj, objType, stack ) {\n\t\t\t\tstack = stack || [];\n\t\t\t\tvar res, parser, parserType,\n\t\t\t\t\tinStack = inArray( obj, stack );\n\n\t\t\t\tif ( inStack !== -1 ) {\n\t\t\t\t\treturn \"recursion(\" + ( inStack - stack.length ) + \")\";\n\t\t\t\t}\n\n\t\t\t\tobjType = objType || this.typeOf( obj  );\n\t\t\t\tparser = this.parsers[ objType ];\n\t\t\t\tparserType = typeof parser;\n\n\t\t\t\tif ( parserType === \"function\" ) {\n\t\t\t\t\tstack.push( obj );\n\t\t\t\t\tres = parser.call( this, obj, stack );\n\t\t\t\t\tstack.pop();\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t\treturn ( parserType === \"string\" ) ? parser : this.parsers.error;\n\t\t\t},\n\t\t\ttypeOf: function( obj ) {\n\t\t\t\tvar type;\n\t\t\t\tif ( obj === null ) {\n\t\t\t\t\ttype = \"null\";\n\t\t\t\t} else if ( typeof obj === \"undefined\" ) {\n\t\t\t\t\ttype = \"undefined\";\n\t\t\t\t} else if ( QUnit.is( \"regexp\", obj ) ) {\n\t\t\t\t\ttype = \"regexp\";\n\t\t\t\t} else if ( QUnit.is( \"date\", obj ) ) {\n\t\t\t\t\ttype = \"date\";\n\t\t\t\t} else if ( QUnit.is( \"function\", obj ) ) {\n\t\t\t\t\ttype = \"function\";\n\t\t\t\t} else if ( obj.setInterval !== undefined &&\n\t\t\t\t\t\tobj.document !== undefined &&\n\t\t\t\t\t\tobj.nodeType === undefined ) {\n\t\t\t\t\ttype = \"window\";\n\t\t\t\t} else if ( obj.nodeType === 9 ) {\n\t\t\t\t\ttype = \"document\";\n\t\t\t\t} else if ( obj.nodeType ) {\n\t\t\t\t\ttype = \"node\";\n\t\t\t\t} else if (\n\n\t\t\t\t\t// native arrays\n\t\t\t\t\ttoString.call( obj ) === \"[object Array]\" ||\n\n\t\t\t\t\t// NodeList objects\n\t\t\t\t\t( typeof obj.length === \"number\" && obj.item !== undefined &&\n\t\t\t\t\t( obj.length ? obj.item( 0 ) === obj[ 0 ] : ( obj.item( 0 ) === null &&\n\t\t\t\t\tobj[ 0 ] === undefined ) ) )\n\t\t\t\t) {\n\t\t\t\t\ttype = \"array\";\n\t\t\t\t} else if ( obj.constructor === Error.prototype.constructor ) {\n\t\t\t\t\ttype = \"error\";\n\t\t\t\t} else {\n\t\t\t\t\ttype = typeof obj;\n\t\t\t\t}\n\t\t\t\treturn type;\n\t\t\t},\n\t\t\tseparator: function() {\n\t\t\t\treturn this.multiline ? this.HTML ? \"<br />\" : \"\\n\" : this.HTML ? \"&#160;\" : \" \";\n\t\t\t},\n\t\t\t// extra can be a number, shortcut for increasing-calling-decreasing\n\t\t\tindent: function( extra ) {\n\t\t\t\tif ( !this.multiline ) {\n\t\t\t\t\treturn \"\";\n\t\t\t\t}\n\t\t\t\tvar chr = this.indentChar;\n\t\t\t\tif ( this.HTML ) {\n\t\t\t\t\tchr = chr.replace( /\\t/g, \"   \" ).replace( / /g, \"&#160;\" );\n\t\t\t\t}\n\t\t\t\treturn new Array( this.depth + ( extra || 0 ) ).join( chr );\n\t\t\t},\n\t\t\tup: function( a ) {\n\t\t\t\tthis.depth += a || 1;\n\t\t\t},\n\t\t\tdown: function( a ) {\n\t\t\t\tthis.depth -= a || 1;\n\t\t\t},\n\t\t\tsetParser: function( name, parser ) {\n\t\t\t\tthis.parsers[ name ] = parser;\n\t\t\t},\n\t\t\t// The next 3 are exposed so you can use them\n\t\t\tquote: quote,\n\t\t\tliteral: literal,\n\t\t\tjoin: join,\n\t\t\t//\n\t\t\tdepth: 1,\n\t\t\tmaxDepth: QUnit.config.maxDepth,\n\n\t\t\t// This is the list of parsers, to modify them, use dump.setParser\n\t\t\tparsers: {\n\t\t\t\twindow: \"[Window]\",\n\t\t\t\tdocument: \"[Document]\",\n\t\t\t\terror: function( error ) {\n\t\t\t\t\treturn \"Error(\\\"\" + error.message + \"\\\")\";\n\t\t\t\t},\n\t\t\t\tunknown: \"[Unknown]\",\n\t\t\t\t\"null\": \"null\",\n\t\t\t\t\"undefined\": \"undefined\",\n\t\t\t\t\"function\": function( fn ) {\n\t\t\t\t\tvar ret = \"function\",\n\n\t\t\t\t\t\t// functions never have name in IE\n\t\t\t\t\t\tname = \"name\" in fn ? fn.name : ( reName.exec( fn ) || [] )[ 1 ];\n\n\t\t\t\t\tif ( name ) {\n\t\t\t\t\t\tret += \" \" + name;\n\t\t\t\t\t}\n\t\t\t\t\tret += \"( \";\n\n\t\t\t\t\tret = [ ret, dump.parse( fn, \"functionArgs\" ), \"){\" ].join( \"\" );\n\t\t\t\t\treturn join( ret, dump.parse( fn, \"functionCode\" ), \"}\" );\n\t\t\t\t},\n\t\t\t\tarray: array,\n\t\t\t\tnodelist: array,\n\t\t\t\t\"arguments\": array,\n\t\t\t\tobject: function( map, stack ) {\n\t\t\t\t\tvar keys, key, val, i, nonEnumerableProperties,\n\t\t\t\t\t\tret = [];\n\n\t\t\t\t\tif ( dump.maxDepth && dump.depth > dump.maxDepth ) {\n\t\t\t\t\t\treturn \"[object Object]\";\n\t\t\t\t\t}\n\n\t\t\t\t\tdump.up();\n\t\t\t\t\tkeys = [];\n\t\t\t\t\tfor ( key in map ) {\n\t\t\t\t\t\tkeys.push( key );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Some properties are not always enumerable on Error objects.\n\t\t\t\t\tnonEnumerableProperties = [ \"message\", \"name\" ];\n\t\t\t\t\tfor ( i in nonEnumerableProperties ) {\n\t\t\t\t\t\tkey = nonEnumerableProperties[ i ];\n\t\t\t\t\t\tif ( key in map && inArray( key, keys ) < 0 ) {\n\t\t\t\t\t\t\tkeys.push( key );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tkeys.sort();\n\t\t\t\t\tfor ( i = 0; i < keys.length; i++ ) {\n\t\t\t\t\t\tkey = keys[ i ];\n\t\t\t\t\t\tval = map[ key ];\n\t\t\t\t\t\tret.push( dump.parse( key, \"key\" ) + \": \" +\n\t\t\t\t\t\t\tdump.parse( val, undefined, stack ) );\n\t\t\t\t\t}\n\t\t\t\t\tdump.down();\n\t\t\t\t\treturn join( \"{\", ret, \"}\" );\n\t\t\t\t},\n\t\t\t\tnode: function( node ) {\n\t\t\t\t\tvar len, i, val,\n\t\t\t\t\t\topen = dump.HTML ? \"&lt;\" : \"<\",\n\t\t\t\t\t\tclose = dump.HTML ? \"&gt;\" : \">\",\n\t\t\t\t\t\ttag = node.nodeName.toLowerCase(),\n\t\t\t\t\t\tret = open + tag,\n\t\t\t\t\t\tattrs = node.attributes;\n\n\t\t\t\t\tif ( attrs ) {\n\t\t\t\t\t\tfor ( i = 0, len = attrs.length; i < len; i++ ) {\n\t\t\t\t\t\t\tval = attrs[ i ].nodeValue;\n\n\t\t\t\t\t\t\t// IE6 includes all attributes in .attributes, even ones not explicitly\n\t\t\t\t\t\t\t// set. Those have values like undefined, null, 0, false, \"\" or\n\t\t\t\t\t\t\t// \"inherit\".\n\t\t\t\t\t\t\tif ( val && val !== \"inherit\" ) {\n\t\t\t\t\t\t\t\tret += \" \" + attrs[ i ].nodeName + \"=\" +\n\t\t\t\t\t\t\t\t\tdump.parse( val, \"attribute\" );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tret += close;\n\n\t\t\t\t\t// Show content of TextNode or CDATASection\n\t\t\t\t\tif ( node.nodeType === 3 || node.nodeType === 4 ) {\n\t\t\t\t\t\tret += node.nodeValue;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ret + open + \"/\" + tag + close;\n\t\t\t\t},\n\n\t\t\t\t// function calls it internally, it's the arguments part of the function\n\t\t\t\tfunctionArgs: function( fn ) {\n\t\t\t\t\tvar args,\n\t\t\t\t\t\tl = fn.length;\n\n\t\t\t\t\tif ( !l ) {\n\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t}\n\n\t\t\t\t\targs = new Array( l );\n\t\t\t\t\twhile ( l-- ) {\n\n\t\t\t\t\t\t// 97 is 'a'\n\t\t\t\t\t\targs[ l ] = String.fromCharCode( 97 + l );\n\t\t\t\t\t}\n\t\t\t\t\treturn \" \" + args.join( \", \" ) + \" \";\n\t\t\t\t},\n\t\t\t\t// object calls it internally, the key part of an item in a map\n\t\t\t\tkey: quote,\n\t\t\t\t// function calls it internally, it's the content of the function\n\t\t\t\tfunctionCode: \"[code]\",\n\t\t\t\t// node calls it internally, it's a html attribute value\n\t\t\t\tattribute: quote,\n\t\t\t\tstring: quote,\n\t\t\t\tdate: quote,\n\t\t\t\tregexp: literal,\n\t\t\t\tnumber: literal,\n\t\t\t\t\"boolean\": literal\n\t\t\t},\n\t\t\t// if true, entities are escaped ( <, >, \\t, space and \\n )\n\t\t\tHTML: false,\n\t\t\t// indentation unit\n\t\t\tindentChar: \"  \",\n\t\t\t// if true, items in a collection, are separated by a \\n, else just a space.\n\t\t\tmultiline: true\n\t\t};\n\n\treturn dump;\n}());\n\n// back compat\nQUnit.jsDump = QUnit.dump;\n\n// For browser, export only select globals\nif ( defined.document ) {\n\n\t// Deprecated\n\t// Extend assert methods to QUnit and Global scope through Backwards compatibility\n\t(function() {\n\t\tvar i,\n\t\t\tassertions = Assert.prototype;\n\n\t\tfunction applyCurrent( current ) {\n\t\t\treturn function() {\n\t\t\t\tvar assert = new Assert( QUnit.config.current );\n\t\t\t\tcurrent.apply( assert, arguments );\n\t\t\t};\n\t\t}\n\n\t\tfor ( i in assertions ) {\n\t\t\tQUnit[ i ] = applyCurrent( assertions[ i ] );\n\t\t}\n\t})();\n\n\t(function() {\n\t\tvar i, l,\n\t\t\tkeys = [\n\t\t\t\t\"test\",\n\t\t\t\t\"module\",\n\t\t\t\t\"expect\",\n\t\t\t\t\"asyncTest\",\n\t\t\t\t\"start\",\n\t\t\t\t\"stop\",\n\t\t\t\t\"ok\",\n\t\t\t\t\"notOk\",\n\t\t\t\t\"equal\",\n\t\t\t\t\"notEqual\",\n\t\t\t\t\"propEqual\",\n\t\t\t\t\"notPropEqual\",\n\t\t\t\t\"deepEqual\",\n\t\t\t\t\"notDeepEqual\",\n\t\t\t\t\"strictEqual\",\n\t\t\t\t\"notStrictEqual\",\n\t\t\t\t\"throws\",\n\t\t\t\t\"raises\"\n\t\t\t];\n\n\t\tfor ( i = 0, l = keys.length; i < l; i++ ) {\n\t\t\twindow[ keys[ i ] ] = QUnit[ keys[ i ] ];\n\t\t}\n\t})();\n\n\twindow.QUnit = QUnit;\n}\n\n// For nodejs\nif ( typeof module !== \"undefined\" && module && module.exports ) {\n\tmodule.exports = QUnit;\n\n\t// For consistency with CommonJS environments' exports\n\tmodule.exports.QUnit = QUnit;\n}\n\n// For CommonJS with exports, but without module.exports, like Rhino\nif ( typeof exports !== \"undefined\" && exports ) {\n\texports.QUnit = QUnit;\n}\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( function() {\n\t\treturn QUnit;\n\t} );\n\tQUnit.config.autostart = false;\n}\n\n/*\n * This file is a modified version of google-diff-match-patch's JavaScript implementation\n * (https://code.google.com/p/google-diff-match-patch/source/browse/trunk/javascript/diff_match_patch_uncompressed.js),\n * modifications are licensed as more fully set forth in LICENSE.txt.\n *\n * The original source of google-diff-match-patch is attributable and licensed as follows:\n *\n * Copyright 2006 Google Inc.\n * https://code.google.com/p/google-diff-match-patch/\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 * https://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 * More Info:\n *  https://code.google.com/p/google-diff-match-patch/\n *\n * Usage: QUnit.diff(expected, actual)\n *\n */\nQUnit.diff = ( function() {\n\tfunction DiffMatchPatch() {\n\t}\n\n\t//  DIFF FUNCTIONS\n\n\t/**\n\t * The data structure representing a diff is an array of tuples:\n\t * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]\n\t * which means: delete 'Hello', add 'Goodbye' and keep ' world.'\n\t */\n\tvar DIFF_DELETE = -1,\n\t\tDIFF_INSERT = 1,\n\t\tDIFF_EQUAL = 0;\n\n\t/**\n\t * Find the differences between two texts.  Simplifies the problem by stripping\n\t * any common prefix or suffix off the texts before diffing.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {boolean=} optChecklines Optional speedup flag. If present and false,\n\t *     then don't run a line-level diff first to identify the changed areas.\n\t *     Defaults to true, which does a faster, slightly less optimal diff.\n\t * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.\n\t */\n\tDiffMatchPatch.prototype.DiffMain = function( text1, text2, optChecklines ) {\n\t\tvar deadline, checklines, commonlength,\n\t\t\tcommonprefix, commonsuffix, diffs;\n\n\t\t// The diff must be complete in up to 1 second.\n\t\tdeadline = ( new Date() ).getTime() + 1000;\n\n\t\t// Check for null inputs.\n\t\tif ( text1 === null || text2 === null ) {\n\t\t\tthrow new Error( \"Null input. (DiffMain)\" );\n\t\t}\n\n\t\t// Check for equality (speedup).\n\t\tif ( text1 === text2 ) {\n\t\t\tif ( text1 ) {\n\t\t\t\treturn [\n\t\t\t\t\t[ DIFF_EQUAL, text1 ]\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn [];\n\t\t}\n\n\t\tif ( typeof optChecklines === \"undefined\" ) {\n\t\t\toptChecklines = true;\n\t\t}\n\n\t\tchecklines = optChecklines;\n\n\t\t// Trim off common prefix (speedup).\n\t\tcommonlength = this.diffCommonPrefix( text1, text2 );\n\t\tcommonprefix = text1.substring( 0, commonlength );\n\t\ttext1 = text1.substring( commonlength );\n\t\ttext2 = text2.substring( commonlength );\n\n\t\t// Trim off common suffix (speedup).\n\t\tcommonlength = this.diffCommonSuffix( text1, text2 );\n\t\tcommonsuffix = text1.substring( text1.length - commonlength );\n\t\ttext1 = text1.substring( 0, text1.length - commonlength );\n\t\ttext2 = text2.substring( 0, text2.length - commonlength );\n\n\t\t// Compute the diff on the middle block.\n\t\tdiffs = this.diffCompute( text1, text2, checklines, deadline );\n\n\t\t// Restore the prefix and suffix.\n\t\tif ( commonprefix ) {\n\t\t\tdiffs.unshift( [ DIFF_EQUAL, commonprefix ] );\n\t\t}\n\t\tif ( commonsuffix ) {\n\t\t\tdiffs.push( [ DIFF_EQUAL, commonsuffix ] );\n\t\t}\n\t\tthis.diffCleanupMerge( diffs );\n\t\treturn diffs;\n\t};\n\n\t/**\n\t * Reduce the number of edits by eliminating operationally trivial equalities.\n\t * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.\n\t */\n\tDiffMatchPatch.prototype.diffCleanupEfficiency = function( diffs ) {\n\t\tvar changes, equalities, equalitiesLength, lastequality,\n\t\t\tpointer, preIns, preDel, postIns, postDel;\n\t\tchanges = false;\n\t\tequalities = []; // Stack of indices where equalities are found.\n\t\tequalitiesLength = 0; // Keeping our own length var is faster in JS.\n\t\t/** @type {?string} */\n\t\tlastequality = null;\n\t\t// Always equal to diffs[equalities[equalitiesLength - 1]][1]\n\t\tpointer = 0; // Index of current position.\n\t\t// Is there an insertion operation before the last equality.\n\t\tpreIns = false;\n\t\t// Is there a deletion operation before the last equality.\n\t\tpreDel = false;\n\t\t// Is there an insertion operation after the last equality.\n\t\tpostIns = false;\n\t\t// Is there a deletion operation after the last equality.\n\t\tpostDel = false;\n\t\twhile ( pointer < diffs.length ) {\n\n\t\t\t// Equality found.\n\t\t\tif ( diffs[ pointer ][ 0 ] === DIFF_EQUAL ) {\n\t\t\t\tif ( diffs[ pointer ][ 1 ].length < 4 && ( postIns || postDel ) ) {\n\n\t\t\t\t\t// Candidate found.\n\t\t\t\t\tequalities[ equalitiesLength++ ] = pointer;\n\t\t\t\t\tpreIns = postIns;\n\t\t\t\t\tpreDel = postDel;\n\t\t\t\t\tlastequality = diffs[ pointer ][ 1 ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// Not a candidate, and can never become one.\n\t\t\t\t\tequalitiesLength = 0;\n\t\t\t\t\tlastequality = null;\n\t\t\t\t}\n\t\t\t\tpostIns = postDel = false;\n\n\t\t\t// An insertion or deletion.\n\t\t\t} else {\n\n\t\t\t\tif ( diffs[ pointer ][ 0 ] === DIFF_DELETE ) {\n\t\t\t\t\tpostDel = true;\n\t\t\t\t} else {\n\t\t\t\t\tpostIns = true;\n\t\t\t\t}\n\n\t\t\t\t/*\n\t\t\t\t * Five types to be split:\n\t\t\t\t * <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del>\n\t\t\t\t * <ins>A</ins>X<ins>C</ins><del>D</del>\n\t\t\t\t * <ins>A</ins><del>B</del>X<ins>C</ins>\n\t\t\t\t * <ins>A</del>X<ins>C</ins><del>D</del>\n\t\t\t\t * <ins>A</ins><del>B</del>X<del>C</del>\n\t\t\t\t */\n\t\t\t\tif ( lastequality && ( ( preIns && preDel && postIns && postDel ) ||\n\t\t\t\t\t\t( ( lastequality.length < 2 ) &&\n\t\t\t\t\t\t( preIns + preDel + postIns + postDel ) === 3 ) ) ) {\n\n\t\t\t\t\t// Duplicate record.\n\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\tequalities[ equalitiesLength - 1 ],\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t[ DIFF_DELETE, lastequality ]\n\t\t\t\t\t);\n\n\t\t\t\t\t// Change second copy to insert.\n\t\t\t\t\tdiffs[ equalities[ equalitiesLength - 1 ] + 1 ][ 0 ] = DIFF_INSERT;\n\t\t\t\t\tequalitiesLength--; // Throw away the equality we just deleted;\n\t\t\t\t\tlastequality = null;\n\t\t\t\t\tif ( preIns && preDel ) {\n\t\t\t\t\t\t// No changes made which could affect previous entry, keep going.\n\t\t\t\t\t\tpostIns = postDel = true;\n\t\t\t\t\t\tequalitiesLength = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tequalitiesLength--; // Throw away the previous equality.\n\t\t\t\t\t\tpointer = equalitiesLength > 0 ? equalities[ equalitiesLength - 1 ] : -1;\n\t\t\t\t\t\tpostIns = postDel = false;\n\t\t\t\t\t}\n\t\t\t\t\tchanges = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\n\t\tif ( changes ) {\n\t\t\tthis.diffCleanupMerge( diffs );\n\t\t}\n\t};\n\n\t/**\n\t * Convert a diff array into a pretty HTML report.\n\t * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.\n\t * @param {integer} string to be beautified.\n\t * @return {string} HTML representation.\n\t */\n\tDiffMatchPatch.prototype.diffPrettyHtml = function( diffs ) {\n\t\tvar op, data, x,\n\t\t\thtml = [];\n\t\tfor ( x = 0; x < diffs.length; x++ ) {\n\t\t\top = diffs[ x ][ 0 ]; // Operation (insert, delete, equal)\n\t\t\tdata = diffs[ x ][ 1 ]; // Text of change.\n\t\t\tswitch ( op ) {\n\t\t\tcase DIFF_INSERT:\n\t\t\t\thtml[ x ] = \"<ins>\" + data + \"</ins>\";\n\t\t\t\tbreak;\n\t\t\tcase DIFF_DELETE:\n\t\t\t\thtml[ x ] = \"<del>\" + data + \"</del>\";\n\t\t\t\tbreak;\n\t\t\tcase DIFF_EQUAL:\n\t\t\t\thtml[ x ] = \"<span>\" + data + \"</span>\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn html.join( \"\" );\n\t};\n\n\t/**\n\t * Determine the common prefix of two strings.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {number} The number of characters common to the start of each\n\t *     string.\n\t */\n\tDiffMatchPatch.prototype.diffCommonPrefix = function( text1, text2 ) {\n\t\tvar pointermid, pointermax, pointermin, pointerstart;\n\t\t// Quick check for common null cases.\n\t\tif ( !text1 || !text2 || text1.charAt( 0 ) !== text2.charAt( 0 ) ) {\n\t\t\treturn 0;\n\t\t}\n\t\t// Binary search.\n\t\t// Performance analysis: https://neil.fraser.name/news/2007/10/09/\n\t\tpointermin = 0;\n\t\tpointermax = Math.min( text1.length, text2.length );\n\t\tpointermid = pointermax;\n\t\tpointerstart = 0;\n\t\twhile ( pointermin < pointermid ) {\n\t\t\tif ( text1.substring( pointerstart, pointermid ) ===\n\t\t\t\t\ttext2.substring( pointerstart, pointermid ) ) {\n\t\t\t\tpointermin = pointermid;\n\t\t\t\tpointerstart = pointermin;\n\t\t\t} else {\n\t\t\t\tpointermax = pointermid;\n\t\t\t}\n\t\t\tpointermid = Math.floor( ( pointermax - pointermin ) / 2 + pointermin );\n\t\t}\n\t\treturn pointermid;\n\t};\n\n\t/**\n\t * Determine the common suffix of two strings.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {number} The number of characters common to the end of each string.\n\t */\n\tDiffMatchPatch.prototype.diffCommonSuffix = function( text1, text2 ) {\n\t\tvar pointermid, pointermax, pointermin, pointerend;\n\t\t// Quick check for common null cases.\n\t\tif ( !text1 ||\n\t\t\t\t!text2 ||\n\t\t\t\ttext1.charAt( text1.length - 1 ) !== text2.charAt( text2.length - 1 ) ) {\n\t\t\treturn 0;\n\t\t}\n\t\t// Binary search.\n\t\t// Performance analysis: https://neil.fraser.name/news/2007/10/09/\n\t\tpointermin = 0;\n\t\tpointermax = Math.min( text1.length, text2.length );\n\t\tpointermid = pointermax;\n\t\tpointerend = 0;\n\t\twhile ( pointermin < pointermid ) {\n\t\t\tif ( text1.substring( text1.length - pointermid, text1.length - pointerend ) ===\n\t\t\t\t\ttext2.substring( text2.length - pointermid, text2.length - pointerend ) ) {\n\t\t\t\tpointermin = pointermid;\n\t\t\t\tpointerend = pointermin;\n\t\t\t} else {\n\t\t\t\tpointermax = pointermid;\n\t\t\t}\n\t\t\tpointermid = Math.floor( ( pointermax - pointermin ) / 2 + pointermin );\n\t\t}\n\t\treturn pointermid;\n\t};\n\n\t/**\n\t * Find the differences between two texts.  Assumes that the texts do not\n\t * have any common prefix or suffix.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {boolean} checklines Speedup flag.  If false, then don't run a\n\t *     line-level diff first to identify the changed areas.\n\t *     If true, then run a faster, slightly less optimal diff.\n\t * @param {number} deadline Time when the diff should be complete by.\n\t * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffCompute = function( text1, text2, checklines, deadline ) {\n\t\tvar diffs, longtext, shorttext, i, hm,\n\t\t\ttext1A, text2A, text1B, text2B,\n\t\t\tmidCommon, diffsA, diffsB;\n\n\t\tif ( !text1 ) {\n\t\t\t// Just add some text (speedup).\n\t\t\treturn [\n\t\t\t\t[ DIFF_INSERT, text2 ]\n\t\t\t];\n\t\t}\n\n\t\tif ( !text2 ) {\n\t\t\t// Just delete some text (speedup).\n\t\t\treturn [\n\t\t\t\t[ DIFF_DELETE, text1 ]\n\t\t\t];\n\t\t}\n\n\t\tlongtext = text1.length > text2.length ? text1 : text2;\n\t\tshorttext = text1.length > text2.length ? text2 : text1;\n\t\ti = longtext.indexOf( shorttext );\n\t\tif ( i !== -1 ) {\n\t\t\t// Shorter text is inside the longer text (speedup).\n\t\t\tdiffs = [\n\t\t\t\t[ DIFF_INSERT, longtext.substring( 0, i ) ],\n\t\t\t\t[ DIFF_EQUAL, shorttext ],\n\t\t\t\t[ DIFF_INSERT, longtext.substring( i + shorttext.length ) ]\n\t\t\t];\n\t\t\t// Swap insertions for deletions if diff is reversed.\n\t\t\tif ( text1.length > text2.length ) {\n\t\t\t\tdiffs[ 0 ][ 0 ] = diffs[ 2 ][ 0 ] = DIFF_DELETE;\n\t\t\t}\n\t\t\treturn diffs;\n\t\t}\n\n\t\tif ( shorttext.length === 1 ) {\n\t\t\t// Single character string.\n\t\t\t// After the previous speedup, the character can't be an equality.\n\t\t\treturn [\n\t\t\t\t[ DIFF_DELETE, text1 ],\n\t\t\t\t[ DIFF_INSERT, text2 ]\n\t\t\t];\n\t\t}\n\n\t\t// Check to see if the problem can be split in two.\n\t\thm = this.diffHalfMatch( text1, text2 );\n\t\tif ( hm ) {\n\t\t\t// A half-match was found, sort out the return data.\n\t\t\ttext1A = hm[ 0 ];\n\t\t\ttext1B = hm[ 1 ];\n\t\t\ttext2A = hm[ 2 ];\n\t\t\ttext2B = hm[ 3 ];\n\t\t\tmidCommon = hm[ 4 ];\n\t\t\t// Send both pairs off for separate processing.\n\t\t\tdiffsA = this.DiffMain( text1A, text2A, checklines, deadline );\n\t\t\tdiffsB = this.DiffMain( text1B, text2B, checklines, deadline );\n\t\t\t// Merge the results.\n\t\t\treturn diffsA.concat( [\n\t\t\t\t[ DIFF_EQUAL, midCommon ]\n\t\t\t], diffsB );\n\t\t}\n\n\t\tif ( checklines && text1.length > 100 && text2.length > 100 ) {\n\t\t\treturn this.diffLineMode( text1, text2, deadline );\n\t\t}\n\n\t\treturn this.diffBisect( text1, text2, deadline );\n\t};\n\n\t/**\n\t * Do the two texts share a substring which is at least half the length of the\n\t * longer text?\n\t * This speedup can produce non-minimal diffs.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {Array.<string>} Five element Array, containing the prefix of\n\t *     text1, the suffix of text1, the prefix of text2, the suffix of\n\t *     text2 and the common middle.  Or null if there was no match.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffHalfMatch = function( text1, text2 ) {\n\t\tvar longtext, shorttext, dmp,\n\t\t\ttext1A, text2B, text2A, text1B, midCommon,\n\t\t\thm1, hm2, hm;\n\n\t\tlongtext = text1.length > text2.length ? text1 : text2;\n\t\tshorttext = text1.length > text2.length ? text2 : text1;\n\t\tif ( longtext.length < 4 || shorttext.length * 2 < longtext.length ) {\n\t\t\treturn null; // Pointless.\n\t\t}\n\t\tdmp = this; // 'this' becomes 'window' in a closure.\n\n\t\t/**\n\t\t * Does a substring of shorttext exist within longtext such that the substring\n\t\t * is at least half the length of longtext?\n\t\t * Closure, but does not reference any external variables.\n\t\t * @param {string} longtext Longer string.\n\t\t * @param {string} shorttext Shorter string.\n\t\t * @param {number} i Start index of quarter length substring within longtext.\n\t\t * @return {Array.<string>} Five element Array, containing the prefix of\n\t\t *     longtext, the suffix of longtext, the prefix of shorttext, the suffix\n\t\t *     of shorttext and the common middle.  Or null if there was no match.\n\t\t * @private\n\t\t */\n\t\tfunction diffHalfMatchI( longtext, shorttext, i ) {\n\t\t\tvar seed, j, bestCommon, prefixLength, suffixLength,\n\t\t\t\tbestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB;\n\t\t\t// Start with a 1/4 length substring at position i as a seed.\n\t\t\tseed = longtext.substring( i, i + Math.floor( longtext.length / 4 ) );\n\t\t\tj = -1;\n\t\t\tbestCommon = \"\";\n\t\t\twhile ( ( j = shorttext.indexOf( seed, j + 1 ) ) !== -1 ) {\n\t\t\t\tprefixLength = dmp.diffCommonPrefix( longtext.substring( i ),\n\t\t\t\t\tshorttext.substring( j ) );\n\t\t\t\tsuffixLength = dmp.diffCommonSuffix( longtext.substring( 0, i ),\n\t\t\t\t\tshorttext.substring( 0, j ) );\n\t\t\t\tif ( bestCommon.length < suffixLength + prefixLength ) {\n\t\t\t\t\tbestCommon = shorttext.substring( j - suffixLength, j ) +\n\t\t\t\t\t\tshorttext.substring( j, j + prefixLength );\n\t\t\t\t\tbestLongtextA = longtext.substring( 0, i - suffixLength );\n\t\t\t\t\tbestLongtextB = longtext.substring( i + prefixLength );\n\t\t\t\t\tbestShorttextA = shorttext.substring( 0, j - suffixLength );\n\t\t\t\t\tbestShorttextB = shorttext.substring( j + prefixLength );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( bestCommon.length * 2 >= longtext.length ) {\n\t\t\t\treturn [ bestLongtextA, bestLongtextB,\n\t\t\t\t\tbestShorttextA, bestShorttextB, bestCommon\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t// First check if the second quarter is the seed for a half-match.\n\t\thm1 = diffHalfMatchI( longtext, shorttext,\n\t\t\tMath.ceil( longtext.length / 4 ) );\n\t\t// Check again based on the third quarter.\n\t\thm2 = diffHalfMatchI( longtext, shorttext,\n\t\t\tMath.ceil( longtext.length / 2 ) );\n\t\tif ( !hm1 && !hm2 ) {\n\t\t\treturn null;\n\t\t} else if ( !hm2 ) {\n\t\t\thm = hm1;\n\t\t} else if ( !hm1 ) {\n\t\t\thm = hm2;\n\t\t} else {\n\t\t\t// Both matched.  Select the longest.\n\t\t\thm = hm1[ 4 ].length > hm2[ 4 ].length ? hm1 : hm2;\n\t\t}\n\n\t\t// A half-match was found, sort out the return data.\n\t\ttext1A, text1B, text2A, text2B;\n\t\tif ( text1.length > text2.length ) {\n\t\t\ttext1A = hm[ 0 ];\n\t\t\ttext1B = hm[ 1 ];\n\t\t\ttext2A = hm[ 2 ];\n\t\t\ttext2B = hm[ 3 ];\n\t\t} else {\n\t\t\ttext2A = hm[ 0 ];\n\t\t\ttext2B = hm[ 1 ];\n\t\t\ttext1A = hm[ 2 ];\n\t\t\ttext1B = hm[ 3 ];\n\t\t}\n\t\tmidCommon = hm[ 4 ];\n\t\treturn [ text1A, text1B, text2A, text2B, midCommon ];\n\t};\n\n\t/**\n\t * Do a quick line-level diff on both strings, then rediff the parts for\n\t * greater accuracy.\n\t * This speedup can produce non-minimal diffs.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {number} deadline Time when the diff should be complete by.\n\t * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffLineMode = function( text1, text2, deadline ) {\n\t\tvar a, diffs, linearray, pointer, countInsert,\n\t\t\tcountDelete, textInsert, textDelete, j;\n\t\t// Scan the text on a line-by-line basis first.\n\t\ta = this.diffLinesToChars( text1, text2 );\n\t\ttext1 = a.chars1;\n\t\ttext2 = a.chars2;\n\t\tlinearray = a.lineArray;\n\n\t\tdiffs = this.DiffMain( text1, text2, false, deadline );\n\n\t\t// Convert the diff back to original text.\n\t\tthis.diffCharsToLines( diffs, linearray );\n\t\t// Eliminate freak matches (e.g. blank lines)\n\t\tthis.diffCleanupSemantic( diffs );\n\n\t\t// Rediff any replacement blocks, this time character-by-character.\n\t\t// Add a dummy entry at the end.\n\t\tdiffs.push( [ DIFF_EQUAL, \"\" ] );\n\t\tpointer = 0;\n\t\tcountDelete = 0;\n\t\tcountInsert = 0;\n\t\ttextDelete = \"\";\n\t\ttextInsert = \"\";\n\t\twhile ( pointer < diffs.length ) {\n\t\t\tswitch ( diffs[ pointer ][ 0 ] ) {\n\t\t\tcase DIFF_INSERT:\n\t\t\t\tcountInsert++;\n\t\t\t\ttextInsert += diffs[ pointer ][ 1 ];\n\t\t\t\tbreak;\n\t\t\tcase DIFF_DELETE:\n\t\t\t\tcountDelete++;\n\t\t\t\ttextDelete += diffs[ pointer ][ 1 ];\n\t\t\t\tbreak;\n\t\t\tcase DIFF_EQUAL:\n\t\t\t\t// Upon reaching an equality, check for prior redundancies.\n\t\t\t\tif ( countDelete >= 1 && countInsert >= 1 ) {\n\t\t\t\t\t// Delete the offending records and add the merged ones.\n\t\t\t\t\tdiffs.splice( pointer - countDelete - countInsert,\n\t\t\t\t\t\tcountDelete + countInsert );\n\t\t\t\t\tpointer = pointer - countDelete - countInsert;\n\t\t\t\t\ta = this.DiffMain( textDelete, textInsert, false, deadline );\n\t\t\t\t\tfor ( j = a.length - 1; j >= 0; j-- ) {\n\t\t\t\t\t\tdiffs.splice( pointer, 0, a[ j ] );\n\t\t\t\t\t}\n\t\t\t\t\tpointer = pointer + a.length;\n\t\t\t\t}\n\t\t\t\tcountInsert = 0;\n\t\t\t\tcountDelete = 0;\n\t\t\t\ttextDelete = \"\";\n\t\t\t\ttextInsert = \"\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\t\tdiffs.pop(); // Remove the dummy entry at the end.\n\n\t\treturn diffs;\n\t};\n\n\t/**\n\t * Find the 'middle snake' of a diff, split the problem in two\n\t * and return the recursively constructed diff.\n\t * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {number} deadline Time at which to bail if not yet complete.\n\t * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffBisect = function( text1, text2, deadline ) {\n\t\tvar text1Length, text2Length, maxD, vOffset, vLength,\n\t\t\tv1, v2, x, delta, front, k1start, k1end, k2start,\n\t\t\tk2end, k2Offset, k1Offset, x1, x2, y1, y2, d, k1, k2;\n\t\t// Cache the text lengths to prevent multiple calls.\n\t\ttext1Length = text1.length;\n\t\ttext2Length = text2.length;\n\t\tmaxD = Math.ceil( ( text1Length + text2Length ) / 2 );\n\t\tvOffset = maxD;\n\t\tvLength = 2 * maxD;\n\t\tv1 = new Array( vLength );\n\t\tv2 = new Array( vLength );\n\t\t// Setting all elements to -1 is faster in Chrome & Firefox than mixing\n\t\t// integers and undefined.\n\t\tfor ( x = 0; x < vLength; x++ ) {\n\t\t\tv1[ x ] = -1;\n\t\t\tv2[ x ] = -1;\n\t\t}\n\t\tv1[ vOffset + 1 ] = 0;\n\t\tv2[ vOffset + 1 ] = 0;\n\t\tdelta = text1Length - text2Length;\n\t\t// If the total number of characters is odd, then the front path will collide\n\t\t// with the reverse path.\n\t\tfront = ( delta % 2 !== 0 );\n\t\t// Offsets for start and end of k loop.\n\t\t// Prevents mapping of space beyond the grid.\n\t\tk1start = 0;\n\t\tk1end = 0;\n\t\tk2start = 0;\n\t\tk2end = 0;\n\t\tfor ( d = 0; d < maxD; d++ ) {\n\t\t\t// Bail out if deadline is reached.\n\t\t\tif ( ( new Date() ).getTime() > deadline ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Walk the front path one step.\n\t\t\tfor ( k1 = -d + k1start; k1 <= d - k1end; k1 += 2 ) {\n\t\t\t\tk1Offset = vOffset + k1;\n\t\t\t\tif ( k1 === -d || ( k1 !== d && v1[ k1Offset - 1 ] < v1[ k1Offset + 1 ] ) ) {\n\t\t\t\t\tx1 = v1[ k1Offset + 1 ];\n\t\t\t\t} else {\n\t\t\t\t\tx1 = v1[ k1Offset - 1 ] + 1;\n\t\t\t\t}\n\t\t\t\ty1 = x1 - k1;\n\t\t\t\twhile ( x1 < text1Length && y1 < text2Length &&\n\t\t\t\t\ttext1.charAt( x1 ) === text2.charAt( y1 ) ) {\n\t\t\t\t\tx1++;\n\t\t\t\t\ty1++;\n\t\t\t\t}\n\t\t\t\tv1[ k1Offset ] = x1;\n\t\t\t\tif ( x1 > text1Length ) {\n\t\t\t\t\t// Ran off the right of the graph.\n\t\t\t\t\tk1end += 2;\n\t\t\t\t} else if ( y1 > text2Length ) {\n\t\t\t\t\t// Ran off the bottom of the graph.\n\t\t\t\t\tk1start += 2;\n\t\t\t\t} else if ( front ) {\n\t\t\t\t\tk2Offset = vOffset + delta - k1;\n\t\t\t\t\tif ( k2Offset >= 0 && k2Offset < vLength && v2[ k2Offset ] !== -1 ) {\n\t\t\t\t\t\t// Mirror x2 onto top-left coordinate system.\n\t\t\t\t\t\tx2 = text1Length - v2[ k2Offset ];\n\t\t\t\t\t\tif ( x1 >= x2 ) {\n\t\t\t\t\t\t\t// Overlap detected.\n\t\t\t\t\t\t\treturn this.diffBisectSplit( text1, text2, x1, y1, deadline );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Walk the reverse path one step.\n\t\t\tfor ( k2 = -d + k2start; k2 <= d - k2end; k2 += 2 ) {\n\t\t\t\tk2Offset = vOffset + k2;\n\t\t\t\tif ( k2 === -d || ( k2 !== d && v2[ k2Offset - 1 ] < v2[ k2Offset + 1 ] ) ) {\n\t\t\t\t\tx2 = v2[ k2Offset + 1 ];\n\t\t\t\t} else {\n\t\t\t\t\tx2 = v2[ k2Offset - 1 ] + 1;\n\t\t\t\t}\n\t\t\t\ty2 = x2 - k2;\n\t\t\t\twhile ( x2 < text1Length && y2 < text2Length &&\n\t\t\t\t\ttext1.charAt( text1Length - x2 - 1 ) ===\n\t\t\t\t\ttext2.charAt( text2Length - y2 - 1 ) ) {\n\t\t\t\t\tx2++;\n\t\t\t\t\ty2++;\n\t\t\t\t}\n\t\t\t\tv2[ k2Offset ] = x2;\n\t\t\t\tif ( x2 > text1Length ) {\n\t\t\t\t\t// Ran off the left of the graph.\n\t\t\t\t\tk2end += 2;\n\t\t\t\t} else if ( y2 > text2Length ) {\n\t\t\t\t\t// Ran off the top of the graph.\n\t\t\t\t\tk2start += 2;\n\t\t\t\t} else if ( !front ) {\n\t\t\t\t\tk1Offset = vOffset + delta - k2;\n\t\t\t\t\tif ( k1Offset >= 0 && k1Offset < vLength && v1[ k1Offset ] !== -1 ) {\n\t\t\t\t\t\tx1 = v1[ k1Offset ];\n\t\t\t\t\t\ty1 = vOffset + x1 - k1Offset;\n\t\t\t\t\t\t// Mirror x2 onto top-left coordinate system.\n\t\t\t\t\t\tx2 = text1Length - x2;\n\t\t\t\t\t\tif ( x1 >= x2 ) {\n\t\t\t\t\t\t\t// Overlap detected.\n\t\t\t\t\t\t\treturn this.diffBisectSplit( text1, text2, x1, y1, deadline );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Diff took too long and hit the deadline or\n\t\t// number of diffs equals number of characters, no commonality at all.\n\t\treturn [\n\t\t\t[ DIFF_DELETE, text1 ],\n\t\t\t[ DIFF_INSERT, text2 ]\n\t\t];\n\t};\n\n\t/**\n\t * Given the location of the 'middle snake', split the diff in two parts\n\t * and recurse.\n\t * @param {string} text1 Old string to be diffed.\n\t * @param {string} text2 New string to be diffed.\n\t * @param {number} x Index of split point in text1.\n\t * @param {number} y Index of split point in text2.\n\t * @param {number} deadline Time at which to bail if not yet complete.\n\t * @return {!Array.<!DiffMatchPatch.Diff>} Array of diff tuples.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffBisectSplit = function( text1, text2, x, y, deadline ) {\n\t\tvar text1a, text1b, text2a, text2b, diffs, diffsb;\n\t\ttext1a = text1.substring( 0, x );\n\t\ttext2a = text2.substring( 0, y );\n\t\ttext1b = text1.substring( x );\n\t\ttext2b = text2.substring( y );\n\n\t\t// Compute both diffs serially.\n\t\tdiffs = this.DiffMain( text1a, text2a, false, deadline );\n\t\tdiffsb = this.DiffMain( text1b, text2b, false, deadline );\n\n\t\treturn diffs.concat( diffsb );\n\t};\n\n\t/**\n\t * Reduce the number of edits by eliminating semantically trivial equalities.\n\t * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.\n\t */\n\tDiffMatchPatch.prototype.diffCleanupSemantic = function( diffs ) {\n\t\tvar changes, equalities, equalitiesLength, lastequality,\n\t\t\tpointer, lengthInsertions2, lengthDeletions2, lengthInsertions1,\n\t\t\tlengthDeletions1, deletion, insertion, overlapLength1, overlapLength2;\n\t\tchanges = false;\n\t\tequalities = []; // Stack of indices where equalities are found.\n\t\tequalitiesLength = 0; // Keeping our own length var is faster in JS.\n\t\t/** @type {?string} */\n\t\tlastequality = null;\n\t\t// Always equal to diffs[equalities[equalitiesLength - 1]][1]\n\t\tpointer = 0; // Index of current position.\n\t\t// Number of characters that changed prior to the equality.\n\t\tlengthInsertions1 = 0;\n\t\tlengthDeletions1 = 0;\n\t\t// Number of characters that changed after the equality.\n\t\tlengthInsertions2 = 0;\n\t\tlengthDeletions2 = 0;\n\t\twhile ( pointer < diffs.length ) {\n\t\t\tif ( diffs[ pointer ][ 0 ] === DIFF_EQUAL ) { // Equality found.\n\t\t\t\tequalities[ equalitiesLength++ ] = pointer;\n\t\t\t\tlengthInsertions1 = lengthInsertions2;\n\t\t\t\tlengthDeletions1 = lengthDeletions2;\n\t\t\t\tlengthInsertions2 = 0;\n\t\t\t\tlengthDeletions2 = 0;\n\t\t\t\tlastequality = diffs[ pointer ][ 1 ];\n\t\t\t} else { // An insertion or deletion.\n\t\t\t\tif ( diffs[ pointer ][ 0 ] === DIFF_INSERT ) {\n\t\t\t\t\tlengthInsertions2 += diffs[ pointer ][ 1 ].length;\n\t\t\t\t} else {\n\t\t\t\t\tlengthDeletions2 += diffs[ pointer ][ 1 ].length;\n\t\t\t\t}\n\t\t\t\t// Eliminate an equality that is smaller or equal to the edits on both\n\t\t\t\t// sides of it.\n\t\t\t\tif ( lastequality && ( lastequality.length <=\n\t\t\t\t\t\tMath.max( lengthInsertions1, lengthDeletions1 ) ) &&\n\t\t\t\t\t\t( lastequality.length <= Math.max( lengthInsertions2,\n\t\t\t\t\t\t\tlengthDeletions2 ) ) ) {\n\n\t\t\t\t\t// Duplicate record.\n\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\tequalities[ equalitiesLength - 1 ],\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t[ DIFF_DELETE, lastequality ]\n\t\t\t\t\t);\n\n\t\t\t\t\t// Change second copy to insert.\n\t\t\t\t\tdiffs[ equalities[ equalitiesLength - 1 ] + 1 ][ 0 ] = DIFF_INSERT;\n\n\t\t\t\t\t// Throw away the equality we just deleted.\n\t\t\t\t\tequalitiesLength--;\n\n\t\t\t\t\t// Throw away the previous equality (it needs to be reevaluated).\n\t\t\t\t\tequalitiesLength--;\n\t\t\t\t\tpointer = equalitiesLength > 0 ? equalities[ equalitiesLength - 1 ] : -1;\n\n\t\t\t\t\t// Reset the counters.\n\t\t\t\t\tlengthInsertions1 = 0;\n\t\t\t\t\tlengthDeletions1 = 0;\n\t\t\t\t\tlengthInsertions2 = 0;\n\t\t\t\t\tlengthDeletions2 = 0;\n\t\t\t\t\tlastequality = null;\n\t\t\t\t\tchanges = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\n\t\t// Normalize the diff.\n\t\tif ( changes ) {\n\t\t\tthis.diffCleanupMerge( diffs );\n\t\t}\n\n\t\t// Find any overlaps between deletions and insertions.\n\t\t// e.g: <del>abcxxx</del><ins>xxxdef</ins>\n\t\t//   -> <del>abc</del>xxx<ins>def</ins>\n\t\t// e.g: <del>xxxabc</del><ins>defxxx</ins>\n\t\t//   -> <ins>def</ins>xxx<del>abc</del>\n\t\t// Only extract an overlap if it is as big as the edit ahead or behind it.\n\t\tpointer = 1;\n\t\twhile ( pointer < diffs.length ) {\n\t\t\tif ( diffs[ pointer - 1 ][ 0 ] === DIFF_DELETE &&\n\t\t\t\t\tdiffs[ pointer ][ 0 ] === DIFF_INSERT ) {\n\t\t\t\tdeletion = diffs[ pointer - 1 ][ 1 ];\n\t\t\t\tinsertion = diffs[ pointer ][ 1 ];\n\t\t\t\toverlapLength1 = this.diffCommonOverlap( deletion, insertion );\n\t\t\t\toverlapLength2 = this.diffCommonOverlap( insertion, deletion );\n\t\t\t\tif ( overlapLength1 >= overlapLength2 ) {\n\t\t\t\t\tif ( overlapLength1 >= deletion.length / 2 ||\n\t\t\t\t\t\t\toverlapLength1 >= insertion.length / 2 ) {\n\t\t\t\t\t\t// Overlap found.  Insert an equality and trim the surrounding edits.\n\t\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\t\tpointer,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t[ DIFF_EQUAL, insertion.substring( 0, overlapLength1 ) ]\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] =\n\t\t\t\t\t\t\tdeletion.substring( 0, deletion.length - overlapLength1 );\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ] = insertion.substring( overlapLength1 );\n\t\t\t\t\t\tpointer++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( overlapLength2 >= deletion.length / 2 ||\n\t\t\t\t\t\t\toverlapLength2 >= insertion.length / 2 ) {\n\n\t\t\t\t\t\t// Reverse overlap found.\n\t\t\t\t\t\t// Insert an equality and swap and trim the surrounding edits.\n\t\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\t\tpointer,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t[ DIFF_EQUAL, deletion.substring( 0, overlapLength2 ) ]\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tdiffs[ pointer - 1 ][ 0 ] = DIFF_INSERT;\n\t\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] =\n\t\t\t\t\t\t\tinsertion.substring( 0, insertion.length - overlapLength2 );\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 0 ] = DIFF_DELETE;\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ] =\n\t\t\t\t\t\t\tdeletion.substring( overlapLength2 );\n\t\t\t\t\t\tpointer++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpointer++;\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\t};\n\n\t/**\n\t * Determine if the suffix of one string is the prefix of another.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {number} The number of characters common to the end of the first\n\t *     string and the start of the second string.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffCommonOverlap = function( text1, text2 ) {\n\t\tvar text1Length, text2Length, textLength,\n\t\t\tbest, length, pattern, found;\n\t\t// Cache the text lengths to prevent multiple calls.\n\t\ttext1Length = text1.length;\n\t\ttext2Length = text2.length;\n\t\t// Eliminate the null case.\n\t\tif ( text1Length === 0 || text2Length === 0 ) {\n\t\t\treturn 0;\n\t\t}\n\t\t// Truncate the longer string.\n\t\tif ( text1Length > text2Length ) {\n\t\t\ttext1 = text1.substring( text1Length - text2Length );\n\t\t} else if ( text1Length < text2Length ) {\n\t\t\ttext2 = text2.substring( 0, text1Length );\n\t\t}\n\t\ttextLength = Math.min( text1Length, text2Length );\n\t\t// Quick check for the worst case.\n\t\tif ( text1 === text2 ) {\n\t\t\treturn textLength;\n\t\t}\n\n\t\t// Start by looking for a single character match\n\t\t// and increase length until no match is found.\n\t\t// Performance analysis: https://neil.fraser.name/news/2010/11/04/\n\t\tbest = 0;\n\t\tlength = 1;\n\t\twhile ( true ) {\n\t\t\tpattern = text1.substring( textLength - length );\n\t\t\tfound = text2.indexOf( pattern );\n\t\t\tif ( found === -1 ) {\n\t\t\t\treturn best;\n\t\t\t}\n\t\t\tlength += found;\n\t\t\tif ( found === 0 || text1.substring( textLength - length ) ===\n\t\t\t\t\ttext2.substring( 0, length ) ) {\n\t\t\t\tbest = length;\n\t\t\t\tlength++;\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Split two texts into an array of strings.  Reduce the texts to a string of\n\t * hashes where each Unicode character represents one line.\n\t * @param {string} text1 First string.\n\t * @param {string} text2 Second string.\n\t * @return {{chars1: string, chars2: string, lineArray: !Array.<string>}}\n\t *     An object containing the encoded text1, the encoded text2 and\n\t *     the array of unique strings.\n\t *     The zeroth element of the array of unique strings is intentionally blank.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffLinesToChars = function( text1, text2 ) {\n\t\tvar lineArray, lineHash, chars1, chars2;\n\t\tlineArray = []; // e.g. lineArray[4] === 'Hello\\n'\n\t\tlineHash = {}; // e.g. lineHash['Hello\\n'] === 4\n\n\t\t// '\\x00' is a valid character, but various debuggers don't like it.\n\t\t// So we'll insert a junk entry to avoid generating a null character.\n\t\tlineArray[ 0 ] = \"\";\n\n\t\t/**\n\t\t * Split a text into an array of strings.  Reduce the texts to a string of\n\t\t * hashes where each Unicode character represents one line.\n\t\t * Modifies linearray and linehash through being a closure.\n\t\t * @param {string} text String to encode.\n\t\t * @return {string} Encoded string.\n\t\t * @private\n\t\t */\n\t\tfunction diffLinesToCharsMunge( text ) {\n\t\t\tvar chars, lineStart, lineEnd, lineArrayLength, line;\n\t\t\tchars = \"\";\n\t\t\t// Walk the text, pulling out a substring for each line.\n\t\t\t// text.split('\\n') would would temporarily double our memory footprint.\n\t\t\t// Modifying text would create many large strings to garbage collect.\n\t\t\tlineStart = 0;\n\t\t\tlineEnd = -1;\n\t\t\t// Keeping our own length variable is faster than looking it up.\n\t\t\tlineArrayLength = lineArray.length;\n\t\t\twhile ( lineEnd < text.length - 1 ) {\n\t\t\t\tlineEnd = text.indexOf( \"\\n\", lineStart );\n\t\t\t\tif ( lineEnd === -1 ) {\n\t\t\t\t\tlineEnd = text.length - 1;\n\t\t\t\t}\n\t\t\t\tline = text.substring( lineStart, lineEnd + 1 );\n\t\t\t\tlineStart = lineEnd + 1;\n\n\t\t\t\tif ( lineHash.hasOwnProperty ? lineHash.hasOwnProperty( line ) :\n\t\t\t\t\t\t\t( lineHash[ line ] !== undefined ) ) {\n\t\t\t\t\tchars += String.fromCharCode( lineHash[ line ] );\n\t\t\t\t} else {\n\t\t\t\t\tchars += String.fromCharCode( lineArrayLength );\n\t\t\t\t\tlineHash[ line ] = lineArrayLength;\n\t\t\t\t\tlineArray[ lineArrayLength++ ] = line;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn chars;\n\t\t}\n\n\t\tchars1 = diffLinesToCharsMunge( text1 );\n\t\tchars2 = diffLinesToCharsMunge( text2 );\n\t\treturn {\n\t\t\tchars1: chars1,\n\t\t\tchars2: chars2,\n\t\t\tlineArray: lineArray\n\t\t};\n\t};\n\n\t/**\n\t * Rehydrate the text in a diff from a string of line hashes to real lines of\n\t * text.\n\t * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.\n\t * @param {!Array.<string>} lineArray Array of unique strings.\n\t * @private\n\t */\n\tDiffMatchPatch.prototype.diffCharsToLines = function( diffs, lineArray ) {\n\t\tvar x, chars, text, y;\n\t\tfor ( x = 0; x < diffs.length; x++ ) {\n\t\t\tchars = diffs[ x ][ 1 ];\n\t\t\ttext = [];\n\t\t\tfor ( y = 0; y < chars.length; y++ ) {\n\t\t\t\ttext[ y ] = lineArray[ chars.charCodeAt( y ) ];\n\t\t\t}\n\t\t\tdiffs[ x ][ 1 ] = text.join( \"\" );\n\t\t}\n\t};\n\n\t/**\n\t * Reorder and merge like edit sections.  Merge equalities.\n\t * Any edit section can move as long as it doesn't cross an equality.\n\t * @param {!Array.<!DiffMatchPatch.Diff>} diffs Array of diff tuples.\n\t */\n\tDiffMatchPatch.prototype.diffCleanupMerge = function( diffs ) {\n\t\tvar pointer, countDelete, countInsert, textInsert, textDelete,\n\t\t\tcommonlength, changes, diffPointer, position;\n\t\tdiffs.push( [ DIFF_EQUAL, \"\" ] ); // Add a dummy entry at the end.\n\t\tpointer = 0;\n\t\tcountDelete = 0;\n\t\tcountInsert = 0;\n\t\ttextDelete = \"\";\n\t\ttextInsert = \"\";\n\t\tcommonlength;\n\t\twhile ( pointer < diffs.length ) {\n\t\t\tswitch ( diffs[ pointer ][ 0 ] ) {\n\t\t\tcase DIFF_INSERT:\n\t\t\t\tcountInsert++;\n\t\t\t\ttextInsert += diffs[ pointer ][ 1 ];\n\t\t\t\tpointer++;\n\t\t\t\tbreak;\n\t\t\tcase DIFF_DELETE:\n\t\t\t\tcountDelete++;\n\t\t\t\ttextDelete += diffs[ pointer ][ 1 ];\n\t\t\t\tpointer++;\n\t\t\t\tbreak;\n\t\t\tcase DIFF_EQUAL:\n\t\t\t\t// Upon reaching an equality, check for prior redundancies.\n\t\t\t\tif ( countDelete + countInsert > 1 ) {\n\t\t\t\t\tif ( countDelete !== 0 && countInsert !== 0 ) {\n\t\t\t\t\t\t// Factor out any common prefixes.\n\t\t\t\t\t\tcommonlength = this.diffCommonPrefix( textInsert, textDelete );\n\t\t\t\t\t\tif ( commonlength !== 0 ) {\n\t\t\t\t\t\t\tif ( ( pointer - countDelete - countInsert ) > 0 &&\n\t\t\t\t\t\t\t\t\tdiffs[ pointer - countDelete - countInsert - 1 ][ 0 ] ===\n\t\t\t\t\t\t\t\t\tDIFF_EQUAL ) {\n\t\t\t\t\t\t\t\tdiffs[ pointer - countDelete - countInsert - 1 ][ 1 ] +=\n\t\t\t\t\t\t\t\t\ttextInsert.substring( 0, commonlength );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdiffs.splice( 0, 0, [ DIFF_EQUAL,\n\t\t\t\t\t\t\t\t\ttextInsert.substring( 0, commonlength )\n\t\t\t\t\t\t\t\t] );\n\t\t\t\t\t\t\t\tpointer++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttextInsert = textInsert.substring( commonlength );\n\t\t\t\t\t\t\ttextDelete = textDelete.substring( commonlength );\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Factor out any common suffixies.\n\t\t\t\t\t\tcommonlength = this.diffCommonSuffix( textInsert, textDelete );\n\t\t\t\t\t\tif ( commonlength !== 0 ) {\n\t\t\t\t\t\t\tdiffs[ pointer ][ 1 ] = textInsert.substring( textInsert.length -\n\t\t\t\t\t\t\t\t\tcommonlength ) + diffs[ pointer ][ 1 ];\n\t\t\t\t\t\t\ttextInsert = textInsert.substring( 0, textInsert.length -\n\t\t\t\t\t\t\t\tcommonlength );\n\t\t\t\t\t\t\ttextDelete = textDelete.substring( 0, textDelete.length -\n\t\t\t\t\t\t\t\tcommonlength );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Delete the offending records and add the merged ones.\n\t\t\t\t\tif ( countDelete === 0 ) {\n\t\t\t\t\t\tdiffs.splice( pointer - countInsert,\n\t\t\t\t\t\t\tcountDelete + countInsert, [ DIFF_INSERT, textInsert ] );\n\t\t\t\t\t} else if ( countInsert === 0 ) {\n\t\t\t\t\t\tdiffs.splice( pointer - countDelete,\n\t\t\t\t\t\t\tcountDelete + countInsert, [ DIFF_DELETE, textDelete ] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdiffs.splice(\n\t\t\t\t\t\t\tpointer - countDelete - countInsert,\n\t\t\t\t\t\t\tcountDelete + countInsert,\n\t\t\t\t\t\t\t[ DIFF_DELETE, textDelete ], [ DIFF_INSERT, textInsert ]\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tpointer = pointer - countDelete - countInsert +\n\t\t\t\t\t\t( countDelete ? 1 : 0 ) + ( countInsert ? 1 : 0 ) + 1;\n\t\t\t\t} else if ( pointer !== 0 && diffs[ pointer - 1 ][ 0 ] === DIFF_EQUAL ) {\n\n\t\t\t\t\t// Merge this equality with the previous one.\n\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] += diffs[ pointer ][ 1 ];\n\t\t\t\t\tdiffs.splice( pointer, 1 );\n\t\t\t\t} else {\n\t\t\t\t\tpointer++;\n\t\t\t\t}\n\t\t\t\tcountInsert = 0;\n\t\t\t\tcountDelete = 0;\n\t\t\t\ttextDelete = \"\";\n\t\t\t\ttextInsert = \"\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif ( diffs[ diffs.length - 1 ][ 1 ] === \"\" ) {\n\t\t\tdiffs.pop(); // Remove the dummy entry at the end.\n\t\t}\n\n\t\t// Second pass: look for single edits surrounded on both sides by equalities\n\t\t// which can be shifted sideways to eliminate an equality.\n\t\t// e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC\n\t\tchanges = false;\n\t\tpointer = 1;\n\n\t\t// Intentionally ignore the first and last element (don't need checking).\n\t\twhile ( pointer < diffs.length - 1 ) {\n\t\t\tif ( diffs[ pointer - 1 ][ 0 ] === DIFF_EQUAL &&\n\t\t\t\t\tdiffs[ pointer + 1 ][ 0 ] === DIFF_EQUAL ) {\n\n\t\t\t\tdiffPointer = diffs[ pointer ][ 1 ];\n\t\t\t\tposition = diffPointer.substring(\n\t\t\t\t\tdiffPointer.length - diffs[ pointer - 1 ][ 1 ].length\n\t\t\t\t);\n\n\t\t\t\t// This is a single edit surrounded by equalities.\n\t\t\t\tif ( position === diffs[ pointer - 1 ][ 1 ] ) {\n\n\t\t\t\t\t// Shift the edit over the previous equality.\n\t\t\t\t\tdiffs[ pointer ][ 1 ] = diffs[ pointer - 1 ][ 1 ] +\n\t\t\t\t\t\tdiffs[ pointer ][ 1 ].substring( 0, diffs[ pointer ][ 1 ].length -\n\t\t\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ].length );\n\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ] =\n\t\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] + diffs[ pointer + 1 ][ 1 ];\n\t\t\t\t\tdiffs.splice( pointer - 1, 1 );\n\t\t\t\t\tchanges = true;\n\t\t\t\t} else if ( diffPointer.substring( 0, diffs[ pointer + 1 ][ 1 ].length ) ===\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ] ) {\n\n\t\t\t\t\t// Shift the edit over the next equality.\n\t\t\t\t\tdiffs[ pointer - 1 ][ 1 ] += diffs[ pointer + 1 ][ 1 ];\n\t\t\t\t\tdiffs[ pointer ][ 1 ] =\n\t\t\t\t\t\tdiffs[ pointer ][ 1 ].substring( diffs[ pointer + 1 ][ 1 ].length ) +\n\t\t\t\t\t\tdiffs[ pointer + 1 ][ 1 ];\n\t\t\t\t\tdiffs.splice( pointer + 1, 1 );\n\t\t\t\t\tchanges = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpointer++;\n\t\t}\n\t\t// If shifts were made, the diff needs reordering and another shift sweep.\n\t\tif ( changes ) {\n\t\t\tthis.diffCleanupMerge( diffs );\n\t\t}\n\t};\n\n\treturn function( o, n ) {\n\t\tvar diff, output, text;\n\t\tdiff = new DiffMatchPatch();\n\t\toutput = diff.DiffMain( o, n );\n\t\tdiff.diffCleanupEfficiency( output );\n\t\ttext = diff.diffPrettyHtml( output );\n\n\t\treturn text;\n\t};\n}() );\n\n// Get a reference to the global object, like window in browsers\n}( (function() {\n\treturn this;\n})() ));\n\n(function() {\n\n// Don't load the HTML Reporter on non-Browser environments\nif ( typeof window === \"undefined\" || !window.document ) {\n\treturn;\n}\n\n// Deprecated QUnit.init - Ref #530\n// Re-initialize the configuration options\nQUnit.init = function() {\n\tvar tests, banner, result, qunit,\n\t\tconfig = QUnit.config;\n\n\tconfig.stats = { all: 0, bad: 0 };\n\tconfig.moduleStats = { all: 0, bad: 0 };\n\tconfig.started = 0;\n\tconfig.updateRate = 1000;\n\tconfig.blocking = false;\n\tconfig.autostart = true;\n\tconfig.autorun = false;\n\tconfig.filter = \"\";\n\tconfig.queue = [];\n\n\t// Return on non-browser environments\n\t// This is necessary to not break on node tests\n\tif ( typeof window === \"undefined\" ) {\n\t\treturn;\n\t}\n\n\tqunit = id( \"qunit\" );\n\tif ( qunit ) {\n\t\tqunit.innerHTML =\n\t\t\t\"<h1 id='qunit-header'>\" + escapeText( document.title ) + \"</h1>\" +\n\t\t\t\"<h2 id='qunit-banner'></h2>\" +\n\t\t\t\"<div id='qunit-testrunner-toolbar'></div>\" +\n\t\t\t\"<h2 id='qunit-userAgent'></h2>\" +\n\t\t\t\"<ol id='qunit-tests'></ol>\";\n\t}\n\n\ttests = id( \"qunit-tests\" );\n\tbanner = id( \"qunit-banner\" );\n\tresult = id( \"qunit-testresult\" );\n\n\tif ( tests ) {\n\t\ttests.innerHTML = \"\";\n\t}\n\n\tif ( banner ) {\n\t\tbanner.className = \"\";\n\t}\n\n\tif ( result ) {\n\t\tresult.parentNode.removeChild( result );\n\t}\n\n\tif ( tests ) {\n\t\tresult = document.createElement( \"p\" );\n\t\tresult.id = \"qunit-testresult\";\n\t\tresult.className = \"result\";\n\t\ttests.parentNode.insertBefore( result, tests );\n\t\tresult.innerHTML = \"Running...<br />&#160;\";\n\t}\n};\n\nvar config = QUnit.config,\n\tcollapseNext = false,\n\thasOwn = Object.prototype.hasOwnProperty,\n\tdefined = {\n\t\tdocument: window.document !== undefined,\n\t\tsessionStorage: (function() {\n\t\t\tvar x = \"qunit-test-string\";\n\t\t\ttry {\n\t\t\t\tsessionStorage.setItem( x, x );\n\t\t\t\tsessionStorage.removeItem( x );\n\t\t\t\treturn true;\n\t\t\t} catch ( e ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}())\n\t},\n\tmodulesList = [];\n\n/**\n* Escape text for attribute or text content.\n*/\nfunction escapeText( s ) {\n\tif ( !s ) {\n\t\treturn \"\";\n\t}\n\ts = s + \"\";\n\n\t// Both single quotes and double quotes (for attributes)\n\treturn s.replace( /['\"<>&]/g, function( s ) {\n\t\tswitch ( s ) {\n\t\tcase \"'\":\n\t\t\treturn \"&#039;\";\n\t\tcase \"\\\"\":\n\t\t\treturn \"&quot;\";\n\t\tcase \"<\":\n\t\t\treturn \"&lt;\";\n\t\tcase \">\":\n\t\t\treturn \"&gt;\";\n\t\tcase \"&\":\n\t\t\treturn \"&amp;\";\n\t\t}\n\t});\n}\n\n/**\n * @param {HTMLElement} elem\n * @param {string} type\n * @param {Function} fn\n */\nfunction addEvent( elem, type, fn ) {\n\tif ( elem.addEventListener ) {\n\n\t\t// Standards-based browsers\n\t\telem.addEventListener( type, fn, false );\n\t} else if ( elem.attachEvent ) {\n\n\t\t// support: IE <9\n\t\telem.attachEvent( \"on\" + type, function() {\n\t\t\tvar event = window.event;\n\t\t\tif ( !event.target ) {\n\t\t\t\tevent.target = event.srcElement || document;\n\t\t\t}\n\n\t\t\tfn.call( elem, event );\n\t\t});\n\t}\n}\n\n/**\n * @param {Array|NodeList} elems\n * @param {string} type\n * @param {Function} fn\n */\nfunction addEvents( elems, type, fn ) {\n\tvar i = elems.length;\n\twhile ( i-- ) {\n\t\taddEvent( elems[ i ], type, fn );\n\t}\n}\n\nfunction hasClass( elem, name ) {\n\treturn ( \" \" + elem.className + \" \" ).indexOf( \" \" + name + \" \" ) >= 0;\n}\n\nfunction addClass( elem, name ) {\n\tif ( !hasClass( elem, name ) ) {\n\t\telem.className += ( elem.className ? \" \" : \"\" ) + name;\n\t}\n}\n\nfunction toggleClass( elem, name ) {\n\tif ( hasClass( elem, name ) ) {\n\t\tremoveClass( elem, name );\n\t} else {\n\t\taddClass( elem, name );\n\t}\n}\n\nfunction removeClass( elem, name ) {\n\tvar set = \" \" + elem.className + \" \";\n\n\t// Class name may appear multiple times\n\twhile ( set.indexOf( \" \" + name + \" \" ) >= 0 ) {\n\t\tset = set.replace( \" \" + name + \" \", \" \" );\n\t}\n\n\t// trim for prettiness\n\telem.className = typeof set.trim === \"function\" ? set.trim() : set.replace( /^\\s+|\\s+$/g, \"\" );\n}\n\nfunction id( name ) {\n\treturn defined.document && document.getElementById && document.getElementById( name );\n}\n\nfunction getUrlConfigHtml() {\n\tvar i, j, val,\n\t\tescaped, escapedTooltip,\n\t\tselection = false,\n\t\tlen = config.urlConfig.length,\n\t\turlConfigHtml = \"\";\n\n\tfor ( i = 0; i < len; i++ ) {\n\t\tval = config.urlConfig[ i ];\n\t\tif ( typeof val === \"string\" ) {\n\t\t\tval = {\n\t\t\t\tid: val,\n\t\t\t\tlabel: val\n\t\t\t};\n\t\t}\n\n\t\tescaped = escapeText( val.id );\n\t\tescapedTooltip = escapeText( val.tooltip );\n\n\t\tif ( config[ val.id ] === undefined ) {\n\t\t\tconfig[ val.id ] = QUnit.urlParams[ val.id ];\n\t\t}\n\n\t\tif ( !val.value || typeof val.value === \"string\" ) {\n\t\t\turlConfigHtml += \"<input id='qunit-urlconfig-\" + escaped +\n\t\t\t\t\"' name='\" + escaped + \"' type='checkbox'\" +\n\t\t\t\t( val.value ? \" value='\" + escapeText( val.value ) + \"'\" : \"\" ) +\n\t\t\t\t( config[ val.id ] ? \" checked='checked'\" : \"\" ) +\n\t\t\t\t\" title='\" + escapedTooltip + \"' /><label for='qunit-urlconfig-\" + escaped +\n\t\t\t\t\"' title='\" + escapedTooltip + \"'>\" + val.label + \"</label>\";\n\t\t} else {\n\t\t\turlConfigHtml += \"<label for='qunit-urlconfig-\" + escaped +\n\t\t\t\t\"' title='\" + escapedTooltip + \"'>\" + val.label +\n\t\t\t\t\": </label><select id='qunit-urlconfig-\" + escaped +\n\t\t\t\t\"' name='\" + escaped + \"' title='\" + escapedTooltip + \"'><option></option>\";\n\n\t\t\tif ( QUnit.is( \"array\", val.value ) ) {\n\t\t\t\tfor ( j = 0; j < val.value.length; j++ ) {\n\t\t\t\t\tescaped = escapeText( val.value[ j ] );\n\t\t\t\t\turlConfigHtml += \"<option value='\" + escaped + \"'\" +\n\t\t\t\t\t\t( config[ val.id ] === val.value[ j ] ?\n\t\t\t\t\t\t\t( selection = true ) && \" selected='selected'\" : \"\" ) +\n\t\t\t\t\t\t\">\" + escaped + \"</option>\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( j in val.value ) {\n\t\t\t\t\tif ( hasOwn.call( val.value, j ) ) {\n\t\t\t\t\t\turlConfigHtml += \"<option value='\" + escapeText( j ) + \"'\" +\n\t\t\t\t\t\t\t( config[ val.id ] === j ?\n\t\t\t\t\t\t\t\t( selection = true ) && \" selected='selected'\" : \"\" ) +\n\t\t\t\t\t\t\t\">\" + escapeText( val.value[ j ] ) + \"</option>\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( config[ val.id ] && !selection ) {\n\t\t\t\tescaped = escapeText( config[ val.id ] );\n\t\t\t\turlConfigHtml += \"<option value='\" + escaped +\n\t\t\t\t\t\"' selected='selected' disabled='disabled'>\" + escaped + \"</option>\";\n\t\t\t}\n\t\t\turlConfigHtml += \"</select>\";\n\t\t}\n\t}\n\n\treturn urlConfigHtml;\n}\n\n// Handle \"click\" events on toolbar checkboxes and \"change\" for select menus.\n// Updates the URL with the new state of `config.urlConfig` values.\nfunction toolbarChanged() {\n\tvar updatedUrl, value,\n\t\tfield = this,\n\t\tparams = {};\n\n\t// Detect if field is a select menu or a checkbox\n\tif ( \"selectedIndex\" in field ) {\n\t\tvalue = field.options[ field.selectedIndex ].value || undefined;\n\t} else {\n\t\tvalue = field.checked ? ( field.defaultValue || true ) : undefined;\n\t}\n\n\tparams[ field.name ] = value;\n\tupdatedUrl = setUrl( params );\n\n\tif ( \"hidepassed\" === field.name && \"replaceState\" in window.history ) {\n\t\tconfig[ field.name ] = value || false;\n\t\tif ( value ) {\n\t\t\taddClass( id( \"qunit-tests\" ), \"hidepass\" );\n\t\t} else {\n\t\t\tremoveClass( id( \"qunit-tests\" ), \"hidepass\" );\n\t\t}\n\n\t\t// It is not necessary to refresh the whole page\n\t\twindow.history.replaceState( null, \"\", updatedUrl );\n\t} else {\n\t\twindow.location = updatedUrl;\n\t}\n}\n\nfunction setUrl( params ) {\n\tvar key,\n\t\tquerystring = \"?\";\n\n\tparams = QUnit.extend( QUnit.extend( {}, QUnit.urlParams ), params );\n\n\tfor ( key in params ) {\n\t\tif ( hasOwn.call( params, key ) ) {\n\t\t\tif ( params[ key ] === undefined ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tquerystring += encodeURIComponent( key );\n\t\t\tif ( params[ key ] !== true ) {\n\t\t\t\tquerystring += \"=\" + encodeURIComponent( params[ key ] );\n\t\t\t}\n\t\t\tquerystring += \"&\";\n\t\t}\n\t}\n\treturn location.protocol + \"//\" + location.host +\n\t\tlocation.pathname + querystring.slice( 0, -1 );\n}\n\nfunction applyUrlParams() {\n\tvar selectedModule,\n\t\tmodulesList = id( \"qunit-modulefilter\" ),\n\t\tfilter = id( \"qunit-filter-input\" ).value;\n\n\tselectedModule = modulesList ?\n\t\tdecodeURIComponent( modulesList.options[ modulesList.selectedIndex ].value ) :\n\t\tundefined;\n\n\twindow.location = setUrl({\n\t\tmodule: ( selectedModule === \"\" ) ? undefined : selectedModule,\n\t\tfilter: ( filter === \"\" ) ? undefined : filter,\n\n\t\t// Remove testId filter\n\t\ttestId: undefined\n\t});\n}\n\nfunction toolbarUrlConfigContainer() {\n\tvar urlConfigContainer = document.createElement( \"span\" );\n\n\turlConfigContainer.innerHTML = getUrlConfigHtml();\n\taddClass( urlConfigContainer, \"qunit-url-config\" );\n\n\t// For oldIE support:\n\t// * Add handlers to the individual elements instead of the container\n\t// * Use \"click\" instead of \"change\" for checkboxes\n\taddEvents( urlConfigContainer.getElementsByTagName( \"input\" ), \"click\", toolbarChanged );\n\taddEvents( urlConfigContainer.getElementsByTagName( \"select\" ), \"change\", toolbarChanged );\n\n\treturn urlConfigContainer;\n}\n\nfunction toolbarLooseFilter() {\n\tvar filter = document.createElement( \"form\" ),\n\t\tlabel = document.createElement( \"label\" ),\n\t\tinput = document.createElement( \"input\" ),\n\t\tbutton = document.createElement( \"button\" );\n\n\taddClass( filter, \"qunit-filter\" );\n\n\tlabel.innerHTML = \"Filter: \";\n\n\tinput.type = \"text\";\n\tinput.value = config.filter || \"\";\n\tinput.name = \"filter\";\n\tinput.id = \"qunit-filter-input\";\n\n\tbutton.innerHTML = \"Go\";\n\n\tlabel.appendChild( input );\n\n\tfilter.appendChild( label );\n\tfilter.appendChild( button );\n\taddEvent( filter, \"submit\", function( ev ) {\n\t\tapplyUrlParams();\n\n\t\tif ( ev && ev.preventDefault ) {\n\t\t\tev.preventDefault();\n\t\t}\n\n\t\treturn false;\n\t});\n\n\treturn filter;\n}\n\nfunction toolbarModuleFilterHtml() {\n\tvar i,\n\t\tmoduleFilterHtml = \"\";\n\n\tif ( !modulesList.length ) {\n\t\treturn false;\n\t}\n\n\tmodulesList.sort(function( a, b ) {\n\t\treturn a.localeCompare( b );\n\t});\n\n\tmoduleFilterHtml += \"<label for='qunit-modulefilter'>Module: </label>\" +\n\t\t\"<select id='qunit-modulefilter' name='modulefilter'><option value='' \" +\n\t\t( QUnit.urlParams.module === undefined ? \"selected='selected'\" : \"\" ) +\n\t\t\">< All Modules ></option>\";\n\n\tfor ( i = 0; i < modulesList.length; i++ ) {\n\t\tmoduleFilterHtml += \"<option value='\" +\n\t\t\tescapeText( encodeURIComponent( modulesList[ i ] ) ) + \"' \" +\n\t\t\t( QUnit.urlParams.module === modulesList[ i ] ? \"selected='selected'\" : \"\" ) +\n\t\t\t\">\" + escapeText( modulesList[ i ] ) + \"</option>\";\n\t}\n\tmoduleFilterHtml += \"</select>\";\n\n\treturn moduleFilterHtml;\n}\n\nfunction toolbarModuleFilter() {\n\tvar toolbar = id( \"qunit-testrunner-toolbar\" ),\n\t\tmoduleFilter = document.createElement( \"span\" ),\n\t\tmoduleFilterHtml = toolbarModuleFilterHtml();\n\n\tif ( !toolbar || !moduleFilterHtml ) {\n\t\treturn false;\n\t}\n\n\tmoduleFilter.setAttribute( \"id\", \"qunit-modulefilter-container\" );\n\tmoduleFilter.innerHTML = moduleFilterHtml;\n\n\taddEvent( moduleFilter.lastChild, \"change\", applyUrlParams );\n\n\ttoolbar.appendChild( moduleFilter );\n}\n\nfunction appendToolbar() {\n\tvar toolbar = id( \"qunit-testrunner-toolbar\" );\n\n\tif ( toolbar ) {\n\t\ttoolbar.appendChild( toolbarUrlConfigContainer() );\n\t\ttoolbar.appendChild( toolbarLooseFilter() );\n\t}\n}\n\nfunction appendHeader() {\n\tvar header = id( \"qunit-header\" );\n\n\tif ( header ) {\n\t\theader.innerHTML = \"<a href='\" +\n\t\t\tsetUrl({ filter: undefined, module: undefined, testId: undefined }) +\n\t\t\t\"'>\" + header.innerHTML + \"</a> \";\n\t}\n}\n\nfunction appendBanner() {\n\tvar banner = id( \"qunit-banner\" );\n\n\tif ( banner ) {\n\t\tbanner.className = \"\";\n\t}\n}\n\nfunction appendTestResults() {\n\tvar tests = id( \"qunit-tests\" ),\n\t\tresult = id( \"qunit-testresult\" );\n\n\tif ( result ) {\n\t\tresult.parentNode.removeChild( result );\n\t}\n\n\tif ( tests ) {\n\t\ttests.innerHTML = \"\";\n\t\tresult = document.createElement( \"p\" );\n\t\tresult.id = \"qunit-testresult\";\n\t\tresult.className = \"result\";\n\t\ttests.parentNode.insertBefore( result, tests );\n\t\tresult.innerHTML = \"Running...<br />&#160;\";\n\t}\n}\n\nfunction storeFixture() {\n\tvar fixture = id( \"qunit-fixture\" );\n\tif ( fixture ) {\n\t\tconfig.fixture = fixture.innerHTML;\n\t}\n}\n\nfunction appendFilteredTest() {\n\tvar testId = QUnit.config.testId;\n\tif ( !testId || testId.length <= 0 ) {\n\t\treturn \"\";\n\t}\n\treturn \"<div id='qunit-filteredTest'>Rerunning selected tests: \" + testId.join(\", \") +\n\t\t\" <a id='qunit-clearFilter' href='\" +\n\t\tsetUrl({ filter: undefined, module: undefined, testId: undefined }) +\n\t\t\"'>\" + \"Run all tests\" + \"</a></div>\";\n}\n\nfunction appendUserAgent() {\n\tvar userAgent = id( \"qunit-userAgent\" );\n\n\tif ( userAgent ) {\n\t\tuserAgent.innerHTML = \"\";\n\t\tuserAgent.appendChild(\n\t\t\tdocument.createTextNode(\n\t\t\t\t\"QUnit \" + QUnit.version + \"; \" + navigator.userAgent\n\t\t\t)\n\t\t);\n\t}\n}\n\nfunction appendTestsList( modules ) {\n\tvar i, l, x, z, test, moduleObj;\n\n\tfor ( i = 0, l = modules.length; i < l; i++ ) {\n\t\tmoduleObj = modules[ i ];\n\n\t\tif ( moduleObj.name ) {\n\t\t\tmodulesList.push( moduleObj.name );\n\t\t}\n\n\t\tfor ( x = 0, z = moduleObj.tests.length; x < z; x++ ) {\n\t\t\ttest = moduleObj.tests[ x ];\n\n\t\t\tappendTest( test.name, test.testId, moduleObj.name );\n\t\t}\n\t}\n}\n\nfunction appendTest( name, testId, moduleName ) {\n\tvar title, rerunTrigger, testBlock, assertList,\n\t\ttests = id( \"qunit-tests\" );\n\n\tif ( !tests ) {\n\t\treturn;\n\t}\n\n\ttitle = document.createElement( \"strong\" );\n\ttitle.innerHTML = getNameHtml( name, moduleName );\n\n\trerunTrigger = document.createElement( \"a\" );\n\trerunTrigger.innerHTML = \"Rerun\";\n\trerunTrigger.href = setUrl({ testId: testId });\n\n\ttestBlock = document.createElement( \"li\" );\n\ttestBlock.appendChild( title );\n\ttestBlock.appendChild( rerunTrigger );\n\ttestBlock.id = \"qunit-test-output-\" + testId;\n\n\tassertList = document.createElement( \"ol\" );\n\tassertList.className = \"qunit-assert-list\";\n\n\ttestBlock.appendChild( assertList );\n\n\ttests.appendChild( testBlock );\n}\n\n// HTML Reporter initialization and load\nQUnit.begin(function( details ) {\n\tvar qunit = id( \"qunit\" );\n\n\t// Fixture is the only one necessary to run without the #qunit element\n\tstoreFixture();\n\n\tif ( qunit ) {\n\t\tqunit.innerHTML =\n\t\t\t\"<h1 id='qunit-header'>\" + escapeText( document.title ) + \"</h1>\" +\n\t\t\t\"<h2 id='qunit-banner'></h2>\" +\n\t\t\t\"<div id='qunit-testrunner-toolbar'></div>\" +\n\t\t\tappendFilteredTest() +\n\t\t\t\"<h2 id='qunit-userAgent'></h2>\" +\n\t\t\t\"<ol id='qunit-tests'></ol>\";\n\t}\n\n\tappendHeader();\n\tappendBanner();\n\tappendTestResults();\n\tappendUserAgent();\n\tappendToolbar();\n\tappendTestsList( details.modules );\n\ttoolbarModuleFilter();\n\n\tif ( qunit && config.hidepassed ) {\n\t\taddClass( qunit.lastChild, \"hidepass\" );\n\t}\n});\n\nQUnit.done(function( details ) {\n\tvar i, key,\n\t\tbanner = id( \"qunit-banner\" ),\n\t\ttests = id( \"qunit-tests\" ),\n\t\thtml = [\n\t\t\t\"Tests completed in \",\n\t\t\tdetails.runtime,\n\t\t\t\" milliseconds.<br />\",\n\t\t\t\"<span class='passed'>\",\n\t\t\tdetails.passed,\n\t\t\t\"</span> assertions of <span class='total'>\",\n\t\t\tdetails.total,\n\t\t\t\"</span> passed, <span class='failed'>\",\n\t\t\tdetails.failed,\n\t\t\t\"</span> failed.\"\n\t\t].join( \"\" );\n\n\tif ( banner ) {\n\t\tbanner.className = details.failed ? \"qunit-fail\" : \"qunit-pass\";\n\t}\n\n\tif ( tests ) {\n\t\tid( \"qunit-testresult\" ).innerHTML = html;\n\t}\n\n\tif ( config.altertitle && defined.document && document.title ) {\n\n\t\t// show ✖ for good, ✔ for bad suite result in title\n\t\t// use escape sequences in case file gets loaded with non-utf-8-charset\n\t\tdocument.title = [\n\t\t\t( details.failed ? \"\\u2716\" : \"\\u2714\" ),\n\t\t\tdocument.title.replace( /^[\\u2714\\u2716] /i, \"\" )\n\t\t].join( \" \" );\n\t}\n\n\t// clear own sessionStorage items if all tests passed\n\tif ( config.reorder && defined.sessionStorage && details.failed === 0 ) {\n\t\tfor ( i = 0; i < sessionStorage.length; i++ ) {\n\t\t\tkey = sessionStorage.key( i++ );\n\t\t\tif ( key.indexOf( \"qunit-test-\" ) === 0 ) {\n\t\t\t\tsessionStorage.removeItem( key );\n\t\t\t}\n\t\t}\n\t}\n\n\t// scroll back to top to show results\n\tif ( config.scrolltop && window.scrollTo ) {\n\t\twindow.scrollTo( 0, 0 );\n\t}\n});\n\nfunction getNameHtml( name, module ) {\n\tvar nameHtml = \"\";\n\n\tif ( module ) {\n\t\tnameHtml = \"<span class='module-name'>\" + escapeText( module ) + \"</span>: \";\n\t}\n\n\tnameHtml += \"<span class='test-name'>\" + escapeText( name ) + \"</span>\";\n\n\treturn nameHtml;\n}\n\nQUnit.testStart(function( details ) {\n\tvar running, testBlock, bad;\n\n\ttestBlock = id( \"qunit-test-output-\" + details.testId );\n\tif ( testBlock ) {\n\t\ttestBlock.className = \"running\";\n\t} else {\n\n\t\t// Report later registered tests\n\t\tappendTest( details.name, details.testId, details.module );\n\t}\n\n\trunning = id( \"qunit-testresult\" );\n\tif ( running ) {\n\t\tbad = QUnit.config.reorder && defined.sessionStorage &&\n\t\t\t+sessionStorage.getItem( \"qunit-test-\" + details.module + \"-\" + details.name );\n\n\t\trunning.innerHTML = ( bad ?\n\t\t\t\"Rerunning previously failed test: <br />\" :\n\t\t\t\"Running: <br />\" ) +\n\t\t\tgetNameHtml( details.name, details.module );\n\t}\n\n});\n\nfunction stripHtml( string ) {\n\t// strip tags, html entity and whitespaces\n\treturn string.replace(/<\\/?[^>]+(>|$)/g, \"\").replace(/\\&quot;/g, \"\").replace(/\\s+/g, \"\");\n}\n\nQUnit.log(function( details ) {\n\tvar assertList, assertLi,\n\t\tmessage, expected, actual, diff,\n\t\tshowDiff = false,\n\t\ttestItem = id( \"qunit-test-output-\" + details.testId );\n\n\tif ( !testItem ) {\n\t\treturn;\n\t}\n\n\tmessage = escapeText( details.message ) || ( details.result ? \"okay\" : \"failed\" );\n\tmessage = \"<span class='test-message'>\" + message + \"</span>\";\n\tmessage += \"<span class='runtime'>@ \" + details.runtime + \" ms</span>\";\n\n\t// pushFailure doesn't provide details.expected\n\t// when it calls, it's implicit to also not show expected and diff stuff\n\t// Also, we need to check details.expected existence, as it can exist and be undefined\n\tif ( !details.result && hasOwn.call( details, \"expected\" ) ) {\n\t\tif ( details.negative ) {\n\t\t\texpected = escapeText( \"NOT \" + QUnit.dump.parse( details.expected ) );\n\t\t} else {\n\t\t\texpected = escapeText( QUnit.dump.parse( details.expected ) );\n\t\t}\n\n\t\tactual = escapeText( QUnit.dump.parse( details.actual ) );\n\t\tmessage += \"<table><tr class='test-expected'><th>Expected: </th><td><pre>\" +\n\t\t\texpected +\n\t\t\t\"</pre></td></tr>\";\n\n\t\tif ( actual !== expected ) {\n\n\t\t\tmessage += \"<tr class='test-actual'><th>Result: </th><td><pre>\" +\n\t\t\t\tactual + \"</pre></td></tr>\";\n\n\t\t\t// Don't show diff if actual or expected are booleans\n\t\t\tif ( !( /^(true|false)$/.test( actual ) ) &&\n\t\t\t\t\t!( /^(true|false)$/.test( expected ) ) ) {\n\t\t\t\tdiff = QUnit.diff( expected, actual );\n\t\t\t\tshowDiff = stripHtml( diff ).length !==\n\t\t\t\t\tstripHtml( expected ).length +\n\t\t\t\t\tstripHtml( actual ).length;\n\t\t\t}\n\n\t\t\t// Don't show diff if expected and actual are totally different\n\t\t\tif ( showDiff ) {\n\t\t\t\tmessage += \"<tr class='test-diff'><th>Diff: </th><td><pre>\" +\n\t\t\t\t\tdiff + \"</pre></td></tr>\";\n\t\t\t}\n\t\t} else if ( expected.indexOf( \"[object Array]\" ) !== -1 ||\n\t\t\t\texpected.indexOf( \"[object Object]\" ) !== -1 ) {\n\t\t\tmessage += \"<tr class='test-message'><th>Message: </th><td>\" +\n\t\t\t\t\"Diff suppressed as the depth of object is more than current max depth (\" +\n\t\t\t\tQUnit.config.maxDepth + \").<p>Hint: Use <code>QUnit.dump.maxDepth</code> to \" +\n\t\t\t\t\" run with a higher max depth or <a href='\" + setUrl({ maxDepth: -1 }) + \"'>\" +\n\t\t\t\t\"Rerun</a> without max depth.</p></td></tr>\";\n\t\t}\n\n\t\tif ( details.source ) {\n\t\t\tmessage += \"<tr class='test-source'><th>Source: </th><td><pre>\" +\n\t\t\t\tescapeText( details.source ) + \"</pre></td></tr>\";\n\t\t}\n\n\t\tmessage += \"</table>\";\n\n\t// this occurs when pushFailure is set and we have an extracted stack trace\n\t} else if ( !details.result && details.source ) {\n\t\tmessage += \"<table>\" +\n\t\t\t\"<tr class='test-source'><th>Source: </th><td><pre>\" +\n\t\t\tescapeText( details.source ) + \"</pre></td></tr>\" +\n\t\t\t\"</table>\";\n\t}\n\n\tassertList = testItem.getElementsByTagName( \"ol\" )[ 0 ];\n\n\tassertLi = document.createElement( \"li\" );\n\tassertLi.className = details.result ? \"pass\" : \"fail\";\n\tassertLi.innerHTML = message;\n\tassertList.appendChild( assertLi );\n});\n\nQUnit.testDone(function( details ) {\n\tvar testTitle, time, testItem, assertList,\n\t\tgood, bad, testCounts, skipped, sourceName,\n\t\ttests = id( \"qunit-tests\" );\n\n\tif ( !tests ) {\n\t\treturn;\n\t}\n\n\ttestItem = id( \"qunit-test-output-\" + details.testId );\n\n\tassertList = testItem.getElementsByTagName( \"ol\" )[ 0 ];\n\n\tgood = details.passed;\n\tbad = details.failed;\n\n\t// store result when possible\n\tif ( config.reorder && defined.sessionStorage ) {\n\t\tif ( bad ) {\n\t\t\tsessionStorage.setItem( \"qunit-test-\" + details.module + \"-\" + details.name, bad );\n\t\t} else {\n\t\t\tsessionStorage.removeItem( \"qunit-test-\" + details.module + \"-\" + details.name );\n\t\t}\n\t}\n\n\tif ( bad === 0 ) {\n\n\t\t// Collapse the passing tests\n\t\taddClass( assertList, \"qunit-collapsed\" );\n\t} else if ( bad && config.collapse && !collapseNext ) {\n\n\t\t// Skip collapsing the first failing test\n\t\tcollapseNext = true;\n\t} else {\n\n\t\t// Collapse remaining tests\n\t\taddClass( assertList, \"qunit-collapsed\" );\n\t}\n\n\t// testItem.firstChild is the test name\n\ttestTitle = testItem.firstChild;\n\n\ttestCounts = bad ?\n\t\t\"<b class='failed'>\" + bad + \"</b>, \" + \"<b class='passed'>\" + good + \"</b>, \" :\n\t\t\"\";\n\n\ttestTitle.innerHTML += \" <b class='counts'>(\" + testCounts +\n\t\tdetails.assertions.length + \")</b>\";\n\n\tif ( details.skipped ) {\n\t\ttestItem.className = \"skipped\";\n\t\tskipped = document.createElement( \"em\" );\n\t\tskipped.className = \"qunit-skipped-label\";\n\t\tskipped.innerHTML = \"skipped\";\n\t\ttestItem.insertBefore( skipped, testTitle );\n\t} else {\n\t\taddEvent( testTitle, \"click\", function() {\n\t\t\ttoggleClass( assertList, \"qunit-collapsed\" );\n\t\t});\n\n\t\ttestItem.className = bad ? \"fail\" : \"pass\";\n\n\t\ttime = document.createElement( \"span\" );\n\t\ttime.className = \"runtime\";\n\t\ttime.innerHTML = details.runtime + \" ms\";\n\t\ttestItem.insertBefore( time, assertList );\n\t}\n\n\t// Show the source of the test when showing assertions\n\tif ( details.source ) {\n\t\tsourceName = document.createElement( \"p\" );\n\t\tsourceName.innerHTML = \"<strong>Source: </strong>\" + details.source;\n\t\taddClass( sourceName, \"qunit-source\" );\n\t\tif ( bad === 0 ) {\n\t\t\taddClass( sourceName, \"qunit-collapsed\" );\n\t\t}\n\t\taddEvent( testTitle, \"click\", function() {\n\t\t\ttoggleClass( sourceName, \"qunit-collapsed\" );\n\t\t});\n\t\ttestItem.appendChild( sourceName );\n\t}\n});\n\nif ( defined.document ) {\n\n\t// Avoid readyState issue with phantomjs\n\t// Ref: #818\n\tvar notPhantom = ( function( p ) {\n\t\treturn !( p && p.version && p.version.major > 0 );\n\t} )( window.phantom );\n\n\tif ( notPhantom && document.readyState === \"complete\" ) {\n\t\tQUnit.load();\n\t} else {\n\t\taddEvent( window, \"load\", QUnit.load );\n\t}\n} else {\n\tconfig.pageLoaded = true;\n\tconfig.autorun = true;\n}\n\n})();\n"
  },
  {
    "path": "test/vendor/require.js",
    "content": "/** vim: et:ts=4:sw=4:sts=4\n * @license RequireJS 2.1.9 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/jrburke/requirejs for details\n */\n//Not using strict: uneven strict support in browsers, #392, and causes\n//problems with requirejs.exec()/transpiler plugins that may not be strict.\n/*jslint regexp: true, nomen: true, sloppy: true */\n/*global window, navigator, document, importScripts, setTimeout, opera */\n\nvar requirejs, require, define;\n(function (global) {\n    var req, s, head, baseElement, dataMain, src,\n        interactiveScript, currentlyAddingScript, mainScript, subPath,\n        version = '2.1.9',\n        commentRegExp = /(\\/\\*([\\s\\S]*?)\\*\\/|([^:]|^)\\/\\/(.*)$)/mg,\n        cjsRequireRegExp = /[^.]\\s*require\\s*\\(\\s*[\"']([^'\"\\s]+)[\"']\\s*\\)/g,\n        jsSuffixRegExp = /\\.js$/,\n        currDirRegExp = /^\\.\\//,\n        op = Object.prototype,\n        ostring = op.toString,\n        hasOwn = op.hasOwnProperty,\n        ap = Array.prototype,\n        apsp = ap.splice,\n        isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document),\n        isWebWorker = !isBrowser && typeof importScripts !== 'undefined',\n        //PS3 indicates loaded and complete, but need to wait for complete\n        //specifically. Sequence is 'loading', 'loaded', execution,\n        // then 'complete'. The UA check is unfortunate, but not sure how\n        //to feature test w/o causing perf issues.\n        readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?\n                      /^complete$/ : /^(complete|loaded)$/,\n        defContextName = '_',\n        //Oh the tragedy, detecting opera. See the usage of isOpera for reason.\n        isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',\n        contexts = {},\n        cfg = {},\n        globalDefQueue = [],\n        useInteractive = false;\n\n    function isFunction(it) {\n        return ostring.call(it) === '[object Function]';\n    }\n\n    function isArray(it) {\n        return ostring.call(it) === '[object Array]';\n    }\n\n    /**\n     * Helper function for iterating over an array. If the func returns\n     * a true value, it will break out of the loop.\n     */\n    function each(ary, func) {\n        if (ary) {\n            var i;\n            for (i = 0; i < ary.length; i += 1) {\n                if (ary[i] && func(ary[i], i, ary)) {\n                    break;\n                }\n            }\n        }\n    }\n\n    /**\n     * Helper function for iterating over an array backwards. If the func\n     * returns a true value, it will break out of the loop.\n     */\n    function eachReverse(ary, func) {\n        if (ary) {\n            var i;\n            for (i = ary.length - 1; i > -1; i -= 1) {\n                if (ary[i] && func(ary[i], i, ary)) {\n                    break;\n                }\n            }\n        }\n    }\n\n    function hasProp(obj, prop) {\n        return hasOwn.call(obj, prop);\n    }\n\n    function getOwn(obj, prop) {\n        return hasProp(obj, prop) && obj[prop];\n    }\n\n    /**\n     * Cycles over properties in an object and calls a function for each\n     * property value. If the function returns a truthy value, then the\n     * iteration is stopped.\n     */\n    function eachProp(obj, func) {\n        var prop;\n        for (prop in obj) {\n            if (hasProp(obj, prop)) {\n                if (func(obj[prop], prop)) {\n                    break;\n                }\n            }\n        }\n    }\n\n    /**\n     * Simple function to mix in properties from source into target,\n     * but only if target does not already have a property of the same name.\n     */\n    function mixin(target, source, force, deepStringMixin) {\n        if (source) {\n            eachProp(source, function (value, prop) {\n                if (force || !hasProp(target, prop)) {\n                    if (deepStringMixin && typeof value !== 'string') {\n                        if (!target[prop]) {\n                            target[prop] = {};\n                        }\n                        mixin(target[prop], value, force, deepStringMixin);\n                    } else {\n                        target[prop] = value;\n                    }\n                }\n            });\n        }\n        return target;\n    }\n\n    //Similar to Function.prototype.bind, but the 'this' object is specified\n    //first, since it is easier to read/figure out what 'this' will be.\n    function bind(obj, fn) {\n        return function () {\n            return fn.apply(obj, arguments);\n        };\n    }\n\n    function scripts() {\n        return document.getElementsByTagName('script');\n    }\n\n    function defaultOnError(err) {\n        throw err;\n    }\n\n    //Allow getting a global that expressed in\n    //dot notation, like 'a.b.c'.\n    function getGlobal(value) {\n        if (!value) {\n            return value;\n        }\n        var g = global;\n        each(value.split('.'), function (part) {\n            g = g[part];\n        });\n        return g;\n    }\n\n    /**\n     * Constructs an error with a pointer to an URL with more information.\n     * @param {String} id the error ID that maps to an ID on a web page.\n     * @param {String} message human readable error.\n     * @param {Error} [err] the original error, if there is one.\n     *\n     * @returns {Error}\n     */\n    function makeError(id, msg, err, requireModules) {\n        var e = new Error(msg + '\\nhttp://requirejs.org/docs/errors.html#' + id);\n        e.requireType = id;\n        e.requireModules = requireModules;\n        if (err) {\n            e.originalError = err;\n        }\n        return e;\n    }\n\n    if (typeof define !== 'undefined') {\n        //If a define is already in play via another AMD loader,\n        //do not overwrite.\n        return;\n    }\n\n    if (typeof requirejs !== 'undefined') {\n        if (isFunction(requirejs)) {\n            //Do not overwrite and existing requirejs instance.\n            return;\n        }\n        cfg = requirejs;\n        requirejs = undefined;\n    }\n\n    //Allow for a require config object\n    if (typeof require !== 'undefined' && !isFunction(require)) {\n        //assume it is a config object.\n        cfg = require;\n        require = undefined;\n    }\n\n    function newContext(contextName) {\n        var inCheckLoaded, Module, context, handlers,\n            checkLoadedTimeoutId,\n            config = {\n                //Defaults. Do not set a default for map\n                //config to speed up normalize(), which\n                //will run faster if there is no default.\n                waitSeconds: 7,\n                baseUrl: './',\n                paths: {},\n                pkgs: {},\n                shim: {},\n                config: {}\n            },\n            registry = {},\n            //registry of just enabled modules, to speed\n            //cycle breaking code when lots of modules\n            //are registered, but not activated.\n            enabledRegistry = {},\n            undefEvents = {},\n            defQueue = [],\n            defined = {},\n            urlFetched = {},\n            requireCounter = 1,\n            unnormalizedCounter = 1;\n\n        /**\n         * Trims the . and .. from an array of path segments.\n         * It will keep a leading path segment if a .. will become\n         * the first path segment, to help with module name lookups,\n         * which act like paths, but can be remapped. But the end result,\n         * all paths that use this function should look normalized.\n         * NOTE: this method MODIFIES the input array.\n         * @param {Array} ary the array of path segments.\n         */\n        function trimDots(ary) {\n            var i, part;\n            for (i = 0; ary[i]; i += 1) {\n                part = ary[i];\n                if (part === '.') {\n                    ary.splice(i, 1);\n                    i -= 1;\n                } else if (part === '..') {\n                    if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {\n                        //End of the line. Keep at least one non-dot\n                        //path segment at the front so it can be mapped\n                        //correctly to disk. Otherwise, there is likely\n                        //no path mapping for a path starting with '..'.\n                        //This can still fail, but catches the most reasonable\n                        //uses of ..\n                        break;\n                    } else if (i > 0) {\n                        ary.splice(i - 1, 2);\n                        i -= 2;\n                    }\n                }\n            }\n        }\n\n        /**\n         * Given a relative module name, like ./something, normalize it to\n         * a real name that can be mapped to a path.\n         * @param {String} name the relative name\n         * @param {String} baseName a real name that the name arg is relative\n         * to.\n         * @param {Boolean} applyMap apply the map config to the value. Should\n         * only be done if this normalization is for a dependency ID.\n         * @returns {String} normalized name\n         */\n        function normalize(name, baseName, applyMap) {\n            var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment,\n                foundMap, foundI, foundStarMap, starI,\n                baseParts = baseName && baseName.split('/'),\n                normalizedBaseParts = baseParts,\n                map = config.map,\n                starMap = map && map['*'];\n\n            //Adjust any relative paths.\n            if (name && name.charAt(0) === '.') {\n                //If have a base name, try to normalize against it,\n                //otherwise, assume it is a top-level require that will\n                //be relative to baseUrl in the end.\n                if (baseName) {\n                    if (getOwn(config.pkgs, baseName)) {\n                        //If the baseName is a package name, then just treat it as one\n                        //name to concat the name with.\n                        normalizedBaseParts = baseParts = [baseName];\n                    } else {\n                        //Convert baseName to array, and lop off the last part,\n                        //so that . matches that 'directory' and not name of the baseName's\n                        //module. For instance, baseName of 'one/two/three', maps to\n                        //'one/two/three.js', but we want the directory, 'one/two' for\n                        //this normalization.\n                        normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);\n                    }\n\n                    name = normalizedBaseParts.concat(name.split('/'));\n                    trimDots(name);\n\n                    //Some use of packages may use a . path to reference the\n                    //'main' module name, so normalize for that.\n                    pkgConfig = getOwn(config.pkgs, (pkgName = name[0]));\n                    name = name.join('/');\n                    if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {\n                        name = pkgName;\n                    }\n                } else if (name.indexOf('./') === 0) {\n                    // No baseName, so this is ID is resolved relative\n                    // to baseUrl, pull off the leading dot.\n                    name = name.substring(2);\n                }\n            }\n\n            //Apply map config if available.\n            if (applyMap && map && (baseParts || starMap)) {\n                nameParts = name.split('/');\n\n                for (i = nameParts.length; i > 0; i -= 1) {\n                    nameSegment = nameParts.slice(0, i).join('/');\n\n                    if (baseParts) {\n                        //Find the longest baseName segment match in the config.\n                        //So, do joins on the biggest to smallest lengths of baseParts.\n                        for (j = baseParts.length; j > 0; j -= 1) {\n                            mapValue = getOwn(map, baseParts.slice(0, j).join('/'));\n\n                            //baseName segment has config, find if it has one for\n                            //this name.\n                            if (mapValue) {\n                                mapValue = getOwn(mapValue, nameSegment);\n                                if (mapValue) {\n                                    //Match, update name to the new value.\n                                    foundMap = mapValue;\n                                    foundI = i;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n\n                    if (foundMap) {\n                        break;\n                    }\n\n                    //Check for a star map match, but just hold on to it,\n                    //if there is a shorter segment match later in a matching\n                    //config, then favor over this star map.\n                    if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {\n                        foundStarMap = getOwn(starMap, nameSegment);\n                        starI = i;\n                    }\n                }\n\n                if (!foundMap && foundStarMap) {\n                    foundMap = foundStarMap;\n                    foundI = starI;\n                }\n\n                if (foundMap) {\n                    nameParts.splice(0, foundI, foundMap);\n                    name = nameParts.join('/');\n                }\n            }\n\n            return name;\n        }\n\n        function removeScript(name) {\n            if (isBrowser) {\n                each(scripts(), function (scriptNode) {\n                    if (scriptNode.getAttribute('data-requiremodule') === name &&\n                            scriptNode.getAttribute('data-requirecontext') === context.contextName) {\n                        scriptNode.parentNode.removeChild(scriptNode);\n                        return true;\n                    }\n                });\n            }\n        }\n\n        function hasPathFallback(id) {\n            var pathConfig = getOwn(config.paths, id);\n            if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {\n                //Pop off the first array value, since it failed, and\n                //retry\n                pathConfig.shift();\n                context.require.undef(id);\n                context.require([id]);\n                return true;\n            }\n        }\n\n        //Turns a plugin!resource to [plugin, resource]\n        //with the plugin being undefined if the name\n        //did not have a plugin prefix.\n        function splitPrefix(name) {\n            var prefix,\n                index = name ? name.indexOf('!') : -1;\n            if (index > -1) {\n                prefix = name.substring(0, index);\n                name = name.substring(index + 1, name.length);\n            }\n            return [prefix, name];\n        }\n\n        /**\n         * Creates a module mapping that includes plugin prefix, module\n         * name, and path. If parentModuleMap is provided it will\n         * also normalize the name via require.normalize()\n         *\n         * @param {String} name the module name\n         * @param {String} [parentModuleMap] parent module map\n         * for the module name, used to resolve relative names.\n         * @param {Boolean} isNormalized: is the ID already normalized.\n         * This is true if this call is done for a define() module ID.\n         * @param {Boolean} applyMap: apply the map config to the ID.\n         * Should only be true if this map is for a dependency.\n         *\n         * @returns {Object}\n         */\n        function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {\n            var url, pluginModule, suffix, nameParts,\n                prefix = null,\n                parentName = parentModuleMap ? parentModuleMap.name : null,\n                originalName = name,\n                isDefine = true,\n                normalizedName = '';\n\n            //If no name, then it means it is a require call, generate an\n            //internal name.\n            if (!name) {\n                isDefine = false;\n                name = '_@r' + (requireCounter += 1);\n            }\n\n            nameParts = splitPrefix(name);\n            prefix = nameParts[0];\n            name = nameParts[1];\n\n            if (prefix) {\n                prefix = normalize(prefix, parentName, applyMap);\n                pluginModule = getOwn(defined, prefix);\n            }\n\n            //Account for relative paths if there is a base name.\n            if (name) {\n                if (prefix) {\n                    if (pluginModule && pluginModule.normalize) {\n                        //Plugin is loaded, use its normalize method.\n                        normalizedName = pluginModule.normalize(name, function (name) {\n                            return normalize(name, parentName, applyMap);\n                        });\n                    } else {\n                        normalizedName = normalize(name, parentName, applyMap);\n                    }\n                } else {\n                    //A regular module.\n                    normalizedName = normalize(name, parentName, applyMap);\n\n                    //Normalized name may be a plugin ID due to map config\n                    //application in normalize. The map config values must\n                    //already be normalized, so do not need to redo that part.\n                    nameParts = splitPrefix(normalizedName);\n                    prefix = nameParts[0];\n                    normalizedName = nameParts[1];\n                    isNormalized = true;\n\n                    url = context.nameToUrl(normalizedName);\n                }\n            }\n\n            //If the id is a plugin id that cannot be determined if it needs\n            //normalization, stamp it with a unique ID so two matching relative\n            //ids that may conflict can be separate.\n            suffix = prefix && !pluginModule && !isNormalized ?\n                     '_unnormalized' + (unnormalizedCounter += 1) :\n                     '';\n\n            return {\n                prefix: prefix,\n                name: normalizedName,\n                parentMap: parentModuleMap,\n                unnormalized: !!suffix,\n                url: url,\n                originalName: originalName,\n                isDefine: isDefine,\n                id: (prefix ?\n                        prefix + '!' + normalizedName :\n                        normalizedName) + suffix\n            };\n        }\n\n        function getModule(depMap) {\n            var id = depMap.id,\n                mod = getOwn(registry, id);\n\n            if (!mod) {\n                mod = registry[id] = new context.Module(depMap);\n            }\n\n            return mod;\n        }\n\n        function on(depMap, name, fn) {\n            var id = depMap.id,\n                mod = getOwn(registry, id);\n\n            if (hasProp(defined, id) &&\n                    (!mod || mod.defineEmitComplete)) {\n                if (name === 'defined') {\n                    fn(defined[id]);\n                }\n            } else {\n                mod = getModule(depMap);\n                if (mod.error && name === 'error') {\n                    fn(mod.error);\n                } else {\n                    mod.on(name, fn);\n                }\n            }\n        }\n\n        function onError(err, errback) {\n            var ids = err.requireModules,\n                notified = false;\n\n            if (errback) {\n                errback(err);\n            } else {\n                each(ids, function (id) {\n                    var mod = getOwn(registry, id);\n                    if (mod) {\n                        //Set error on module, so it skips timeout checks.\n                        mod.error = err;\n                        if (mod.events.error) {\n                            notified = true;\n                            mod.emit('error', err);\n                        }\n                    }\n                });\n\n                if (!notified) {\n                    req.onError(err);\n                }\n            }\n        }\n\n        /**\n         * Internal method to transfer globalQueue items to this context's\n         * defQueue.\n         */\n        function takeGlobalQueue() {\n            //Push all the globalDefQueue items into the context's defQueue\n            if (globalDefQueue.length) {\n                //Array splice in the values since the context code has a\n                //local var ref to defQueue, so cannot just reassign the one\n                //on context.\n                apsp.apply(defQueue,\n                           [defQueue.length - 1, 0].concat(globalDefQueue));\n                globalDefQueue = [];\n            }\n        }\n\n        handlers = {\n            'require': function (mod) {\n                if (mod.require) {\n                    return mod.require;\n                } else {\n                    return (mod.require = context.makeRequire(mod.map));\n                }\n            },\n            'exports': function (mod) {\n                mod.usingExports = true;\n                if (mod.map.isDefine) {\n                    if (mod.exports) {\n                        return mod.exports;\n                    } else {\n                        return (mod.exports = defined[mod.map.id] = {});\n                    }\n                }\n            },\n            'module': function (mod) {\n                if (mod.module) {\n                    return mod.module;\n                } else {\n                    return (mod.module = {\n                        id: mod.map.id,\n                        uri: mod.map.url,\n                        config: function () {\n                            var c,\n                                pkg = getOwn(config.pkgs, mod.map.id);\n                            // For packages, only support config targeted\n                            // at the main module.\n                            c = pkg ? getOwn(config.config, mod.map.id + '/' + pkg.main) :\n                                      getOwn(config.config, mod.map.id);\n                            return  c || {};\n                        },\n                        exports: defined[mod.map.id]\n                    });\n                }\n            }\n        };\n\n        function cleanRegistry(id) {\n            //Clean up machinery used for waiting modules.\n            delete registry[id];\n            delete enabledRegistry[id];\n        }\n\n        function breakCycle(mod, traced, processed) {\n            var id = mod.map.id;\n\n            if (mod.error) {\n                mod.emit('error', mod.error);\n            } else {\n                traced[id] = true;\n                each(mod.depMaps, function (depMap, i) {\n                    var depId = depMap.id,\n                        dep = getOwn(registry, depId);\n\n                    //Only force things that have not completed\n                    //being defined, so still in the registry,\n                    //and only if it has not been matched up\n                    //in the module already.\n                    if (dep && !mod.depMatched[i] && !processed[depId]) {\n                        if (getOwn(traced, depId)) {\n                            mod.defineDep(i, defined[depId]);\n                            mod.check(); //pass false?\n                        } else {\n                            breakCycle(dep, traced, processed);\n                        }\n                    }\n                });\n                processed[id] = true;\n            }\n        }\n\n        function checkLoaded() {\n            var map, modId, err, usingPathFallback,\n                waitInterval = config.waitSeconds * 1000,\n                //It is possible to disable the wait interval by using waitSeconds of 0.\n                expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),\n                noLoads = [],\n                reqCalls = [],\n                stillLoading = false,\n                needCycleCheck = true;\n\n            //Do not bother if this call was a result of a cycle break.\n            if (inCheckLoaded) {\n                return;\n            }\n\n            inCheckLoaded = true;\n\n            //Figure out the state of all the modules.\n            eachProp(enabledRegistry, function (mod) {\n                map = mod.map;\n                modId = map.id;\n\n                //Skip things that are not enabled or in error state.\n                if (!mod.enabled) {\n                    return;\n                }\n\n                if (!map.isDefine) {\n                    reqCalls.push(mod);\n                }\n\n                if (!mod.error) {\n                    //If the module should be executed, and it has not\n                    //been inited and time is up, remember it.\n                    if (!mod.inited && expired) {\n                        if (hasPathFallback(modId)) {\n                            usingPathFallback = true;\n                            stillLoading = true;\n                        } else {\n                            noLoads.push(modId);\n                            removeScript(modId);\n                        }\n                    } else if (!mod.inited && mod.fetched && map.isDefine) {\n                        stillLoading = true;\n                        if (!map.prefix) {\n                            //No reason to keep looking for unfinished\n                            //loading. If the only stillLoading is a\n                            //plugin resource though, keep going,\n                            //because it may be that a plugin resource\n                            //is waiting on a non-plugin cycle.\n                            return (needCycleCheck = false);\n                        }\n                    }\n                }\n            });\n\n            if (expired && noLoads.length) {\n                //If wait time expired, throw error of unloaded modules.\n                err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);\n                err.contextName = context.contextName;\n                return onError(err);\n            }\n\n            //Not expired, check for a cycle.\n            if (needCycleCheck) {\n                each(reqCalls, function (mod) {\n                    breakCycle(mod, {}, {});\n                });\n            }\n\n            //If still waiting on loads, and the waiting load is something\n            //other than a plugin resource, or there are still outstanding\n            //scripts, then just try back later.\n            if ((!expired || usingPathFallback) && stillLoading) {\n                //Something is still waiting to load. Wait for it, but only\n                //if a timeout is not already in effect.\n                if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {\n                    checkLoadedTimeoutId = setTimeout(function () {\n                        checkLoadedTimeoutId = 0;\n                        checkLoaded();\n                    }, 50);\n                }\n            }\n\n            inCheckLoaded = false;\n        }\n\n        Module = function (map) {\n            this.events = getOwn(undefEvents, map.id) || {};\n            this.map = map;\n            this.shim = getOwn(config.shim, map.id);\n            this.depExports = [];\n            this.depMaps = [];\n            this.depMatched = [];\n            this.pluginMaps = {};\n            this.depCount = 0;\n\n            /* this.exports this.factory\n               this.depMaps = [],\n               this.enabled, this.fetched\n            */\n        };\n\n        Module.prototype = {\n            init: function (depMaps, factory, errback, options) {\n                options = options || {};\n\n                //Do not do more inits if already done. Can happen if there\n                //are multiple define calls for the same module. That is not\n                //a normal, common case, but it is also not unexpected.\n                if (this.inited) {\n                    return;\n                }\n\n                this.factory = factory;\n\n                if (errback) {\n                    //Register for errors on this module.\n                    this.on('error', errback);\n                } else if (this.events.error) {\n                    //If no errback already, but there are error listeners\n                    //on this module, set up an errback to pass to the deps.\n                    errback = bind(this, function (err) {\n                        this.emit('error', err);\n                    });\n                }\n\n                //Do a copy of the dependency array, so that\n                //source inputs are not modified. For example\n                //\"shim\" deps are passed in here directly, and\n                //doing a direct modification of the depMaps array\n                //would affect that config.\n                this.depMaps = depMaps && depMaps.slice(0);\n\n                this.errback = errback;\n\n                //Indicate this module has be initialized\n                this.inited = true;\n\n                this.ignore = options.ignore;\n\n                //Could have option to init this module in enabled mode,\n                //or could have been previously marked as enabled. However,\n                //the dependencies are not known until init is called. So\n                //if enabled previously, now trigger dependencies as enabled.\n                if (options.enabled || this.enabled) {\n                    //Enable this module and dependencies.\n                    //Will call this.check()\n                    this.enable();\n                } else {\n                    this.check();\n                }\n            },\n\n            defineDep: function (i, depExports) {\n                //Because of cycles, defined callback for a given\n                //export can be called more than once.\n                if (!this.depMatched[i]) {\n                    this.depMatched[i] = true;\n                    this.depCount -= 1;\n                    this.depExports[i] = depExports;\n                }\n            },\n\n            fetch: function () {\n                if (this.fetched) {\n                    return;\n                }\n                this.fetched = true;\n\n                context.startTime = (new Date()).getTime();\n\n                var map = this.map;\n\n                //If the manager is for a plugin managed resource,\n                //ask the plugin to load it now.\n                if (this.shim) {\n                    context.makeRequire(this.map, {\n                        enableBuildCallback: true\n                    })(this.shim.deps || [], bind(this, function () {\n                        return map.prefix ? this.callPlugin() : this.load();\n                    }));\n                } else {\n                    //Regular dependency.\n                    return map.prefix ? this.callPlugin() : this.load();\n                }\n            },\n\n            load: function () {\n                var url = this.map.url;\n\n                //Regular dependency.\n                if (!urlFetched[url]) {\n                    urlFetched[url] = true;\n                    context.load(this.map.id, url);\n                }\n            },\n\n            /**\n             * Checks if the module is ready to define itself, and if so,\n             * define it.\n             */\n            check: function () {\n                if (!this.enabled || this.enabling) {\n                    return;\n                }\n\n                var err, cjsModule,\n                    id = this.map.id,\n                    depExports = this.depExports,\n                    exports = this.exports,\n                    factory = this.factory;\n\n                if (!this.inited) {\n                    this.fetch();\n                } else if (this.error) {\n                    this.emit('error', this.error);\n                } else if (!this.defining) {\n                    //The factory could trigger another require call\n                    //that would result in checking this module to\n                    //define itself again. If already in the process\n                    //of doing that, skip this work.\n                    this.defining = true;\n\n                    if (this.depCount < 1 && !this.defined) {\n                        if (isFunction(factory)) {\n                            //If there is an error listener, favor passing\n                            //to that instead of throwing an error. However,\n                            //only do it for define()'d  modules. require\n                            //errbacks should not be called for failures in\n                            //their callbacks (#699). However if a global\n                            //onError is set, use that.\n                            if ((this.events.error && this.map.isDefine) ||\n                                req.onError !== defaultOnError) {\n                                try {\n                                    exports = context.execCb(id, factory, depExports, exports);\n                                } catch (e) {\n                                    err = e;\n                                }\n                            } else {\n                                exports = context.execCb(id, factory, depExports, exports);\n                            }\n\n                            if (this.map.isDefine) {\n                                //If setting exports via 'module' is in play,\n                                //favor that over return value and exports. After that,\n                                //favor a non-undefined return value over exports use.\n                                cjsModule = this.module;\n                                if (cjsModule &&\n                                        cjsModule.exports !== undefined &&\n                                        //Make sure it is not already the exports value\n                                        cjsModule.exports !== this.exports) {\n                                    exports = cjsModule.exports;\n                                } else if (exports === undefined && this.usingExports) {\n                                    //exports already set the defined value.\n                                    exports = this.exports;\n                                }\n                            }\n\n                            if (err) {\n                                err.requireMap = this.map;\n                                err.requireModules = this.map.isDefine ? [this.map.id] : null;\n                                err.requireType = this.map.isDefine ? 'define' : 'require';\n                                return onError((this.error = err));\n                            }\n\n                        } else {\n                            //Just a literal value\n                            exports = factory;\n                        }\n\n                        this.exports = exports;\n\n                        if (this.map.isDefine && !this.ignore) {\n                            defined[id] = exports;\n\n                            if (req.onResourceLoad) {\n                                req.onResourceLoad(context, this.map, this.depMaps);\n                            }\n                        }\n\n                        //Clean up\n                        cleanRegistry(id);\n\n                        this.defined = true;\n                    }\n\n                    //Finished the define stage. Allow calling check again\n                    //to allow define notifications below in the case of a\n                    //cycle.\n                    this.defining = false;\n\n                    if (this.defined && !this.defineEmitted) {\n                        this.defineEmitted = true;\n                        this.emit('defined', this.exports);\n                        this.defineEmitComplete = true;\n                    }\n\n                }\n            },\n\n            callPlugin: function () {\n                var map = this.map,\n                    id = map.id,\n                    //Map already normalized the prefix.\n                    pluginMap = makeModuleMap(map.prefix);\n\n                //Mark this as a dependency for this plugin, so it\n                //can be traced for cycles.\n                this.depMaps.push(pluginMap);\n\n                on(pluginMap, 'defined', bind(this, function (plugin) {\n                    var load, normalizedMap, normalizedMod,\n                        name = this.map.name,\n                        parentName = this.map.parentMap ? this.map.parentMap.name : null,\n                        localRequire = context.makeRequire(map.parentMap, {\n                            enableBuildCallback: true\n                        });\n\n                    //If current map is not normalized, wait for that\n                    //normalized name to load instead of continuing.\n                    if (this.map.unnormalized) {\n                        //Normalize the ID if the plugin allows it.\n                        if (plugin.normalize) {\n                            name = plugin.normalize(name, function (name) {\n                                return normalize(name, parentName, true);\n                            }) || '';\n                        }\n\n                        //prefix and name should already be normalized, no need\n                        //for applying map config again either.\n                        normalizedMap = makeModuleMap(map.prefix + '!' + name,\n                                                      this.map.parentMap);\n                        on(normalizedMap,\n                            'defined', bind(this, function (value) {\n                                this.init([], function () { return value; }, null, {\n                                    enabled: true,\n                                    ignore: true\n                                });\n                            }));\n\n                        normalizedMod = getOwn(registry, normalizedMap.id);\n                        if (normalizedMod) {\n                            //Mark this as a dependency for this plugin, so it\n                            //can be traced for cycles.\n                            this.depMaps.push(normalizedMap);\n\n                            if (this.events.error) {\n                                normalizedMod.on('error', bind(this, function (err) {\n                                    this.emit('error', err);\n                                }));\n                            }\n                            normalizedMod.enable();\n                        }\n\n                        return;\n                    }\n\n                    load = bind(this, function (value) {\n                        this.init([], function () { return value; }, null, {\n                            enabled: true\n                        });\n                    });\n\n                    load.error = bind(this, function (err) {\n                        this.inited = true;\n                        this.error = err;\n                        err.requireModules = [id];\n\n                        //Remove temp unnormalized modules for this module,\n                        //since they will never be resolved otherwise now.\n                        eachProp(registry, function (mod) {\n                            if (mod.map.id.indexOf(id + '_unnormalized') === 0) {\n                                cleanRegistry(mod.map.id);\n                            }\n                        });\n\n                        onError(err);\n                    });\n\n                    //Allow plugins to load other code without having to know the\n                    //context or how to 'complete' the load.\n                    load.fromText = bind(this, function (text, textAlt) {\n                        /*jslint evil: true */\n                        var moduleName = map.name,\n                            moduleMap = makeModuleMap(moduleName),\n                            hasInteractive = useInteractive;\n\n                        //As of 2.1.0, support just passing the text, to reinforce\n                        //fromText only being called once per resource. Still\n                        //support old style of passing moduleName but discard\n                        //that moduleName in favor of the internal ref.\n                        if (textAlt) {\n                            text = textAlt;\n                        }\n\n                        //Turn off interactive script matching for IE for any define\n                        //calls in the text, then turn it back on at the end.\n                        if (hasInteractive) {\n                            useInteractive = false;\n                        }\n\n                        //Prime the system by creating a module instance for\n                        //it.\n                        getModule(moduleMap);\n\n                        //Transfer any config to this other module.\n                        if (hasProp(config.config, id)) {\n                            config.config[moduleName] = config.config[id];\n                        }\n\n                        try {\n                            req.exec(text);\n                        } catch (e) {\n                            return onError(makeError('fromtexteval',\n                                             'fromText eval for ' + id +\n                                            ' failed: ' + e,\n                                             e,\n                                             [id]));\n                        }\n\n                        if (hasInteractive) {\n                            useInteractive = true;\n                        }\n\n                        //Mark this as a dependency for the plugin\n                        //resource\n                        this.depMaps.push(moduleMap);\n\n                        //Support anonymous modules.\n                        context.completeLoad(moduleName);\n\n                        //Bind the value of that module to the value for this\n                        //resource ID.\n                        localRequire([moduleName], load);\n                    });\n\n                    //Use parentName here since the plugin's name is not reliable,\n                    //could be some weird string with no path that actually wants to\n                    //reference the parentName's path.\n                    plugin.load(map.name, localRequire, load, config);\n                }));\n\n                context.enable(pluginMap, this);\n                this.pluginMaps[pluginMap.id] = pluginMap;\n            },\n\n            enable: function () {\n                enabledRegistry[this.map.id] = this;\n                this.enabled = true;\n\n                //Set flag mentioning that the module is enabling,\n                //so that immediate calls to the defined callbacks\n                //for dependencies do not trigger inadvertent load\n                //with the depCount still being zero.\n                this.enabling = true;\n\n                //Enable each dependency\n                each(this.depMaps, bind(this, function (depMap, i) {\n                    var id, mod, handler;\n\n                    if (typeof depMap === 'string') {\n                        //Dependency needs to be converted to a depMap\n                        //and wired up to this module.\n                        depMap = makeModuleMap(depMap,\n                                               (this.map.isDefine ? this.map : this.map.parentMap),\n                                               false,\n                                               !this.skipMap);\n                        this.depMaps[i] = depMap;\n\n                        handler = getOwn(handlers, depMap.id);\n\n                        if (handler) {\n                            this.depExports[i] = handler(this);\n                            return;\n                        }\n\n                        this.depCount += 1;\n\n                        on(depMap, 'defined', bind(this, function (depExports) {\n                            this.defineDep(i, depExports);\n                            this.check();\n                        }));\n\n                        if (this.errback) {\n                            on(depMap, 'error', bind(this, this.errback));\n                        }\n                    }\n\n                    id = depMap.id;\n                    mod = registry[id];\n\n                    //Skip special modules like 'require', 'exports', 'module'\n                    //Also, don't call enable if it is already enabled,\n                    //important in circular dependency cases.\n                    if (!hasProp(handlers, id) && mod && !mod.enabled) {\n                        context.enable(depMap, this);\n                    }\n                }));\n\n                //Enable each plugin that is used in\n                //a dependency\n                eachProp(this.pluginMaps, bind(this, function (pluginMap) {\n                    var mod = getOwn(registry, pluginMap.id);\n                    if (mod && !mod.enabled) {\n                        context.enable(pluginMap, this);\n                    }\n                }));\n\n                this.enabling = false;\n\n                this.check();\n            },\n\n            on: function (name, cb) {\n                var cbs = this.events[name];\n                if (!cbs) {\n                    cbs = this.events[name] = [];\n                }\n                cbs.push(cb);\n            },\n\n            emit: function (name, evt) {\n                each(this.events[name], function (cb) {\n                    cb(evt);\n                });\n                if (name === 'error') {\n                    //Now that the error handler was triggered, remove\n                    //the listeners, since this broken Module instance\n                    //can stay around for a while in the registry.\n                    delete this.events[name];\n                }\n            }\n        };\n\n        function callGetModule(args) {\n            //Skip modules already defined.\n            if (!hasProp(defined, args[0])) {\n                getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);\n            }\n        }\n\n        function removeListener(node, func, name, ieName) {\n            //Favor detachEvent because of IE9\n            //issue, see attachEvent/addEventListener comment elsewhere\n            //in this file.\n            if (node.detachEvent && !isOpera) {\n                //Probably IE. If not it will throw an error, which will be\n                //useful to know.\n                if (ieName) {\n                    node.detachEvent(ieName, func);\n                }\n            } else {\n                node.removeEventListener(name, func, false);\n            }\n        }\n\n        /**\n         * Given an event from a script node, get the requirejs info from it,\n         * and then removes the event listeners on the node.\n         * @param {Event} evt\n         * @returns {Object}\n         */\n        function getScriptData(evt) {\n            //Using currentTarget instead of target for Firefox 2.0's sake. Not\n            //all old browsers will be supported, but this one was easy enough\n            //to support and still makes sense.\n            var node = evt.currentTarget || evt.srcElement;\n\n            //Remove the listeners once here.\n            removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');\n            removeListener(node, context.onScriptError, 'error');\n\n            return {\n                node: node,\n                id: node && node.getAttribute('data-requiremodule')\n            };\n        }\n\n        function intakeDefines() {\n            var args;\n\n            //Any defined modules in the global queue, intake them now.\n            takeGlobalQueue();\n\n            //Make sure any remaining defQueue items get properly processed.\n            while (defQueue.length) {\n                args = defQueue.shift();\n                if (args[0] === null) {\n                    return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));\n                } else {\n                    //args are id, deps, factory. Should be normalized by the\n                    //define() function.\n                    callGetModule(args);\n                }\n            }\n        }\n\n        context = {\n            config: config,\n            contextName: contextName,\n            registry: registry,\n            defined: defined,\n            urlFetched: urlFetched,\n            defQueue: defQueue,\n            Module: Module,\n            makeModuleMap: makeModuleMap,\n            nextTick: req.nextTick,\n            onError: onError,\n\n            /**\n             * Set a configuration for the context.\n             * @param {Object} cfg config object to integrate.\n             */\n            configure: function (cfg) {\n                //Make sure the baseUrl ends in a slash.\n                if (cfg.baseUrl) {\n                    if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {\n                        cfg.baseUrl += '/';\n                    }\n                }\n\n                //Save off the paths and packages since they require special processing,\n                //they are additive.\n                var pkgs = config.pkgs,\n                    shim = config.shim,\n                    objs = {\n                        paths: true,\n                        config: true,\n                        map: true\n                    };\n\n                eachProp(cfg, function (value, prop) {\n                    if (objs[prop]) {\n                        if (prop === 'map') {\n                            if (!config.map) {\n                                config.map = {};\n                            }\n                            mixin(config[prop], value, true, true);\n                        } else {\n                            mixin(config[prop], value, true);\n                        }\n                    } else {\n                        config[prop] = value;\n                    }\n                });\n\n                //Merge shim\n                if (cfg.shim) {\n                    eachProp(cfg.shim, function (value, id) {\n                        //Normalize the structure\n                        if (isArray(value)) {\n                            value = {\n                                deps: value\n                            };\n                        }\n                        if ((value.exports || value.init) && !value.exportsFn) {\n                            value.exportsFn = context.makeShimExports(value);\n                        }\n                        shim[id] = value;\n                    });\n                    config.shim = shim;\n                }\n\n                //Adjust packages if necessary.\n                if (cfg.packages) {\n                    each(cfg.packages, function (pkgObj) {\n                        var location;\n\n                        pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj;\n                        location = pkgObj.location;\n\n                        //Create a brand new object on pkgs, since currentPackages can\n                        //be passed in again, and config.pkgs is the internal transformed\n                        //state for all package configs.\n                        pkgs[pkgObj.name] = {\n                            name: pkgObj.name,\n                            location: location || pkgObj.name,\n                            //Remove leading dot in main, so main paths are normalized,\n                            //and remove any trailing .js, since different package\n                            //envs have different conventions: some use a module name,\n                            //some use a file name.\n                            main: (pkgObj.main || 'main')\n                                  .replace(currDirRegExp, '')\n                                  .replace(jsSuffixRegExp, '')\n                        };\n                    });\n\n                    //Done with modifications, assing packages back to context config\n                    config.pkgs = pkgs;\n                }\n\n                //If there are any \"waiting to execute\" modules in the registry,\n                //update the maps for them, since their info, like URLs to load,\n                //may have changed.\n                eachProp(registry, function (mod, id) {\n                    //If module already has init called, since it is too\n                    //late to modify them, and ignore unnormalized ones\n                    //since they are transient.\n                    if (!mod.inited && !mod.map.unnormalized) {\n                        mod.map = makeModuleMap(id);\n                    }\n                });\n\n                //If a deps array or a config callback is specified, then call\n                //require with those args. This is useful when require is defined as a\n                //config object before require.js is loaded.\n                if (cfg.deps || cfg.callback) {\n                    context.require(cfg.deps || [], cfg.callback);\n                }\n            },\n\n            makeShimExports: function (value) {\n                function fn() {\n                    var ret;\n                    if (value.init) {\n                        ret = value.init.apply(global, arguments);\n                    }\n                    return ret || (value.exports && getGlobal(value.exports));\n                }\n                return fn;\n            },\n\n            makeRequire: function (relMap, options) {\n                options = options || {};\n\n                function localRequire(deps, callback, errback) {\n                    var id, map, requireMod;\n\n                    if (options.enableBuildCallback && callback && isFunction(callback)) {\n                        callback.__requireJsBuild = true;\n                    }\n\n                    if (typeof deps === 'string') {\n                        if (isFunction(callback)) {\n                            //Invalid call\n                            return onError(makeError('requireargs', 'Invalid require call'), errback);\n                        }\n\n                        //If require|exports|module are requested, get the\n                        //value for them from the special handlers. Caveat:\n                        //this only works while module is being defined.\n                        if (relMap && hasProp(handlers, deps)) {\n                            return handlers[deps](registry[relMap.id]);\n                        }\n\n                        //Synchronous access to one module. If require.get is\n                        //available (as in the Node adapter), prefer that.\n                        if (req.get) {\n                            return req.get(context, deps, relMap, localRequire);\n                        }\n\n                        //Normalize module name, if it contains . or ..\n                        map = makeModuleMap(deps, relMap, false, true);\n                        id = map.id;\n\n                        if (!hasProp(defined, id)) {\n                            return onError(makeError('notloaded', 'Module name \"' +\n                                        id +\n                                        '\" has not been loaded yet for context: ' +\n                                        contextName +\n                                        (relMap ? '' : '. Use require([])')));\n                        }\n                        return defined[id];\n                    }\n\n                    //Grab defines waiting in the global queue.\n                    intakeDefines();\n\n                    //Mark all the dependencies as needing to be loaded.\n                    context.nextTick(function () {\n                        //Some defines could have been added since the\n                        //require call, collect them.\n                        intakeDefines();\n\n                        requireMod = getModule(makeModuleMap(null, relMap));\n\n                        //Store if map config should be applied to this require\n                        //call for dependencies.\n                        requireMod.skipMap = options.skipMap;\n\n                        requireMod.init(deps, callback, errback, {\n                            enabled: true\n                        });\n\n                        checkLoaded();\n                    });\n\n                    return localRequire;\n                }\n\n                mixin(localRequire, {\n                    isBrowser: isBrowser,\n\n                    /**\n                     * Converts a module name + .extension into an URL path.\n                     * *Requires* the use of a module name. It does not support using\n                     * plain URLs like nameToUrl.\n                     */\n                    toUrl: function (moduleNamePlusExt) {\n                        var ext,\n                            index = moduleNamePlusExt.lastIndexOf('.'),\n                            segment = moduleNamePlusExt.split('/')[0],\n                            isRelative = segment === '.' || segment === '..';\n\n                        //Have a file extension alias, and it is not the\n                        //dots from a relative path.\n                        if (index !== -1 && (!isRelative || index > 1)) {\n                            ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);\n                            moduleNamePlusExt = moduleNamePlusExt.substring(0, index);\n                        }\n\n                        return context.nameToUrl(normalize(moduleNamePlusExt,\n                                                relMap && relMap.id, true), ext,  true);\n                    },\n\n                    defined: function (id) {\n                        return hasProp(defined, makeModuleMap(id, relMap, false, true).id);\n                    },\n\n                    specified: function (id) {\n                        id = makeModuleMap(id, relMap, false, true).id;\n                        return hasProp(defined, id) || hasProp(registry, id);\n                    }\n                });\n\n                //Only allow undef on top level require calls\n                if (!relMap) {\n                    localRequire.undef = function (id) {\n                        //Bind any waiting define() calls to this context,\n                        //fix for #408\n                        takeGlobalQueue();\n\n                        var map = makeModuleMap(id, relMap, true),\n                            mod = getOwn(registry, id);\n\n                        removeScript(id);\n\n                        delete defined[id];\n                        delete urlFetched[map.url];\n                        delete undefEvents[id];\n\n                        if (mod) {\n                            //Hold on to listeners in case the\n                            //module will be attempted to be reloaded\n                            //using a different config.\n                            if (mod.events.defined) {\n                                undefEvents[id] = mod.events;\n                            }\n\n                            cleanRegistry(id);\n                        }\n                    };\n                }\n\n                return localRequire;\n            },\n\n            /**\n             * Called to enable a module if it is still in the registry\n             * awaiting enablement. A second arg, parent, the parent module,\n             * is passed in for context, when this method is overriden by\n             * the optimizer. Not shown here to keep code compact.\n             */\n            enable: function (depMap) {\n                var mod = getOwn(registry, depMap.id);\n                if (mod) {\n                    getModule(depMap).enable();\n                }\n            },\n\n            /**\n             * Internal method used by environment adapters to complete a load event.\n             * A load event could be a script load or just a load pass from a synchronous\n             * load call.\n             * @param {String} moduleName the name of the module to potentially complete.\n             */\n            completeLoad: function (moduleName) {\n                var found, args, mod,\n                    shim = getOwn(config.shim, moduleName) || {},\n                    shExports = shim.exports;\n\n                takeGlobalQueue();\n\n                while (defQueue.length) {\n                    args = defQueue.shift();\n                    if (args[0] === null) {\n                        args[0] = moduleName;\n                        //If already found an anonymous module and bound it\n                        //to this name, then this is some other anon module\n                        //waiting for its completeLoad to fire.\n                        if (found) {\n                            break;\n                        }\n                        found = true;\n                    } else if (args[0] === moduleName) {\n                        //Found matching define call for this script!\n                        found = true;\n                    }\n\n                    callGetModule(args);\n                }\n\n                //Do this after the cycle of callGetModule in case the result\n                //of those calls/init calls changes the registry.\n                mod = getOwn(registry, moduleName);\n\n                if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {\n                    if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {\n                        if (hasPathFallback(moduleName)) {\n                            return;\n                        } else {\n                            return onError(makeError('nodefine',\n                                             'No define call for ' + moduleName,\n                                             null,\n                                             [moduleName]));\n                        }\n                    } else {\n                        //A script that does not call define(), so just simulate\n                        //the call for it.\n                        callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);\n                    }\n                }\n\n                checkLoaded();\n            },\n\n            /**\n             * Converts a module name to a file path. Supports cases where\n             * moduleName may actually be just an URL.\n             * Note that it **does not** call normalize on the moduleName,\n             * it is assumed to have already been normalized. This is an\n             * internal API, not a public one. Use toUrl for the public API.\n             */\n            nameToUrl: function (moduleName, ext, skipExt) {\n                var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url,\n                    parentPath;\n\n                //If a colon is in the URL, it indicates a protocol is used and it is just\n                //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)\n                //or ends with .js, then assume the user meant to use an url and not a module id.\n                //The slash is important for protocol-less URLs as well as full paths.\n                if (req.jsExtRegExp.test(moduleName)) {\n                    //Just a plain path, not module name lookup, so just return it.\n                    //Add extension if it is included. This is a bit wonky, only non-.js things pass\n                    //an extension, this method probably needs to be reworked.\n                    url = moduleName + (ext || '');\n                } else {\n                    //A module that needs to be converted to a path.\n                    paths = config.paths;\n                    pkgs = config.pkgs;\n\n                    syms = moduleName.split('/');\n                    //For each module name segment, see if there is a path\n                    //registered for it. Start with most specific name\n                    //and work up from it.\n                    for (i = syms.length; i > 0; i -= 1) {\n                        parentModule = syms.slice(0, i).join('/');\n                        pkg = getOwn(pkgs, parentModule);\n                        parentPath = getOwn(paths, parentModule);\n                        if (parentPath) {\n                            //If an array, it means there are a few choices,\n                            //Choose the one that is desired\n                            if (isArray(parentPath)) {\n                                parentPath = parentPath[0];\n                            }\n                            syms.splice(0, i, parentPath);\n                            break;\n                        } else if (pkg) {\n                            //If module name is just the package name, then looking\n                            //for the main module.\n                            if (moduleName === pkg.name) {\n                                pkgPath = pkg.location + '/' + pkg.main;\n                            } else {\n                                pkgPath = pkg.location;\n                            }\n                            syms.splice(0, i, pkgPath);\n                            break;\n                        }\n                    }\n\n                    //Join the path parts together, then figure out if baseUrl is needed.\n                    url = syms.join('/');\n                    url += (ext || (/^data\\:|\\?/.test(url) || skipExt ? '' : '.js'));\n                    url = (url.charAt(0) === '/' || url.match(/^[\\w\\+\\.\\-]+:/) ? '' : config.baseUrl) + url;\n                }\n\n                return config.urlArgs ? url +\n                                        ((url.indexOf('?') === -1 ? '?' : '&') +\n                                         config.urlArgs) : url;\n            },\n\n            //Delegates to req.load. Broken out as a separate function to\n            //allow overriding in the optimizer.\n            load: function (id, url) {\n                req.load(context, id, url);\n            },\n\n            /**\n             * Executes a module callback function. Broken out as a separate function\n             * solely to allow the build system to sequence the files in the built\n             * layer in the right sequence.\n             *\n             * @private\n             */\n            execCb: function (name, callback, args, exports) {\n                return callback.apply(exports, args);\n            },\n\n            /**\n             * callback for script loads, used to check status of loading.\n             *\n             * @param {Event} evt the event from the browser for the script\n             * that was loaded.\n             */\n            onScriptLoad: function (evt) {\n                //Using currentTarget instead of target for Firefox 2.0's sake. Not\n                //all old browsers will be supported, but this one was easy enough\n                //to support and still makes sense.\n                if (evt.type === 'load' ||\n                        (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {\n                    //Reset interactive script so a script node is not held onto for\n                    //to long.\n                    interactiveScript = null;\n\n                    //Pull out the name of the module and the context.\n                    var data = getScriptData(evt);\n                    context.completeLoad(data.id);\n                }\n            },\n\n            /**\n             * Callback for script errors.\n             */\n            onScriptError: function (evt) {\n                var data = getScriptData(evt);\n                if (!hasPathFallback(data.id)) {\n                    return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id]));\n                }\n            }\n        };\n\n        context.require = context.makeRequire();\n        return context;\n    }\n\n    /**\n     * Main entry point.\n     *\n     * If the only argument to require is a string, then the module that\n     * is represented by that string is fetched for the appropriate context.\n     *\n     * If the first argument is an array, then it will be treated as an array\n     * of dependency string names to fetch. An optional function callback can\n     * be specified to execute when all of those dependencies are available.\n     *\n     * Make a local req variable to help Caja compliance (it assumes things\n     * on a require that are not standardized), and to give a short\n     * name for minification/local scope use.\n     */\n    req = requirejs = function (deps, callback, errback, optional) {\n\n        //Find the right context, use default\n        var context, config,\n            contextName = defContextName;\n\n        // Determine if have config object in the call.\n        if (!isArray(deps) && typeof deps !== 'string') {\n            // deps is a config object\n            config = deps;\n            if (isArray(callback)) {\n                // Adjust args if there are dependencies\n                deps = callback;\n                callback = errback;\n                errback = optional;\n            } else {\n                deps = [];\n            }\n        }\n\n        if (config && config.context) {\n            contextName = config.context;\n        }\n\n        context = getOwn(contexts, contextName);\n        if (!context) {\n            context = contexts[contextName] = req.s.newContext(contextName);\n        }\n\n        if (config) {\n            context.configure(config);\n        }\n\n        return context.require(deps, callback, errback);\n    };\n\n    /**\n     * Support require.config() to make it easier to cooperate with other\n     * AMD loaders on globally agreed names.\n     */\n    req.config = function (config) {\n        return req(config);\n    };\n\n    /**\n     * Execute something after the current tick\n     * of the event loop. Override for other envs\n     * that have a better solution than setTimeout.\n     * @param  {Function} fn function to execute later.\n     */\n    req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {\n        setTimeout(fn, 4);\n    } : function (fn) { fn(); };\n\n    /**\n     * Export require as a global, but only if it does not already exist.\n     */\n    if (!require) {\n        require = req;\n    }\n\n    req.version = version;\n\n    //Used to filter out dependencies that are already paths.\n    req.jsExtRegExp = /^\\/|:|\\?|\\.js$/;\n    req.isBrowser = isBrowser;\n    s = req.s = {\n        contexts: contexts,\n        newContext: newContext\n    };\n\n    //Create default context.\n    req({});\n\n    //Exports some context-sensitive methods on global require.\n    each([\n        'toUrl',\n        'undef',\n        'defined',\n        'specified'\n    ], function (prop) {\n        //Reference from contexts instead of early binding to default context,\n        //so that during builds, the latest instance of the default context\n        //with its config gets used.\n        req[prop] = function () {\n            var ctx = contexts[defContextName];\n            return ctx.require[prop].apply(ctx, arguments);\n        };\n    });\n\n    if (isBrowser) {\n        head = s.head = document.getElementsByTagName('head')[0];\n        //If BASE tag is in play, using appendChild is a problem for IE6.\n        //When that browser dies, this can be removed. Details in this jQuery bug:\n        //http://dev.jquery.com/ticket/2709\n        baseElement = document.getElementsByTagName('base')[0];\n        if (baseElement) {\n            head = s.head = baseElement.parentNode;\n        }\n    }\n\n    /**\n     * Any errors that require explicitly generates will be passed to this\n     * function. Intercept/override it if you want custom error handling.\n     * @param {Error} err the error object.\n     */\n    req.onError = defaultOnError;\n\n    /**\n     * Creates the node for the load command. Only used in browser envs.\n     */\n    req.createNode = function (config, moduleName, url) {\n        var node = config.xhtml ?\n                document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :\n                document.createElement('script');\n        node.type = config.scriptType || 'text/javascript';\n        node.charset = 'utf-8';\n        node.async = true;\n        return node;\n    };\n\n    /**\n     * Does the request to load a module for the browser case.\n     * Make this a separate function to allow other environments\n     * to override it.\n     *\n     * @param {Object} context the require context to find state.\n     * @param {String} moduleName the name of the module.\n     * @param {Object} url the URL to the module.\n     */\n    req.load = function (context, moduleName, url) {\n        var config = (context && context.config) || {},\n            node;\n        if (isBrowser) {\n            //In the browser so use a script tag\n            node = req.createNode(config, moduleName, url);\n\n            node.setAttribute('data-requirecontext', context.contextName);\n            node.setAttribute('data-requiremodule', moduleName);\n\n            //Set up load listener. Test attachEvent first because IE9 has\n            //a subtle issue in its addEventListener and script onload firings\n            //that do not match the behavior of all other browsers with\n            //addEventListener support, which fire the onload event for a\n            //script right after the script execution. See:\n            //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution\n            //UNFORTUNATELY Opera implements attachEvent but does not follow the script\n            //script execution mode.\n            if (node.attachEvent &&\n                    //Check if node.attachEvent is artificially added by custom script or\n                    //natively supported by browser\n                    //read https://github.com/jrburke/requirejs/issues/187\n                    //if we can NOT find [native code] then it must NOT natively supported.\n                    //in IE8, node.attachEvent does not have toString()\n                    //Note the test for \"[native code\" with no closing brace, see:\n                    //https://github.com/jrburke/requirejs/issues/273\n                    !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&\n                    !isOpera) {\n                //Probably IE. IE (at least 6-8) do not fire\n                //script onload right after executing the script, so\n                //we cannot tie the anonymous define call to a name.\n                //However, IE reports the script as being in 'interactive'\n                //readyState at the time of the define call.\n                useInteractive = true;\n\n                node.attachEvent('onreadystatechange', context.onScriptLoad);\n                //It would be great to add an error handler here to catch\n                //404s in IE9+. However, onreadystatechange will fire before\n                //the error handler, so that does not help. If addEventListener\n                //is used, then IE will fire error before load, but we cannot\n                //use that pathway given the connect.microsoft.com issue\n                //mentioned above about not doing the 'script execute,\n                //then fire the script load event listener before execute\n                //next script' that other browsers do.\n                //Best hope: IE10 fixes the issues,\n                //and then destroys all installs of IE 6-9.\n                //node.attachEvent('onerror', context.onScriptError);\n            } else {\n                node.addEventListener('load', context.onScriptLoad, false);\n                node.addEventListener('error', context.onScriptError, false);\n            }\n            node.src = url;\n\n            //For some cache cases in IE 6-8, the script executes before the end\n            //of the appendChild execution, so to tie an anonymous define\n            //call to the module name (which is stored on the node), hold on\n            //to a reference to this node, but clear after the DOM insertion.\n            currentlyAddingScript = node;\n            if (baseElement) {\n                head.insertBefore(node, baseElement);\n            } else {\n                head.appendChild(node);\n            }\n            currentlyAddingScript = null;\n\n            return node;\n        } else if (isWebWorker) {\n            try {\n                //In a web worker, use importScripts. This is not a very\n                //efficient use of importScripts, importScripts will block until\n                //its script is downloaded and evaluated. However, if web workers\n                //are in play, the expectation that a build has been done so that\n                //only one script needs to be loaded anyway. This may need to be\n                //reevaluated if other use cases become common.\n                importScripts(url);\n\n                //Account for anonymous modules\n                context.completeLoad(moduleName);\n            } catch (e) {\n                context.onError(makeError('importscripts',\n                                'importScripts failed for ' +\n                                    moduleName + ' at ' + url,\n                                e,\n                                [moduleName]));\n            }\n        }\n    };\n\n    function getInteractiveScript() {\n        if (interactiveScript && interactiveScript.readyState === 'interactive') {\n            return interactiveScript;\n        }\n\n        eachReverse(scripts(), function (script) {\n            if (script.readyState === 'interactive') {\n                return (interactiveScript = script);\n            }\n        });\n        return interactiveScript;\n    }\n\n    //Look for a data-main script attribute, which could also adjust the baseUrl.\n    if (isBrowser && !cfg.skipDataMain) {\n        //Figure out baseUrl. Get it from the script tag with require.js in it.\n        eachReverse(scripts(), function (script) {\n            //Set the 'head' where we can append children by\n            //using the script's parent.\n            if (!head) {\n                head = script.parentNode;\n            }\n\n            //Look for a data-main attribute to set main script for the page\n            //to load. If it is there, the path to data main becomes the\n            //baseUrl, if it is not already set.\n            dataMain = script.getAttribute('data-main');\n            if (dataMain) {\n                //Preserve dataMain in case it is a path (i.e. contains '?')\n                mainScript = dataMain;\n\n                //Set final baseUrl if there is not already an explicit one.\n                if (!cfg.baseUrl) {\n                    //Pull off the directory of data-main for use as the\n                    //baseUrl.\n                    src = mainScript.split('/');\n                    mainScript = src.pop();\n                    subPath = src.length ? src.join('/')  + '/' : './';\n\n                    cfg.baseUrl = subPath;\n                }\n\n                //Strip off any trailing .js since mainScript is now\n                //like a module name.\n                mainScript = mainScript.replace(jsSuffixRegExp, '');\n\n                 //If mainScript is still a path, fall back to dataMain\n                if (req.jsExtRegExp.test(mainScript)) {\n                    mainScript = dataMain;\n                }\n\n                //Put the data-main script in the files to load.\n                cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];\n\n                return true;\n            }\n        });\n    }\n\n    /**\n     * The function that handles definitions of modules. Differs from\n     * require() in that a string for the module should be the first argument,\n     * and the function to execute after dependencies are loaded should\n     * return a value to define the module corresponding to the first argument's\n     * name.\n     */\n    define = function (name, deps, callback) {\n        var node, context;\n\n        //Allow for anonymous modules\n        if (typeof name !== 'string') {\n            //Adjust args appropriately\n            callback = deps;\n            deps = name;\n            name = null;\n        }\n\n        //This module may not have dependencies\n        if (!isArray(deps)) {\n            callback = deps;\n            deps = null;\n        }\n\n        //If no name, and callback is a function, then figure out if it a\n        //CommonJS thing with dependencies.\n        if (!deps && isFunction(callback)) {\n            deps = [];\n            //Remove comments from the callback string,\n            //look for require calls, and pull them into the dependencies,\n            //but only if there are function args.\n            if (callback.length) {\n                callback\n                    .toString()\n                    .replace(commentRegExp, '')\n                    .replace(cjsRequireRegExp, function (match, dep) {\n                        deps.push(dep);\n                    });\n\n                //May be a CommonJS thing even without require calls, but still\n                //could use exports, and module. Avoid doing exports and module\n                //work though if it just needs require.\n                //REQUIRES the function to expect the CommonJS variables in the\n                //order listed below.\n                deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);\n            }\n        }\n\n        //If in IE 6-8 and hit an anonymous define() call, do the interactive\n        //work.\n        if (useInteractive) {\n            node = currentlyAddingScript || getInteractiveScript();\n            if (node) {\n                if (!name) {\n                    name = node.getAttribute('data-requiremodule');\n                }\n                context = contexts[node.getAttribute('data-requirecontext')];\n            }\n        }\n\n        //Always save off evaluating the def call until the script onload handler.\n        //This allows multiple modules to be in a file without prematurely\n        //tracing dependencies, and allows for anonymous module support,\n        //where the module name is not known until the script onload event\n        //occurs. If no context, use the global queue, and get it processed\n        //in the onscript load callback.\n        (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);\n    };\n\n    define.amd = {\n        jQuery: true\n    };\n\n\n    /**\n     * Executes the text. Normally just uses eval, but can be modified\n     * to use a better, environment-specific call. Only used for transpiling\n     * loader plugins, not for plain JS modules.\n     * @param {String} text the text to execute/evaluate.\n     */\n    req.exec = function (text) {\n        /*jslint evil: true */\n        return eval(text);\n    };\n\n    //Set up with config info.\n    req(cfg);\n}(this));\n"
  },
  {
    "path": "test/vendor/underscore.js",
    "content": "//     Underscore.js 1.8.3\n//     http://underscorejs.org\n//     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n//     Underscore may be freely distributed under the MIT license.\n\n(function() {\n\n  // Baseline setup\n  // --------------\n\n  // Establish the root object, `window` in the browser, or `exports` on the server.\n  var root = this;\n\n  // Save the previous value of the `_` variable.\n  var previousUnderscore = root._;\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var\n    push             = ArrayProto.push,\n    slice            = ArrayProto.slice,\n    toString         = ObjProto.toString,\n    hasOwnProperty   = ObjProto.hasOwnProperty;\n\n  // All **ECMAScript 5** native function implementations that we hope to use\n  // are declared here.\n  var\n    nativeIsArray      = Array.isArray,\n    nativeKeys         = Object.keys,\n    nativeBind         = FuncProto.bind,\n    nativeCreate       = Object.create;\n\n  // Naked function reference for surrogate-prototype-swapping.\n  var Ctor = function(){};\n\n  // Create a safe reference to the Underscore object for use below.\n  var _ = function(obj) {\n    if (obj instanceof _) return obj;\n    if (!(this instanceof _)) return new _(obj);\n    this._wrapped = obj;\n  };\n\n  // Export the Underscore object for **Node.js**, with\n  // backwards-compatibility for the old `require()` API. If we're in\n  // the browser, add `_` as a global object.\n  if (typeof exports !== 'undefined') {\n    if (typeof module !== 'undefined' && module.exports) {\n      exports = module.exports = _;\n    }\n    exports._ = _;\n  } else {\n    root._ = _;\n  }\n\n  // Current version.\n  _.VERSION = '1.8.3';\n\n  // Internal function that returns an efficient (for current engines) version\n  // of the passed-in callback, to be repeatedly applied in other Underscore\n  // functions.\n  var optimizeCb = function(func, context, argCount) {\n    if (context === void 0) return func;\n    switch (argCount == null ? 3 : argCount) {\n      case 1: return function(value) {\n        return func.call(context, value);\n      };\n      case 2: return function(value, other) {\n        return func.call(context, value, other);\n      };\n      case 3: return function(value, index, collection) {\n        return func.call(context, value, index, collection);\n      };\n      case 4: return function(accumulator, value, index, collection) {\n        return func.call(context, accumulator, value, index, collection);\n      };\n    }\n    return function() {\n      return func.apply(context, arguments);\n    };\n  };\n\n  // A mostly-internal function to generate callbacks that can be applied\n  // to each element in a collection, returning the desired result — either\n  // identity, an arbitrary callback, a property matcher, or a property accessor.\n  var cb = function(value, context, argCount) {\n    if (value == null) return _.identity;\n    if (_.isFunction(value)) return optimizeCb(value, context, argCount);\n    if (_.isObject(value)) return _.matcher(value);\n    return _.property(value);\n  };\n  _.iteratee = function(value, context) {\n    return cb(value, context, Infinity);\n  };\n\n  // An internal function for creating assigner functions.\n  var createAssigner = function(keysFunc, undefinedOnly) {\n    return function(obj) {\n      var length = arguments.length;\n      if (length < 2 || obj == null) return obj;\n      for (var index = 1; index < length; index++) {\n        var source = arguments[index],\n            keys = keysFunc(source),\n            l = keys.length;\n        for (var i = 0; i < l; i++) {\n          var key = keys[i];\n          if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];\n        }\n      }\n      return obj;\n    };\n  };\n\n  // An internal function for creating a new object that inherits from another.\n  var baseCreate = function(prototype) {\n    if (!_.isObject(prototype)) return {};\n    if (nativeCreate) return nativeCreate(prototype);\n    Ctor.prototype = prototype;\n    var result = new Ctor;\n    Ctor.prototype = null;\n    return result;\n  };\n\n  var property = function(key) {\n    return function(obj) {\n      return obj == null ? void 0 : obj[key];\n    };\n  };\n\n  // Helper for collection methods to determine whether a collection\n  // should be iterated as an array or as an object\n  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength\n  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094\n  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;\n  var getLength = property('length');\n  var isArrayLike = function(collection) {\n    var length = getLength(collection);\n    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;\n  };\n\n  // Collection Functions\n  // --------------------\n\n  // The cornerstone, an `each` implementation, aka `forEach`.\n  // Handles raw objects in addition to array-likes. Treats all\n  // sparse array-likes as if they were dense.\n  _.each = _.forEach = function(obj, iteratee, context) {\n    iteratee = optimizeCb(iteratee, context);\n    var i, length;\n    if (isArrayLike(obj)) {\n      for (i = 0, length = obj.length; i < length; i++) {\n        iteratee(obj[i], i, obj);\n      }\n    } else {\n      var keys = _.keys(obj);\n      for (i = 0, length = keys.length; i < length; i++) {\n        iteratee(obj[keys[i]], keys[i], obj);\n      }\n    }\n    return obj;\n  };\n\n  // Return the results of applying the iteratee to each element.\n  _.map = _.collect = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length,\n        results = Array(length);\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      results[index] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  };\n\n  // Create a reducing function iterating left or right.\n  function createReduce(dir) {\n    // Optimized iterator function as using arguments.length\n    // in the main function will deoptimize the, see #1991.\n    function iterator(obj, iteratee, memo, keys, index, length) {\n      for (; index >= 0 && index < length; index += dir) {\n        var currentKey = keys ? keys[index] : index;\n        memo = iteratee(memo, obj[currentKey], currentKey, obj);\n      }\n      return memo;\n    }\n\n    return function(obj, iteratee, memo, context) {\n      iteratee = optimizeCb(iteratee, context, 4);\n      var keys = !isArrayLike(obj) && _.keys(obj),\n          length = (keys || obj).length,\n          index = dir > 0 ? 0 : length - 1;\n      // Determine the initial value if none is provided.\n      if (arguments.length < 3) {\n        memo = obj[keys ? keys[index] : index];\n        index += dir;\n      }\n      return iterator(obj, iteratee, memo, keys, index, length);\n    };\n  }\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`.\n  _.reduce = _.foldl = _.inject = createReduce(1);\n\n  // The right-associative version of reduce, also known as `foldr`.\n  _.reduceRight = _.foldr = createReduce(-1);\n\n  // Return the first value which passes a truth test. Aliased as `detect`.\n  _.find = _.detect = function(obj, predicate, context) {\n    var key;\n    if (isArrayLike(obj)) {\n      key = _.findIndex(obj, predicate, context);\n    } else {\n      key = _.findKey(obj, predicate, context);\n    }\n    if (key !== void 0 && key !== -1) return obj[key];\n  };\n\n  // Return all the elements that pass a truth test.\n  // Aliased as `select`.\n  _.filter = _.select = function(obj, predicate, context) {\n    var results = [];\n    predicate = cb(predicate, context);\n    _.each(obj, function(value, index, list) {\n      if (predicate(value, index, list)) results.push(value);\n    });\n    return results;\n  };\n\n  // Return all the elements for which a truth test fails.\n  _.reject = function(obj, predicate, context) {\n    return _.filter(obj, _.negate(cb(predicate)), context);\n  };\n\n  // Determine whether all of the elements match a truth test.\n  // Aliased as `all`.\n  _.every = _.all = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (!predicate(obj[currentKey], currentKey, obj)) return false;\n    }\n    return true;\n  };\n\n  // Determine if at least one element in the object matches a truth test.\n  // Aliased as `any`.\n  _.some = _.any = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (predicate(obj[currentKey], currentKey, obj)) return true;\n    }\n    return false;\n  };\n\n  // Determine if the array or object contains a given item (using `===`).\n  // Aliased as `includes` and `include`.\n  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {\n    if (!isArrayLike(obj)) obj = _.values(obj);\n    if (typeof fromIndex != 'number' || guard) fromIndex = 0;\n    return _.indexOf(obj, item, fromIndex) >= 0;\n  };\n\n  // Invoke a method (with arguments) on every item in a collection.\n  _.invoke = function(obj, method) {\n    var args = slice.call(arguments, 2);\n    var isFunc = _.isFunction(method);\n    return _.map(obj, function(value) {\n      var func = isFunc ? method : value[method];\n      return func == null ? func : func.apply(value, args);\n    });\n  };\n\n  // Convenience version of a common use case of `map`: fetching a property.\n  _.pluck = function(obj, key) {\n    return _.map(obj, _.property(key));\n  };\n\n  // Convenience version of a common use case of `filter`: selecting only objects\n  // containing specific `key:value` pairs.\n  _.where = function(obj, attrs) {\n    return _.filter(obj, _.matcher(attrs));\n  };\n\n  // Convenience version of a common use case of `find`: getting the first object\n  // containing specific `key:value` pairs.\n  _.findWhere = function(obj, attrs) {\n    return _.find(obj, _.matcher(attrs));\n  };\n\n  // Return the maximum element (or element-based computation).\n  _.max = function(obj, iteratee, context) {\n    var result = -Infinity, lastComputed = -Infinity,\n        value, computed;\n    if (iteratee == null && obj != null) {\n      obj = isArrayLike(obj) ? obj : _.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value > result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(value, index, list) {\n        computed = iteratee(value, index, list);\n        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {\n          result = value;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Return the minimum element (or element-based computation).\n  _.min = function(obj, iteratee, context) {\n    var result = Infinity, lastComputed = Infinity,\n        value, computed;\n    if (iteratee == null && obj != null) {\n      obj = isArrayLike(obj) ? obj : _.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value < result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(value, index, list) {\n        computed = iteratee(value, index, list);\n        if (computed < lastComputed || computed === Infinity && result === Infinity) {\n          result = value;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Shuffle a collection, using the modern version of the\n  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n  _.shuffle = function(obj) {\n    var set = isArrayLike(obj) ? obj : _.values(obj);\n    var length = set.length;\n    var shuffled = Array(length);\n    for (var index = 0, rand; index < length; index++) {\n      rand = _.random(0, index);\n      if (rand !== index) shuffled[index] = shuffled[rand];\n      shuffled[rand] = set[index];\n    }\n    return shuffled;\n  };\n\n  // Sample **n** random values from a collection.\n  // If **n** is not specified, returns a single random element.\n  // The internal `guard` argument allows it to work with `map`.\n  _.sample = function(obj, n, guard) {\n    if (n == null || guard) {\n      if (!isArrayLike(obj)) obj = _.values(obj);\n      return obj[_.random(obj.length - 1)];\n    }\n    return _.shuffle(obj).slice(0, Math.max(0, n));\n  };\n\n  // Sort the object's values by a criterion produced by an iteratee.\n  _.sortBy = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    return _.pluck(_.map(obj, function(value, index, list) {\n      return {\n        value: value,\n        index: index,\n        criteria: iteratee(value, index, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index - right.index;\n    }), 'value');\n  };\n\n  // An internal function used for aggregate \"group by\" operations.\n  var group = function(behavior) {\n    return function(obj, iteratee, context) {\n      var result = {};\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(value, index) {\n        var key = iteratee(value, index, obj);\n        behavior(result, value, key);\n      });\n      return result;\n    };\n  };\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  _.groupBy = group(function(result, value, key) {\n    if (_.has(result, key)) result[key].push(value); else result[key] = [value];\n  });\n\n  // Indexes the object's values by a criterion, similar to `groupBy`, but for\n  // when you know that your index values will be unique.\n  _.indexBy = group(function(result, value, key) {\n    result[key] = value;\n  });\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  _.countBy = group(function(result, value, key) {\n    if (_.has(result, key)) result[key]++; else result[key] = 1;\n  });\n\n  // Safely create a real, live array from anything iterable.\n  _.toArray = function(obj) {\n    if (!obj) return [];\n    if (_.isArray(obj)) return slice.call(obj);\n    if (isArrayLike(obj)) return _.map(obj, _.identity);\n    return _.values(obj);\n  };\n\n  // Return the number of elements in an object.\n  _.size = function(obj) {\n    if (obj == null) return 0;\n    return isArrayLike(obj) ? obj.length : _.keys(obj).length;\n  };\n\n  // Split a collection into two arrays: one whose elements all satisfy the given\n  // predicate, and one whose elements all do not satisfy the predicate.\n  _.partition = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var pass = [], fail = [];\n    _.each(obj, function(value, key, obj) {\n      (predicate(value, key, obj) ? pass : fail).push(value);\n    });\n    return [pass, fail];\n  };\n\n  // Array Functions\n  // ---------------\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. Aliased as `head` and `take`. The **guard** check\n  // allows it to work with `_.map`.\n  _.first = _.head = _.take = function(array, n, guard) {\n    if (array == null) return void 0;\n    if (n == null || guard) return array[0];\n    return _.initial(array, array.length - n);\n  };\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  _.initial = function(array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  };\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array.\n  _.last = function(array, n, guard) {\n    if (array == null) return void 0;\n    if (n == null || guard) return array[array.length - 1];\n    return _.rest(array, Math.max(0, array.length - n));\n  };\n\n  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.\n  // Especially useful on the arguments object. Passing an **n** will return\n  // the rest N values in the array.\n  _.rest = _.tail = _.drop = function(array, n, guard) {\n    return slice.call(array, n == null || guard ? 1 : n);\n  };\n\n  // Trim out all falsy values from an array.\n  _.compact = function(array) {\n    return _.filter(array, _.identity);\n  };\n\n  // Internal implementation of a recursive `flatten` function.\n  var flatten = function(input, shallow, strict, startIndex) {\n    var output = [], idx = 0;\n    for (var i = startIndex || 0, length = getLength(input); i < length; i++) {\n      var value = input[i];\n      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {\n        //flatten current level of array or arguments object\n        if (!shallow) value = flatten(value, shallow, strict);\n        var j = 0, len = value.length;\n        output.length += len;\n        while (j < len) {\n          output[idx++] = value[j++];\n        }\n      } else if (!strict) {\n        output[idx++] = value;\n      }\n    }\n    return output;\n  };\n\n  // Flatten out an array, either recursively (by default), or just one level.\n  _.flatten = function(array, shallow) {\n    return flatten(array, shallow, false);\n  };\n\n  // Return a version of the array that does not contain the specified value(s).\n  _.without = function(array) {\n    return _.difference(array, slice.call(arguments, 1));\n  };\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // Aliased as `unique`.\n  _.uniq = _.unique = function(array, isSorted, iteratee, context) {\n    if (!_.isBoolean(isSorted)) {\n      context = iteratee;\n      iteratee = isSorted;\n      isSorted = false;\n    }\n    if (iteratee != null) iteratee = cb(iteratee, context);\n    var result = [];\n    var seen = [];\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var value = array[i],\n          computed = iteratee ? iteratee(value, i, array) : value;\n      if (isSorted) {\n        if (!i || seen !== computed) result.push(value);\n        seen = computed;\n      } else if (iteratee) {\n        if (!_.contains(seen, computed)) {\n          seen.push(computed);\n          result.push(value);\n        }\n      } else if (!_.contains(result, value)) {\n        result.push(value);\n      }\n    }\n    return result;\n  };\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  _.union = function() {\n    return _.uniq(flatten(arguments, true, true));\n  };\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  _.intersection = function(array) {\n    var result = [];\n    var argsLength = arguments.length;\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var item = array[i];\n      if (_.contains(result, item)) continue;\n      for (var j = 1; j < argsLength; j++) {\n        if (!_.contains(arguments[j], item)) break;\n      }\n      if (j === argsLength) result.push(item);\n    }\n    return result;\n  };\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  _.difference = function(array) {\n    var rest = flatten(arguments, true, true, 1);\n    return _.filter(array, function(value){\n      return !_.contains(rest, value);\n    });\n  };\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  _.zip = function() {\n    return _.unzip(arguments);\n  };\n\n  // Complement of _.zip. Unzip accepts an array of arrays and groups\n  // each array's elements on shared indices\n  _.unzip = function(array) {\n    var length = array && _.max(array, getLength).length || 0;\n    var result = Array(length);\n\n    for (var index = 0; index < length; index++) {\n      result[index] = _.pluck(array, index);\n    }\n    return result;\n  };\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values.\n  _.object = function(list, values) {\n    var result = {};\n    for (var i = 0, length = getLength(list); i < length; i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  };\n\n  // Generator function to create the findIndex and findLastIndex functions\n  function createPredicateIndexFinder(dir) {\n    return function(array, predicate, context) {\n      predicate = cb(predicate, context);\n      var length = getLength(array);\n      var index = dir > 0 ? 0 : length - 1;\n      for (; index >= 0 && index < length; index += dir) {\n        if (predicate(array[index], index, array)) return index;\n      }\n      return -1;\n    };\n  }\n\n  // Returns the first index on an array-like that passes a predicate test\n  _.findIndex = createPredicateIndexFinder(1);\n  _.findLastIndex = createPredicateIndexFinder(-1);\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  _.sortedIndex = function(array, obj, iteratee, context) {\n    iteratee = cb(iteratee, context, 1);\n    var value = iteratee(obj);\n    var low = 0, high = getLength(array);\n    while (low < high) {\n      var mid = Math.floor((low + high) / 2);\n      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;\n    }\n    return low;\n  };\n\n  // Generator function to create the indexOf and lastIndexOf functions\n  function createIndexFinder(dir, predicateFind, sortedIndex) {\n    return function(array, item, idx) {\n      var i = 0, length = getLength(array);\n      if (typeof idx == 'number') {\n        if (dir > 0) {\n            i = idx >= 0 ? idx : Math.max(idx + length, i);\n        } else {\n            length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;\n        }\n      } else if (sortedIndex && idx && length) {\n        idx = sortedIndex(array, item);\n        return array[idx] === item ? idx : -1;\n      }\n      if (item !== item) {\n        idx = predicateFind(slice.call(array, i, length), _.isNaN);\n        return idx >= 0 ? idx + i : -1;\n      }\n      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {\n        if (array[idx] === item) return idx;\n      }\n      return -1;\n    };\n  }\n\n  // Return the position of the first occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);\n  _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](http://docs.python.org/library/functions.html#range).\n  _.range = function(start, stop, step) {\n    if (stop == null) {\n      stop = start || 0;\n      start = 0;\n    }\n    step = step || 1;\n\n    var length = Math.max(Math.ceil((stop - start) / step), 0);\n    var range = Array(length);\n\n    for (var idx = 0; idx < length; idx++, start += step) {\n      range[idx] = start;\n    }\n\n    return range;\n  };\n\n  // Function (ahem) Functions\n  // ------------------\n\n  // Determines whether to execute a function as a constructor\n  // or a normal function with the provided arguments\n  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {\n    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);\n    var self = baseCreate(sourceFunc.prototype);\n    var result = sourceFunc.apply(self, args);\n    if (_.isObject(result)) return result;\n    return self;\n  };\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if\n  // available.\n  _.bind = function(func, context) {\n    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));\n    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');\n    var args = slice.call(arguments, 2);\n    var bound = function() {\n      return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));\n    };\n    return bound;\n  };\n\n  // Partially apply a function by creating a version that has had some of its\n  // arguments pre-filled, without changing its dynamic `this` context. _ acts\n  // as a placeholder, allowing any combination of arguments to be pre-filled.\n  _.partial = function(func) {\n    var boundArgs = slice.call(arguments, 1);\n    var bound = function() {\n      var position = 0, length = boundArgs.length;\n      var args = Array(length);\n      for (var i = 0; i < length; i++) {\n        args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];\n      }\n      while (position < arguments.length) args.push(arguments[position++]);\n      return executeBound(func, bound, this, this, args);\n    };\n    return bound;\n  };\n\n  // Bind a number of an object's methods to that object. Remaining arguments\n  // are the method names to be bound. Useful for ensuring that all callbacks\n  // defined on an object belong to it.\n  _.bindAll = function(obj) {\n    var i, length = arguments.length, key;\n    if (length <= 1) throw new Error('bindAll must be passed function names');\n    for (i = 1; i < length; i++) {\n      key = arguments[i];\n      obj[key] = _.bind(obj[key], obj);\n    }\n    return obj;\n  };\n\n  // Memoize an expensive function by storing its results.\n  _.memoize = function(func, hasher) {\n    var memoize = function(key) {\n      var cache = memoize.cache;\n      var address = '' + (hasher ? hasher.apply(this, arguments) : key);\n      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);\n      return cache[address];\n    };\n    memoize.cache = {};\n    return memoize;\n  };\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  _.delay = function(func, wait) {\n    var args = slice.call(arguments, 2);\n    return setTimeout(function(){\n      return func.apply(null, args);\n    }, wait);\n  };\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  _.defer = _.partial(_.delay, _, 1);\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time. Normally, the throttled function will run\n  // as much as it can, without ever going more than once per `wait` duration;\n  // but if you'd like to disable the execution on the leading edge, pass\n  // `{leading: false}`. To disable execution on the trailing edge, ditto.\n  _.throttle = function(func, wait, options) {\n    var context, args, result;\n    var timeout = null;\n    var previous = 0;\n    if (!options) options = {};\n    var later = function() {\n      previous = options.leading === false ? 0 : _.now();\n      timeout = null;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    };\n    return function() {\n      var now = _.now();\n      if (!previous && options.leading === false) previous = now;\n      var remaining = wait - (now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0 || remaining > wait) {\n        if (timeout) {\n          clearTimeout(timeout);\n          timeout = null;\n        }\n        previous = now;\n        result = func.apply(context, args);\n        if (!timeout) context = args = null;\n      } else if (!timeout && options.trailing !== false) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n  };\n\n  // Returns a function, that, as long as it continues to be invoked, will not\n  // be triggered. The function will be called after it stops being called for\n  // N milliseconds. If `immediate` is passed, trigger the function on the\n  // leading edge, instead of the trailing.\n  _.debounce = function(func, wait, immediate) {\n    var timeout, args, context, timestamp, result;\n\n    var later = function() {\n      var last = _.now() - timestamp;\n\n      if (last < wait && last >= 0) {\n        timeout = setTimeout(later, wait - last);\n      } else {\n        timeout = null;\n        if (!immediate) {\n          result = func.apply(context, args);\n          if (!timeout) context = args = null;\n        }\n      }\n    };\n\n    return function() {\n      context = this;\n      args = arguments;\n      timestamp = _.now();\n      var callNow = immediate && !timeout;\n      if (!timeout) timeout = setTimeout(later, wait);\n      if (callNow) {\n        result = func.apply(context, args);\n        context = args = null;\n      }\n\n      return result;\n    };\n  };\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  _.wrap = function(func, wrapper) {\n    return _.partial(wrapper, func);\n  };\n\n  // Returns a negated version of the passed-in predicate.\n  _.negate = function(predicate) {\n    return function() {\n      return !predicate.apply(this, arguments);\n    };\n  };\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  _.compose = function() {\n    var args = arguments;\n    var start = args.length - 1;\n    return function() {\n      var i = start;\n      var result = args[start].apply(this, arguments);\n      while (i--) result = args[i].call(this, result);\n      return result;\n    };\n  };\n\n  // Returns a function that will only be executed on and after the Nth call.\n  _.after = function(times, func) {\n    return function() {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  };\n\n  // Returns a function that will only be executed up to (but not including) the Nth call.\n  _.before = function(times, func) {\n    var memo;\n    return function() {\n      if (--times > 0) {\n        memo = func.apply(this, arguments);\n      }\n      if (times <= 1) func = null;\n      return memo;\n    };\n  };\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  _.once = _.partial(_.before, 2);\n\n  // Object Functions\n  // ----------------\n\n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');\n  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',\n                      'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n\n  function collectNonEnumProps(obj, keys) {\n    var nonEnumIdx = nonEnumerableProps.length;\n    var constructor = obj.constructor;\n    var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;\n\n    // Constructor is a special case.\n    var prop = 'constructor';\n    if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);\n\n    while (nonEnumIdx--) {\n      prop = nonEnumerableProps[nonEnumIdx];\n      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {\n        keys.push(prop);\n      }\n    }\n  }\n\n  // Retrieve the names of an object's own properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`\n  _.keys = function(obj) {\n    if (!_.isObject(obj)) return [];\n    if (nativeKeys) return nativeKeys(obj);\n    var keys = [];\n    for (var key in obj) if (_.has(obj, key)) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve all the property names of an object.\n  _.allKeys = function(obj) {\n    if (!_.isObject(obj)) return [];\n    var keys = [];\n    for (var key in obj) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve the values of an object's properties.\n  _.values = function(obj) {\n    var keys = _.keys(obj);\n    var length = keys.length;\n    var values = Array(length);\n    for (var i = 0; i < length; i++) {\n      values[i] = obj[keys[i]];\n    }\n    return values;\n  };\n\n  // Returns the results of applying the iteratee to each element of the object\n  // In contrast to _.map it returns an object\n  _.mapObject = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys =  _.keys(obj),\n          length = keys.length,\n          results = {},\n          currentKey;\n      for (var index = 0; index < length; index++) {\n        currentKey = keys[index];\n        results[currentKey] = iteratee(obj[currentKey], currentKey, obj);\n      }\n      return results;\n  };\n\n  // Convert an object into a list of `[key, value]` pairs.\n  _.pairs = function(obj) {\n    var keys = _.keys(obj);\n    var length = keys.length;\n    var pairs = Array(length);\n    for (var i = 0; i < length; i++) {\n      pairs[i] = [keys[i], obj[keys[i]]];\n    }\n    return pairs;\n  };\n\n  // Invert the keys and values of an object. The values must be serializable.\n  _.invert = function(obj) {\n    var result = {};\n    var keys = _.keys(obj);\n    for (var i = 0, length = keys.length; i < length; i++) {\n      result[obj[keys[i]]] = keys[i];\n    }\n    return result;\n  };\n\n  // Return a sorted list of the function names available on the object.\n  // Aliased as `methods`\n  _.functions = _.methods = function(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (_.isFunction(obj[key])) names.push(key);\n    }\n    return names.sort();\n  };\n\n  // Extend a given object with all the properties in passed-in object(s).\n  _.extend = createAssigner(_.allKeys);\n\n  // Assigns a given object with all the own properties in the passed-in object(s)\n  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  _.extendOwn = _.assign = createAssigner(_.keys);\n\n  // Returns the first key on an object that passes a predicate test\n  _.findKey = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = _.keys(obj), key;\n    for (var i = 0, length = keys.length; i < length; i++) {\n      key = keys[i];\n      if (predicate(obj[key], key, obj)) return key;\n    }\n  };\n\n  // Return a copy of the object only containing the allowed properties.\n  _.pick = function(object, oiteratee, context) {\n    var result = {}, obj = object, iteratee, keys;\n    if (obj == null) return result;\n    if (_.isFunction(oiteratee)) {\n      keys = _.allKeys(obj);\n      iteratee = optimizeCb(oiteratee, context);\n    } else {\n      keys = flatten(arguments, false, false, 1);\n      iteratee = function(value, key, obj) { return key in obj; };\n      obj = Object(obj);\n    }\n    for (var i = 0, length = keys.length; i < length; i++) {\n      var key = keys[i];\n      var value = obj[key];\n      if (iteratee(value, key, obj)) result[key] = value;\n    }\n    return result;\n  };\n\n   // Return a copy of the object without the disallowed properties.\n  _.omit = function(obj, iteratee, context) {\n    if (_.isFunction(iteratee)) {\n      iteratee = _.negate(iteratee);\n    } else {\n      var keys = _.map(flatten(arguments, false, false, 1), String);\n      iteratee = function(value, key) {\n        return !_.contains(keys, key);\n      };\n    }\n    return _.pick(obj, iteratee, context);\n  };\n\n  // Fill in a given object with default properties.\n  _.defaults = createAssigner(_.allKeys, true);\n\n  // Creates an object that inherits from the given prototype object.\n  // If additional properties are provided then they will be added to the\n  // created object.\n  _.create = function(prototype, props) {\n    var result = baseCreate(prototype);\n    if (props) _.extendOwn(result, props);\n    return result;\n  };\n\n  // Create a (shallow-cloned) duplicate of an object.\n  _.clone = function(obj) {\n    if (!_.isObject(obj)) return obj;\n    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\n  };\n\n  // Invokes interceptor with the obj, and then returns obj.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  _.tap = function(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  };\n\n  // Returns whether an object has a given set of `key:value` pairs.\n  _.isMatch = function(object, attrs) {\n    var keys = _.keys(attrs), length = keys.length;\n    if (object == null) return !length;\n    var obj = Object(object);\n    for (var i = 0; i < length; i++) {\n      var key = keys[i];\n      if (attrs[key] !== obj[key] || !(key in obj)) return false;\n    }\n    return true;\n  };\n\n\n  // Internal recursive comparison function for `isEqual`.\n  var eq = function(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) return a !== 0 || 1 / a === 1 / b;\n    // A strict comparison is necessary because `null == undefined`.\n    if (a == null || b == null) return a === b;\n    // Unwrap any wrapped objects.\n    if (a instanceof _) a = a._wrapped;\n    if (b instanceof _) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className !== toString.call(b)) return false;\n    switch (className) {\n      // Strings, numbers, regular expressions, dates, and booleans are compared by value.\n      case '[object RegExp]':\n      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return '' + a === '' + b;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive.\n        // Object(NaN) is equivalent to NaN\n        if (+a !== +a) return +b !== +b;\n        // An `egal` comparison is performed for other numeric values.\n        return +a === 0 ? 1 / +a === 1 / b : +a === +b;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a === +b;\n    }\n\n    var areArrays = className === '[object Array]';\n    if (!areArrays) {\n      if (typeof a != 'object' || typeof b != 'object') return false;\n\n      // Objects with different constructors are not equivalent, but `Object`s or `Array`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&\n                               _.isFunction(bCtor) && bCtor instanceof bCtor)\n                          && ('constructor' in a && 'constructor' in b)) {\n        return false;\n      }\n    }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n\n    // Initializing stack of traversed objects.\n    // It's done here since we only need them for objects and arrays comparison.\n    aStack = aStack || [];\n    bStack = bStack || [];\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] === a) return bStack[length] === b;\n    }\n\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n\n    // Recursively compare objects and arrays.\n    if (areArrays) {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      length = a.length;\n      if (length !== b.length) return false;\n      // Deep compare the contents, ignoring non-numeric properties.\n      while (length--) {\n        if (!eq(a[length], b[length], aStack, bStack)) return false;\n      }\n    } else {\n      // Deep compare objects.\n      var keys = _.keys(a), key;\n      length = keys.length;\n      // Ensure that both objects contain the same number of properties before comparing deep equality.\n      if (_.keys(b).length !== length) return false;\n      while (length--) {\n        // Deep compare each member\n        key = keys[length];\n        if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return true;\n  };\n\n  // Perform a deep comparison to check if two objects are equal.\n  _.isEqual = function(a, b) {\n    return eq(a, b);\n  };\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  _.isEmpty = function(obj) {\n    if (obj == null) return true;\n    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;\n    return _.keys(obj).length === 0;\n  };\n\n  // Is a given value a DOM element?\n  _.isElement = function(obj) {\n    return !!(obj && obj.nodeType === 1);\n  };\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native Array.isArray\n  _.isArray = nativeIsArray || function(obj) {\n    return toString.call(obj) === '[object Array]';\n  };\n\n  // Is a given variable an object?\n  _.isObject = function(obj) {\n    var type = typeof obj;\n    return type === 'function' || type === 'object' && !!obj;\n  };\n\n  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.\n  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {\n    _['is' + name] = function(obj) {\n      return toString.call(obj) === '[object ' + name + ']';\n    };\n  });\n\n  // Define a fallback version of the method in browsers (ahem, IE < 9), where\n  // there isn't any inspectable \"Arguments\" type.\n  if (!_.isArguments(arguments)) {\n    _.isArguments = function(obj) {\n      return _.has(obj, 'callee');\n    };\n  }\n\n  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,\n  // IE 11 (#1621), and in Safari 8 (#1929).\n  if (typeof /./ != 'function' && typeof Int8Array != 'object') {\n    _.isFunction = function(obj) {\n      return typeof obj == 'function' || false;\n    };\n  }\n\n  // Is a given object a finite number?\n  _.isFinite = function(obj) {\n    return isFinite(obj) && !isNaN(parseFloat(obj));\n  };\n\n  // Is the given value `NaN`? (NaN is the only number which does not equal itself).\n  _.isNaN = function(obj) {\n    return _.isNumber(obj) && obj !== +obj;\n  };\n\n  // Is a given value a boolean?\n  _.isBoolean = function(obj) {\n    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';\n  };\n\n  // Is a given value equal to null?\n  _.isNull = function(obj) {\n    return obj === null;\n  };\n\n  // Is a given variable undefined?\n  _.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  // Shortcut function for checking if an object has a given property directly\n  // on itself (in other words, not on a prototype).\n  _.has = function(obj, key) {\n    return obj != null && hasOwnProperty.call(obj, key);\n  };\n\n  // Utility Functions\n  // -----------------\n\n  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n  // previous owner. Returns a reference to the Underscore object.\n  _.noConflict = function() {\n    root._ = previousUnderscore;\n    return this;\n  };\n\n  // Keep the identity function around for default iteratees.\n  _.identity = function(value) {\n    return value;\n  };\n\n  // Predicate-generating functions. Often useful outside of Underscore.\n  _.constant = function(value) {\n    return function() {\n      return value;\n    };\n  };\n\n  _.noop = function(){};\n\n  _.property = property;\n\n  // Generates a function for a given object that returns a given property.\n  _.propertyOf = function(obj) {\n    return obj == null ? function(){} : function(key) {\n      return obj[key];\n    };\n  };\n\n  // Returns a predicate for checking whether an object has a given set of\n  // `key:value` pairs.\n  _.matcher = _.matches = function(attrs) {\n    attrs = _.extendOwn({}, attrs);\n    return function(obj) {\n      return _.isMatch(obj, attrs);\n    };\n  };\n\n  // Run a function **n** times.\n  _.times = function(n, iteratee, context) {\n    var accum = Array(Math.max(0, n));\n    iteratee = optimizeCb(iteratee, context, 1);\n    for (var i = 0; i < n; i++) accum[i] = iteratee(i);\n    return accum;\n  };\n\n  // Return a random integer between min and max (inclusive).\n  _.random = function(min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + Math.floor(Math.random() * (max - min + 1));\n  };\n\n  // A (possibly faster) way to get the current timestamp as an integer.\n  _.now = Date.now || function() {\n    return new Date().getTime();\n  };\n\n   // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  var unescapeMap = _.invert(escapeMap);\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped\n    var source = '(?:' + _.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n  _.escape = createEscaper(escapeMap);\n  _.unescape = createEscaper(unescapeMap);\n\n  // If the value of the named `property` is a function then invoke it with the\n  // `object` as context; otherwise, return it.\n  _.result = function(object, property, fallback) {\n    var value = object == null ? void 0 : object[property];\n    if (value === void 0) {\n      value = fallback;\n    }\n    return _.isFunction(value) ? value.call(object) : value;\n  };\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  _.uniqueId = function(prefix) {\n    var id = ++idCounter + '';\n    return prefix ? prefix + id : id;\n  };\n\n  // By default, Underscore uses ERB-style template delimiters, change the\n  // following template settings to use alternative delimiters.\n  _.templateSettings = {\n    evaluate    : /<%([\\s\\S]+?)%>/g,\n    interpolate : /<%=([\\s\\S]+?)%>/g,\n    escape      : /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\":      \"'\",\n    '\\\\':     '\\\\',\n    '\\r':     'r',\n    '\\n':     'n',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  var escaper = /\\\\|'|\\r|\\n|\\u2028|\\u2029/g;\n\n  var escapeChar = function(match) {\n    return '\\\\' + escapes[match];\n  };\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  // NB: `oldSettings` only exists for backwards compatibility.\n  _.template = function(text, settings, oldSettings) {\n    if (!settings && oldSettings) settings = oldSettings;\n    settings = _.defaults({}, settings, _.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = RegExp([\n      (settings.escape || noMatch).source,\n      (settings.interpolate || noMatch).source,\n      (settings.evaluate || noMatch).source\n    ].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset).replace(escaper, escapeChar);\n      index = offset + match.length;\n\n      if (escape) {\n        source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n      } else if (interpolate) {\n        source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n      } else if (evaluate) {\n        source += \"';\\n\" + evaluate + \"\\n__p+='\";\n      }\n\n      // Adobe VMs need the match returned to produce the correct offest.\n      return match;\n    });\n    source += \"';\\n\";\n\n    // If a variable is not specified, place data values in local scope.\n    if (!settings.variable) source = 'with(obj||{}){\\n' + source + '}\\n';\n\n    source = \"var __t,__p='',__j=Array.prototype.join,\" +\n      \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n      source + 'return __p;\\n';\n\n    try {\n      var render = new Function(settings.variable || 'obj', '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n\n    var template = function(data) {\n      return render.call(this, data, _);\n    };\n\n    // Provide the compiled source as a convenience for precompilation.\n    var argument = settings.variable || 'obj';\n    template.source = 'function(' + argument + '){\\n' + source + '}';\n\n    return template;\n  };\n\n  // Add a \"chain\" function. Start chaining a wrapped Underscore object.\n  _.chain = function(obj) {\n    var instance = _(obj);\n    instance._chain = true;\n    return instance;\n  };\n\n  // OOP\n  // ---------------\n  // If Underscore is called as a function, it returns a wrapped object that\n  // can be used OO-style. This wrapper holds altered versions of all the\n  // underscore functions. Wrapped objects may be chained.\n\n  // Helper function to continue chaining intermediate results.\n  var result = function(instance, obj) {\n    return instance._chain ? _(obj).chain() : obj;\n  };\n\n  // Add your own custom functions to the Underscore object.\n  _.mixin = function(obj) {\n    _.each(_.functions(obj), function(name) {\n      var func = _[name] = obj[name];\n      _.prototype[name] = function() {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return result(this, func.apply(_, args));\n      };\n    });\n  };\n\n  // Add all of the Underscore functions to the wrapper object.\n  _.mixin(_);\n\n  // Add all mutator Array functions to the wrapper.\n  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      var obj = this._wrapped;\n      method.apply(obj, arguments);\n      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];\n      return result(this, obj);\n    };\n  });\n\n  // Add all accessor Array functions to the wrapper.\n  _.each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      return result(this, method.apply(this._wrapped, arguments));\n    };\n  });\n\n  // Extracts the result from a wrapped and chained object.\n  _.prototype.value = function() {\n    return this._wrapped;\n  };\n\n  // Provide unwrapping proxy for some methods used in engine operations\n  // such as arithmetic and JSON stringification.\n  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;\n\n  _.prototype.toString = function() {\n    return '' + this._wrapped;\n  };\n\n  // AMD registration happens at the end for compatibility with AMD loaders\n  // that may not enforce next-turn semantics on modules. Even though general\n  // practice for AMD registration is to be anonymous, underscore registers\n  // as a named module because, like jQuery, it is a base library that is\n  // popular enough to be bundled in a third party lib, but not be part of\n  // an AMD load request. Those cases could generate an error when an\n  // anonymous define() is called outside of a loader request.\n  if (typeof define === 'function' && define.amd) {\n    define('underscore', [], function() {\n      return _;\n    });\n  }\n}.call(this));\n"
  },
  {
    "path": "test/view.js",
    "content": "(function(QUnit) {\n\n  var view;\n\n  QUnit.module('Backbone.View', {\n\n    beforeEach: function() {\n      $('#qunit-fixture').append(\n        '<div id=\"testElement\"><h1>Test</h1></div>'\n      );\n\n      view = new Backbone.View({\n        id: 'test-view',\n        className: 'test-view',\n        other: 'non-special-option'\n      });\n    },\n\n    afterEach: function() {\n      $('#testElement').remove();\n      $('#test-view').remove();\n    }\n\n  });\n\n  QUnit.test('constructor', function(assert) {\n    assert.expect(3);\n    assert.equal(view.el.id, 'test-view');\n    assert.equal(view.el.className, 'test-view');\n    assert.equal(view.el.other, void 0);\n  });\n\n  QUnit.test('$', function(assert) {\n    assert.expect(2);\n    var myView = new Backbone.View;\n    myView.setElement('<p><a><b>test</b></a></p>');\n    var result = myView.$('a b');\n\n    assert.strictEqual(result[0].innerHTML, 'test');\n    assert.ok(result.length === +result.length);\n  });\n\n  QUnit.test('$el', function(assert) {\n    assert.expect(3);\n    var myView = new Backbone.View;\n    myView.setElement('<p><a><b>test</b></a></p>');\n    assert.strictEqual(myView.el.nodeType, 1);\n\n    assert.ok(myView.$el instanceof Backbone.$);\n    assert.strictEqual(myView.$el[0], myView.el);\n  });\n\n  QUnit.test('initialize', function(assert) {\n    assert.expect(1);\n    var View = Backbone.View.extend({\n      initialize: function() {\n        this.one = 1;\n      }\n    });\n\n    assert.strictEqual(new View().one, 1);\n  });\n\n  QUnit.test('preinitialize', function(assert) {\n    assert.expect(1);\n    var View = Backbone.View.extend({\n      preinitialize: function() {\n        this.one = 1;\n      }\n    });\n\n    assert.strictEqual(new View().one, 1);\n  });\n\n  QUnit.test('preinitialize occurs before the view is set up', function(assert) {\n    assert.expect(2);\n    var View = Backbone.View.extend({\n      preinitialize: function() {\n        assert.equal(this.el, undefined);\n      }\n    });\n    var _view = new View({});\n    assert.notEqual(_view.el, undefined);\n  });\n\n  QUnit.test('render', function(assert) {\n    assert.expect(1);\n    var myView = new Backbone.View;\n    assert.equal(myView.render(), myView, '#render returns the view instance');\n  });\n\n  QUnit.test('delegateEvents', function(assert) {\n    assert.expect(6);\n    var counter1 = 0, counter2 = 0;\n\n    var myView = new Backbone.View({el: '#testElement'});\n    myView.increment = function() { counter1++; };\n    myView.$el.on('click', function() { counter2++; });\n\n    var events = {'click h1': 'increment'};\n\n    myView.delegateEvents(events);\n    myView.$('h1').trigger('click');\n    assert.equal(counter1, 1);\n    assert.equal(counter2, 1);\n\n    myView.$('h1').trigger('click');\n    assert.equal(counter1, 2);\n    assert.equal(counter2, 2);\n\n    myView.delegateEvents(events);\n    myView.$('h1').trigger('click');\n    assert.equal(counter1, 3);\n    assert.equal(counter2, 3);\n  });\n\n  QUnit.test('delegate', function(assert) {\n    assert.expect(3);\n    var myView = new Backbone.View({el: '#testElement'});\n    myView.delegate('click', 'h1', function() {\n      assert.ok(true);\n    });\n    myView.delegate('click', function() {\n      assert.ok(true);\n    });\n    myView.$('h1').trigger('click');\n\n    assert.equal(myView.delegate(), myView, '#delegate returns the view instance');\n  });\n\n  QUnit.test('delegateEvents allows functions for callbacks', function(assert) {\n    assert.expect(3);\n    var myView = new Backbone.View({el: '<p></p>'});\n    myView.counter = 0;\n\n    var events = {\n      click: function() {\n        this.counter++;\n      }\n    };\n\n    myView.delegateEvents(events);\n    myView.$el.trigger('click');\n    assert.equal(myView.counter, 1);\n\n    myView.$el.trigger('click');\n    assert.equal(myView.counter, 2);\n\n    myView.delegateEvents(events);\n    myView.$el.trigger('click');\n    assert.equal(myView.counter, 3);\n  });\n\n  QUnit.test('delegateEvents ignore undefined methods', function(assert) {\n    assert.expect(0);\n    var myView = new Backbone.View({el: '<p></p>'});\n    myView.delegateEvents({click: 'undefinedMethod'});\n    myView.$el.trigger('click');\n  });\n\n  QUnit.test('undelegateEvents', function(assert) {\n    assert.expect(7);\n    var counter1 = 0, counter2 = 0;\n\n    var myView = new Backbone.View({el: '#testElement'});\n    myView.increment = function() { counter1++; };\n    myView.$el.on('click', function() { counter2++; });\n\n    var events = {'click h1': 'increment'};\n\n    myView.delegateEvents(events);\n    myView.$('h1').trigger('click');\n    assert.equal(counter1, 1);\n    assert.equal(counter2, 1);\n\n    myView.undelegateEvents();\n    myView.$('h1').trigger('click');\n    assert.equal(counter1, 1);\n    assert.equal(counter2, 2);\n\n    myView.delegateEvents(events);\n    myView.$('h1').trigger('click');\n    assert.equal(counter1, 2);\n    assert.equal(counter2, 3);\n\n    assert.equal(myView.undelegateEvents(), myView, '#undelegateEvents returns the view instance');\n  });\n\n  QUnit.test('undelegate', function(assert) {\n    assert.expect(1);\n    var myView = new Backbone.View({el: '#testElement'});\n    myView.delegate('click', function() { assert.ok(false); });\n    myView.delegate('click', 'h1', function() { assert.ok(false); });\n\n    myView.undelegate('click');\n\n    myView.$('h1').trigger('click');\n    myView.$el.trigger('click');\n\n    assert.equal(myView.undelegate(), myView, '#undelegate returns the view instance');\n  });\n\n  QUnit.test('undelegate with passed handler', function(assert) {\n    assert.expect(1);\n    var myView = new Backbone.View({el: '#testElement'});\n    var listener = function() { assert.ok(false); };\n    myView.delegate('click', listener);\n    myView.delegate('click', function() { assert.ok(true); });\n    myView.undelegate('click', listener);\n    myView.$el.trigger('click');\n  });\n\n  QUnit.test('undelegate with selector', function(assert) {\n    assert.expect(2);\n    var myView = new Backbone.View({el: '#testElement'});\n    myView.delegate('click', function() { assert.ok(true); });\n    myView.delegate('click', 'h1', function() { assert.ok(false); });\n    myView.undelegate('click', 'h1');\n    myView.$('h1').trigger('click');\n    myView.$el.trigger('click');\n  });\n\n  QUnit.test('undelegate with handler and selector', function(assert) {\n    assert.expect(2);\n    var myView = new Backbone.View({el: '#testElement'});\n    myView.delegate('click', function() { assert.ok(true); });\n    var handler = function() { assert.ok(false); };\n    myView.delegate('click', 'h1', handler);\n    myView.undelegate('click', 'h1', handler);\n    myView.$('h1').trigger('click');\n    myView.$el.trigger('click');\n  });\n\n  QUnit.test('tagName can be provided as a string', function(assert) {\n    assert.expect(1);\n    var View = Backbone.View.extend({\n      tagName: 'span'\n    });\n\n    assert.equal(new View().el.tagName, 'SPAN');\n  });\n\n  QUnit.test('tagName can be provided as a function', function(assert) {\n    assert.expect(1);\n    var View = Backbone.View.extend({\n      tagName: function() {\n        return 'p';\n      }\n    });\n\n    assert.ok(new View().$el.is('p'));\n  });\n\n  QUnit.test('_ensureElement with DOM node el', function(assert) {\n    assert.expect(1);\n    var View = Backbone.View.extend({\n      el: document.body\n    });\n\n    assert.equal(new View().el, document.body);\n  });\n\n  QUnit.test('_ensureElement with string el', function(assert) {\n    assert.expect(3);\n    var View = Backbone.View.extend({\n      el: 'body'\n    });\n    assert.strictEqual(new View().el, document.body);\n\n    View = Backbone.View.extend({\n      el: '#testElement > h1'\n    });\n    assert.strictEqual(new View().el, $('#testElement > h1').get(0));\n\n    View = Backbone.View.extend({\n      el: '#nonexistent'\n    });\n    assert.ok(!new View().el);\n  });\n\n  QUnit.test('with className and id functions', function(assert) {\n    assert.expect(2);\n    var View = Backbone.View.extend({\n      className: function() {\n        return 'className';\n      },\n      id: function() {\n        return 'id';\n      }\n    });\n\n    assert.strictEqual(new View().el.className, 'className');\n    assert.strictEqual(new View().el.id, 'id');\n  });\n\n  QUnit.test('with attributes', function(assert) {\n    assert.expect(2);\n    var View = Backbone.View.extend({\n      attributes: {\n        'id': 'id',\n        'class': 'class'\n      }\n    });\n\n    assert.strictEqual(new View().el.className, 'class');\n    assert.strictEqual(new View().el.id, 'id');\n  });\n\n  QUnit.test('with attributes as a function', function(assert) {\n    assert.expect(1);\n    var View = Backbone.View.extend({\n      attributes: function() {\n        return {'class': 'dynamic'};\n      }\n    });\n\n    assert.strictEqual(new View().el.className, 'dynamic');\n  });\n\n  QUnit.test('should default to className/id properties', function(assert) {\n    assert.expect(4);\n    var View = Backbone.View.extend({\n      className: 'backboneClass',\n      id: 'backboneId',\n      attributes: {\n        'class': 'attributeClass',\n        'id': 'attributeId'\n      }\n    });\n\n    var myView = new View;\n    assert.strictEqual(myView.el.className, 'backboneClass');\n    assert.strictEqual(myView.el.id, 'backboneId');\n    assert.strictEqual(myView.$el.attr('class'), 'backboneClass');\n    assert.strictEqual(myView.$el.attr('id'), 'backboneId');\n  });\n\n  QUnit.test('multiple views per element', function(assert) {\n    assert.expect(3);\n    var count = 0;\n    var $el = $('<p></p>');\n\n    var View = Backbone.View.extend({\n      el: $el,\n      events: {\n        click: function() {\n          count++;\n        }\n      }\n    });\n\n    var view1 = new View;\n    $el.trigger('click');\n    assert.equal(1, count);\n\n    var view2 = new View;\n    $el.trigger('click');\n    assert.equal(3, count);\n\n    view1.delegateEvents();\n    $el.trigger('click');\n    assert.equal(5, count);\n  });\n\n  QUnit.test('custom events', function(assert) {\n    assert.expect(2);\n    var View = Backbone.View.extend({\n      el: $('body'),\n      events: {\n        fake$event: function() { assert.ok(true); }\n      }\n    });\n\n    var myView = new View;\n    $('body').trigger('fake$event').trigger('fake$event');\n\n    $('body').off('fake$event');\n    $('body').trigger('fake$event');\n  });\n\n  QUnit.test('#1048 - setElement uses provided object.', function(assert) {\n    assert.expect(2);\n    var $el = $('body');\n\n    var myView = new Backbone.View({el: $el});\n    assert.ok(myView.$el === $el);\n\n    myView.setElement($el = $($el));\n    assert.ok(myView.$el === $el);\n  });\n\n  QUnit.test('#986 - Undelegate before changing element.', function(assert) {\n    assert.expect(1);\n    var button1 = $('<button></button>');\n    var button2 = $('<button></button>');\n\n    var View = Backbone.View.extend({\n      events: {\n        click: function(e) {\n          assert.ok(myView.el === e.target);\n        }\n      }\n    });\n\n    var myView = new View({el: button1});\n    myView.setElement(button2);\n\n    button1.trigger('click');\n    button2.trigger('click');\n  });\n\n  QUnit.test('#1172 - Clone attributes object', function(assert) {\n    assert.expect(2);\n    var View = Backbone.View.extend({\n      attributes: {foo: 'bar'}\n    });\n\n    var view1 = new View({id: 'foo'});\n    assert.strictEqual(view1.el.id, 'foo');\n\n    var view2 = new View();\n    assert.ok(!view2.el.id);\n  });\n\n  QUnit.test('views stopListening', function(assert) {\n    assert.expect(0);\n    var View = Backbone.View.extend({\n      initialize: function() {\n        this.listenTo(this.model, 'all x', function() { assert.ok(false); });\n        this.listenTo(this.collection, 'all x', function() { assert.ok(false); });\n      }\n    });\n\n    var myView = new View({\n      model: new Backbone.Model,\n      collection: new Backbone.Collection\n    });\n\n    myView.stopListening();\n    myView.model.trigger('x');\n    myView.collection.trigger('x');\n  });\n\n  QUnit.test('Provide function for el.', function(assert) {\n    assert.expect(2);\n    var View = Backbone.View.extend({\n      el: function() {\n        return '<p><a></a></p>';\n      }\n    });\n\n    var myView = new View;\n    assert.ok(myView.$el.is('p'));\n    assert.ok(myView.$el.has('a'));\n  });\n\n  QUnit.test('events passed in options', function(assert) {\n    assert.expect(1);\n    var counter = 0;\n\n    var View = Backbone.View.extend({\n      el: '#testElement',\n      increment: function() {\n        counter++;\n      }\n    });\n\n    var myView = new View({\n      events: {\n        'click h1': 'increment'\n      }\n    });\n\n    myView.$('h1').trigger('click').trigger('click');\n    assert.equal(counter, 2);\n  });\n\n  QUnit.test('remove', function(assert) {\n    assert.expect(2);\n    var myView = new Backbone.View;\n    document.body.appendChild(view.el);\n\n    myView.delegate('click', function() { assert.ok(false); });\n    myView.listenTo(myView, 'all x', function() { assert.ok(false); });\n\n    assert.equal(myView.remove(), myView, '#remove returns the view instance');\n    myView.$el.trigger('click');\n    myView.trigger('x');\n\n    // In IE8 and below, parentNode still exists but is not document.body.\n    assert.notEqual(myView.el.parentNode, document.body);\n  });\n\n  QUnit.test('setElement', function(assert) {\n    assert.expect(3);\n    var myView = new Backbone.View({\n      events: {\n        click: function() { assert.ok(false); }\n      }\n    });\n    myView.events = {\n      click: function() { assert.ok(true); }\n    };\n    var oldEl = myView.el;\n    var $oldEl = myView.$el;\n\n    myView.setElement(document.createElement('div'));\n\n    $oldEl.click();\n    myView.$el.click();\n\n    assert.notEqual(oldEl, myView.el);\n    assert.notEqual($oldEl, myView.$el);\n  });\n\n})(QUnit);\n"
  }
]