JGoogleAnalytics_0.3.jar APL 2.0 License - http://code.google.com/p/jgoogleanalytics/
Jmol-14.2.14_2015.06.11.jar GPL/LGPLv2 http://sourceforge.net/projects/jmol/files/
-VARNAv3-91.jar GPL licenced software by K�vin Darty, Alain Denise and Yann Ponty. http://varna.lri.fr
+VARNAv3-93.jar GPL licenced software by K�vin Darty, Alain Denise and Yann Ponty. http://varna.lri.fr
activation.jar
apache-mime4j-0.6.jar
axis.jar
<property name="outputJar" value="jalview.jar" />
<!-- Jalview Applet JMol Jar Dependency -->
<property name="jmolJar" value="JmolApplet-14.2.14_2015.06.01.jar" />
- <property name="varnaJar" value="VARNAv3-91.jar" />
+ <property name="varnaJar" value="VARNAv3-93.jar" />
<property name="jsoup" value="jsoup-1.8.1.jar" />
<property name="jsonSimple" value="json_simple-1.1.jar" />
<property name="javaJson" value="java-json.jar" />
--- /dev/null
+.idea
+docson.iml
+/nbproject
--- /dev/null
+Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
--- /dev/null
+<p align='right'>A <a href="http://www.swisspush.org">swisspush</a> project <a href="http://www.swisspush.org" border=0><img align="top" src='https://1.gravatar.com/avatar/cf7292487846085732baf808def5685a?s=32'></a></p>
+Docson
+======
+
+Documentation for your JSON types.
+
+Give Docson a JSON schema and it will generate a [beautiful documentation](http://lbovet.github.io/docson/index.html#/docson/examples/example.json).
+
+## Features
+* [JSON schema](http://json-schema.org/) v4 keywords.
+* Runs entirely in the browser.
+* Render schema descriptions with markdown
+
+## Installation
+
+* Place the Docson distribution on the web server serving the schemas (to avoid cross-origin issues).
+
+## Usage
+
+* Open [index.html](http://lbovet.github.io/docson/index.html) and enter the schema path in the form field.
+* Or give the schema path directly as hash parameter: [index.html#/docson/examples/example.json](http://lbovet.github.io/docson/index.html#/docson/examples/example.json)
+
+Note that you can refer to a sub-schema by adding a json-pointer path as 'dollar-parameter': [index.html#/docson/examples/example.json$items](http://lbovet.github.io/docson/index.html#/docson/examples/example.json$items)
+
+## Typson
+
+You can directly reference your JSON types defined as TypeScript interfaces. If the path ends with `.ts`, Docson will use [Typson](https://github.com/lbovet/typson) to convert the Type Scripts to schema in order to generate the documentation.
+
+For example, [index.html#/typson/example/invoice/line.ts$InvoiceLine](http://lbovet.github.io/docson/index.html#/typson/example/invoice/line.ts$InvoiceLine) is the documentation of [line.ts](https://github.com/lbovet/typson/blob/master/example/invoice/line.ts).
+
+You need to install [Typson](https://github.com/lbovet/typson) by yourself on your server. It must be in a directory named `typson` located at the same level as the `docson` directory.
+
+## Widget
+
+To include a Docson schema documentations on any page (wiki, ...) without worrying about messing up with javascript libraries and cross-origin issues:
+
+* Install Docson somewhere as described above.
+* Place the following `script` tags in the including page, nothing else is needed:
+
+```
+<script src="http://somewhere/path-to-docson/widget.js" data-schema="/path-to-schema">
+</script>
+```
+
+See the [widget example](http://jsfiddle.net/3kXu2/3/) on jsfiddle.
+
+## Swagger
+
+You can adapt [Swagger UI](https://github.com/wordnik/swagger-ui) to display Docson-generated model documentation instead of the builtin signatures.
+
+See how it looks like in the [Swagger Docson example](http://lbovet.github.io/swagger-ui/dist/index.html)
+
+In Swagger UI's `index.html`, include the [Swagger integration script after other script tags](https://github.com/lbovet/swagger-ui/blob/3f37722b03db6c48cc2a8460df26dda5f4d6f8e4/src/main/html/index.html#L19):
+```
+ <script src='/path-to-docson/docson-swagger.js' type='text/javascript'></script>
+```
+
+Also, you will need a patched version of [Swagger Client](https://github.com/lbovet/swagger-js/blob/models-exposed/lib/swagger.js) so that the raw json-schema model is visible from Docson. Either replace the `swagger.js` file in your Swagger UI disctribution or take it directly from github by replacing
+
+```
+ <script src='/lib/swagger.js' type='text/javascript'></script>
+```
+
+with
+
+```
+ <script src='https://raw2.github.com/lbovet/swagger-js/models-exposed/lib/swagger.js' type='text/javascript'></script>
+```
+
+For a better layout of parameter models, you may [want to change the width of some elements](https://github.com/lbovet/swagger-ui/blob/3f37722b03db6c48cc2a8460df26dda5f4d6f8e4/src/main/html/index.html#L20-L27):
+
+```
+ <style>
+ .swagger-ui-wrap {
+ max-width: 1200px;
+ }
+ .swagger-ui-wrap .body-textarea {
+ width: 200px;
+ }
+ </style>
+```
+
+## Integration
+
+You can also integrate Docson in your application and use its javascript API:
+
+```javascript
+docson.doc(element, schema, ref)
+```
+
+* `element` is the element which will host the documentation. Either a DOM element (id or object) or jQuery element.
+* `schema` is the URI or path to the schema or a string containing the schema source itself.
+* `ref` is an optional json-pointer path to a sub-schema.
+
+Examples:
+* [Simple integration example](http://lbovet.github.io/docson/examples/example.html)
+* [See it in action](http://lbovet.github.io/typson-demo/) with its buddy [typson](https://github.com/lbovet/typson).
+
+## Limitations
+
+* Mixing unrelated keywords can lead to unexpected results.
+
+Not implemented:
+* Non-primitive values in enums and default values
+* dependencies, additionalItems, patternProperties
+
+## Development
+
+* [All tests](http://lbovet.github.io/docson/tests/test.html)
+
+Please pull-request your failing schemas in the `tests/` folder and open an issue describing the expected result.
+
+[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lbovet/docson/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
+
--- /dev/null
+{"$schema":"http://json-schema.org/draft-04/schema#","id":"http://jsonschema.net","type":"object","properties":{"seqs":{"id":"http://jsonschema.net/seqs","type":"array","items":{"id":"http://jsonschema.net/seqs/0","type":"object","properties":{"name":{"id":"http://jsonschema.net/seqs/0/name","type":"string","description":"Sequence name"},"start":{"id":"http://jsonschema.net/seqs/0/start","type":"integer","description":"Start residue position"},"svid":{"id":"http://jsonschema.net/seqs/0/svid","type":"string","description":"Serial version id for sequence object"},"end":{"id":"http://jsonschema.net/seqs/0/end","type":"integer","description":"End residue position"},"id":{"id":"http://jsonschema.net/seqs/0/id","type":"string","description":"Sequence unique identifier"},"seq":{"id":"http://jsonschema.net/seqs/0/seq","type":"string","description":"Sequence Residues"},"order":{"id":"http://jsonschema.net/seqs/0/order","type":"integer","description":"Sequence order in an alignment space"}},"required":["name","start","svid","end","id","seq"]},"required":["0"],"description":"Sequences in the Alignemnt","minItems":"1","maxItems":"*"},"appSettings":{"id":"http://jsonschema.net/appSettings","type":"object","properties":{"globalColorScheme":{"id":"http://jsonschema.net/appSettings/globalColorScheme","type":"string","description":"Global colour schem for the alignment"},"webStartUrl":{"id":"http://jsonschema.net/appSettings/webStartUrl","type":"string","description":"Jalview specific setting which points to a url for launching Jalview"},"application":{"id":"http://jsonschema.net/appSettings/application","type":"string","description":"Application which generated the Json"},"showSeqFeatures":{"id":"http://jsonschema.net/appSettings/showSeqFeatures","type":"string","description":"Determines if sequence features are visible or not"},"version":{"id":"http://jsonschema.net/appSettings/version","type":"string","description":"Verion of the application which generated the JSON"},"hiddenCols":{"id":"http://jsonschema.net/appSettings/hiddenCols","type":"string","description":"Delimited lists of hidden colums ranges i.e [2-3,5-5,11-23]"}},"description":"Application specific settings"},"seqGroups":{"id":"http://jsonschema.net/seqGroups","type":"array","items":[{"id":"http://jsonschema.net/seqGroups/0","type":"object","properties":{"displayText":{"id":"http://jsonschema.net/seqGroups/0/displayText","type":"boolean","description":"Determines if the texts of the group is displayed or not"},"startRes":{"id":"http://jsonschema.net/seqGroups/0/startRes","type":"integer","description":"Start residue position for a given group"},"groupName":{"id":"http://jsonschema.net/seqGroups/0/groupName","type":"string","description":"Group name"},"endRes":{"id":"http://jsonschema.net/seqGroups/0/endRes","type":"integer","description":"End residue position for a given group"},"colourText":{"id":"http://jsonschema.net/seqGroups/0/colourText","type":"boolean","description":"Determines if the Residues text for the group is coloured"},"seqsHash":{"id":"http://jsonschema.net/seqGroups/0/seqsHash","type":"array","items":[],"minItems":"0","maxItems":"*","description":"The id's of the sequences which belongs to the group"},"svid":{"id":"http://jsonschema.net/seqGroups/0/svid","type":"string","description":"Serial version id for a given group"},"showNonconserved":{"id":"http://jsonschema.net/seqGroups/0/showNonconserved","type":"boolean","description":"Determines if non conserved regions of a group is shown or not"},"colourScheme":{"id":"http://jsonschema.net/seqGroups/0/colourScheme","type":"string","description":"Colour Scheme for the sequence group"},"displayBoxes":{"id":"http://jsonschema.net/seqGroups/0/displayBoxes","type":"boolean","description":"Determines if the group border should be visible or not"}}}],"description":"Sequence groups in the Alignment","minItems":"0","maxItems":"*"},"alignAnnotation":{"id":"http://jsonschema.net/alignAnnotation","type":"array","items":{"id":"http://jsonschema.net/alignAnnotation/0","type":"object","properties":{"svid":{"id":"http://jsonschema.net/alignAnnotation/0/svid","type":"string","description":"Serial version id for the annotation object"},"annotations":{"id":"http://jsonschema.net/alignAnnotation/0/annotations","type":"array","items":[{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0","type":"object","properties":{"displayCharacter":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0/displayCharacter","type":"string","description":"Display character to denote the given annotation"},"value":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0/value","type":"integer","description":"Value of the annotation"},"secondaryStructure":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0/secondaryStructure","type":"string","description":"Secondary structure symbol for the given annotation"}}},{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1","type":"object","properties":{"displayCharacter":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1/displayCharacter","type":"string"},"value":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1/value","type":"integer"},"secondaryStructure":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1/secondaryStructure","type":"string"}}},{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2","type":"object","properties":{"displayCharacter":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2/displayCharacter","type":"string"},"value":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2/value","type":"integer"},"secondaryStructure":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2/secondaryStructure","type":"string"}}}]},"description":{"id":"http://jsonschema.net/alignAnnotation/0/description","type":"string","description":"Description of the Alignment Annotation"},"label":{"id":"http://jsonschema.net/alignAnnotation/0/label","type":"string","description":"Label for the Annotation"}}},"description":"Alignment Annotations","minItems":"0","maxItems":"*"},"svid":{"id":"http://jsonschema.net/svid","type":"string","description":"Serial version id"},"seqFeatures":{"id":"http://jsonschema.net/seqFeatures","type":"array","items":{"id":"http://jsonschema.net/seqFeatures/0","type":"object","properties":{"fillColor":{"id":"http://jsonschema.net/seqFeatures/0/fillColor","type":"string","description":"Fill colour"},"score":{"id":"http://jsonschema.net/seqFeatures/0/score","type":"integer","description":"Score"},"sequenceRef":{"id":"http://jsonschema.net/seqFeatures/0/sequenceRef","type":"string","description":"Reference to the Sequence in the alignement (More like a foreign key)"},"featureGroup":{"id":"http://jsonschema.net/seqFeatures/0/featureGroup","type":"string","description":"Feature Group"},"svid":{"id":"http://jsonschema.net/seqFeatures/0/svid","type":"string","description":"Serial version id for the SeqFeature object"},"description":{"id":"http://jsonschema.net/seqFeatures/0/description","type":"string","description":"Description of Feature"},"xStart":{"id":"http://jsonschema.net/seqFeatures/0/xStart","type":"integer","description":"Start residue position for the sequence feature"},"xEnd":{"id":"http://jsonschema.net/seqFeatures/0/xEnd","type":"integer","description":"End residue position for the sequence feature"},"type":{"id":"http://jsonschema.net/seqFeatures/0/type","type":"string","description":"The name of the SequenceFeature"}}},"minItems":"0","maxItems":"*","description":"Sequence Features within the alignment"}},"required":["seqs","appSettings","seqGroups","alignAnnotation","svid","seqFeatures"]}
\ No newline at end of file
--- /dev/null
+{
+ "name": "docson",
+ "main": "docson.js",
+ "version": "0.1.0",
+ "homepage": "https://github.com/lbovet/docson",
+ "authors": [
+ "Laurent Bovet <laurent.bovet@windmaster.ch>"
+ ],
+ "description": "Documentation for your JSON types",
+ "moduleType": [
+ "amd"
+ ],
+ "keywords": [
+ "docson",
+ "json"
+ ],
+ "license": "http://www.apache.org/licenses/LICENSE-2.0",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ]
+}
--- /dev/null
+/*
+ * Copyright 2013 Laurent Bovet <laurent.bovet@windmaster.ch>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.docson {
+ font-family: 'Droid Sans',verdana,helvetica;
+ font-size: 13px;
+ padding: 6px 6px 6px 6px;
+}
+
+.docson .box {
+ position: relative;
+ float: left;
+ background-color:rgba(255, 255, 255, 0.2);
+ border: 1px solid lightgrey;
+ border-radius: 4px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ padding-bottom: 10px;
+ -moz-box-shadow: 1px 1px 1px darkgray;
+ -webkit-box-shadow: 1px 1px 1px darkgray;
+ box-shadow: 1px 1px 1px darkgray;
+}
+
+.docson .expand-button {
+ position: absolute;
+ margin-top: 15px;
+ padding: 2px;
+ right: 2px;
+ float: right;
+ width: 18px;
+ text-align: center;
+ cursor: pointer;
+ font-weight: bold;
+ font-family: "Lucida Console", Monaco, monospace;
+ font-size: 15px;
+ color: darkgray;
+ display: none;
+}
+
+.docson .source-button {
+ position: absolute;
+ padding: 2px;
+ margin-top: 3px;
+ right: 2px;
+ width: 18px;
+ text-align: center;
+ cursor: pointer;
+ font-weight: bold;
+ font-family: "Lucida Console", Monaco, monospace;
+ font-size: 10px;
+ color: darkgray;
+ display: none;
+}
+
+.docson .box-header {
+ padding: 6px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom: 1px solid lightgrey;
+ background: whitesmoke;
+ /* background: -webkit-linear-gradient(ghostwhite, whitesmoke, whitesmoke, gainsboro);
+ background: -moz-linear-gradient(ghostwhite, whitesmoke, whitesmoke, gainsboro);*/
+}
+
+.docson .box-name {
+ color: darkblue;
+ padding: 5px 40px 2px 3px;
+ float: left;
+}
+
+.docson .title {
+ margin-top: -3px;
+ font-size: 120%;
+}
+
+.docson .link {
+ text-decoration: underline;
+}
+
+.docson .box-description {
+ color: dimgray;
+ float: left;
+ max-width: 600px;
+}
+
+.docson .end {
+ clear: both;
+}
+
+.docson .error {
+ color: red;
+}
+
+.docson .box-body {
+ padding-left: 10px;
+ padding-right: 28px;
+ clear: both;
+}
+
+.docson .box-1 {
+ background: whitesmoke;/*
+ background: -webkit-linear-gradient(ghostwhite, whitesmoke, whitesmoke, gainsboro);
+ background: -moz-linear-gradient(ghostwhite, whitesmoke, whitesmoke, gainsboro);*/
+}
+
+.docson .box-2 {
+ background: beige;
+ background: -webkit-linear-gradient(white, beige, beige, gainsboro);
+ background: -moz-linear-gradient(white, beige, beige, gainsboro);
+}
+
+.docson .box-3 {
+ background: azure;
+ background: -webkit-linear-gradient(white, azure, azure, gainsboro);
+ background: -moz-linear-gradient(white, azure, azure, gainsboro);
+}
+
+.docson .box-4 {
+ background: mistyrose;
+ background: -webkit-linear-gradient(white, mistyrose, mistyrose, gainsboro);
+ background: -moz-linear-gradient(white, mistyrose, mistyrose, gainsboro);
+}
+
+.docson .box-5 {
+ background: #ddffee;
+ background: -webkit-linear-gradient(white, #ddffee, #ddffee, gainsboro);
+ background: -moz-linear-gradient(white, #ddffee, #ddffee, gainsboro);
+}
+
+.docson .box-6 {
+ background: ghostwhite;
+ background: -webkit-linear-gradient(white, ghostwhite, ghostwhite, gainsboro);
+ background: -moz-linear-gradient(white, ghostwhite, ghostwhite, gainsboro);
+}
+
+.docson .box-7 {
+ background: lavenderblush;
+ background: -webkit-linear-gradient(white, lavenderblush, lavenderblush, gainsboro);
+ background: -moz-linear-gradient(white, lavenderblush, lavenderblush, gainsboro);
+}
+
+.docson .box-8 {
+ background: aliceblue;
+ background: -webkit-linear-gradient(white, aliceblue, aliceblue, gainsboro);
+ background: -moz-linear-gradient(white, aliceblue, aliceblue, gainsboro);
+}
+
+.docson .signature {
+ padding-top: 5px;
+ clear: left;
+}
+
+.docson .signature-header {
+ padding-top: 3px;
+ height: 20px;
+ line-height: 24px;
+}
+
+.docson .property-name {
+ float: left;
+ font-family: "Lucida Console", Monaco, monospace;
+ min-width: 130px;
+}
+
+.docson .required {
+ font-weight: bold;
+}
+
+.docson .type-keyword {
+ font-size: 80%;
+ color: dimgray;
+}
+
+.docson .type-pattern {
+ font-size: 80%;
+ color: darkolivegreen;
+}
+
+.docson .type-enum {
+ color: purple;
+ font-family: "Lucida Console", Monaco, monospace;
+ font-size: 90%;
+ padding-left: 2px;
+}
+
+.docson .type-default {
+ color: darkslategrey;
+ font-family: "Lucida Console", Monaco, monospace;
+}
+
+.docson .signature-type {
+ padding-left: 6px;
+ float: left;
+ min-width: 160px;
+ max-width: 320px;
+}
+
+.docson .signature-type-any {
+ font-style: italic;
+}
+
+.docson .signature-type-string {
+ color: green;
+}
+
+.docson .signature-type-number {
+ color: blue;
+}
+
+.docson .signature-type-integer {
+ color: blueviolet;
+}
+
+.docson .signature-type-boolean {
+ color: orangered;
+}
+
+.docson .signature-type-null {
+ font-family: "Lucida Console", Monaco, monospace;
+ color: red;
+}
+
+.docson .signature-type-date-time {
+ color: #224466;
+}
+
+.docson .signature-type-email {
+ color: cornflowerblue;
+}
+
+.docson .signature-type-hostname {
+ color: darkolivegreen;
+}
+
+.docson .signature-type-ipv6 {
+ color: darkslateblue;
+}
+
+.docson .signature-type-ipv4 {
+ color: indigo;
+}
+
+.docson .signature-type-uri {
+ color: saddlebrown;
+}
+
+.docson .signature-button {
+ cursor: pointer;
+ padding: 4px;
+ border-radius: 4px;
+ border: 1px solid lightgrey;
+ -moz-border-radius: 4px;
+}
+
+.docson .signature-type-ref {
+ color: darkblue;
+}
+
+.docson .signature-type-expanded {
+ padding: 5px 3px 3px 5px;
+ vertical-align: -1px;
+ opacity: 0.6;
+ -moz-box-shadow: inset 1px 1px 1px darkgray;
+ -webkit-box-shadow: inset 1px 1px 1px darkgray;
+ box-shadow: inset 1px 1px 1px darkgray;
+}
+
+.docson .signature-description {
+ padding-left: 6px;
+ padding-bottom: 3px;
+ color: dimgray;
+ float: left;
+ max-width: 600px;
+}
+
+.docson .signature-box-container {
+ clear: both;
+}
+
+.docson .box-container {
+ float: left;
+ padding-top: 4px;
+ padding-left: 8px;
+ display: none;
+}
+
+.docson .button {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.docson .button:hover {
+ color: darkred;
+}
+
+@media all and (min-width: 20px) and (max-width: 500px) {
+ .docson .property-name {
+ min-width: 0px;
+ }
+ .docson .signature-type {
+ min-width: 0px;
+ }
+ .docson .source {
+ width: 100%;
+ }
+ .docson .box-container, .box {
+ width: 100%;
+ }
+}
+
+.docson .desc {
+ padding-left: 6px;
+ line-height: 17px;
+}
+
+.docson .desc p {
+ margin: 0;
+ margin-top: 3px;
+}
+
+.docson .desc code {
+ color: purple;
+ font-size: 90%;
+}
+
+
+.docson .desc table {
+ margin-top: 4px;
+ margin-bottom: 4px;
+ border-collapse:collapse;
+}
+
+.docson .desc th {
+ padding: 0px;
+ font-size: 80%;
+ font-weight: normal;
+ background: rgba(231, 231, 231, 0.5);
+}
+
+.docson .desc table,
+.docson .desc th,
+.docson .desc td {
+ border: 1px solid lightgrey;
+}
+
+.docson .desc tr > td {
+ padding: 2px 6px 2px 6px;
+}
+
+.docson .desc h1 {
+ font-size: 120%;
+ margin-top: 0px;
+ margin-bottom: 3px;
+}
+
+.docson .desc h2 {
+ font-size: 115%;
+ margin-top: 0px;
+ margin-bottom: 3px;
+}
+
+.docson .desc h3 {
+ font-size: 110%;
+ margin-top: 0px;
+ margin-bottom: 3px;
+}
+
+.docson .desc h4 {
+ font-size: 100%;
+ margin-top: 0px;
+ margin-bottom: 3px;
+}
+
+.docson .desc pre {
+ border: 1px solid lightgray;
+ border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ padding: 4px;
+ margin: 3px 0px;
+}
+
+.docson .desc ul {
+ padding-left: 16px;
+ margin: 3px 0px;
+}
+
+.docson .desc ol {
+ padding-left: 16px;
+ margin: 3px 0px;
+}
+
+.docson .desc blockquote {
+ margin: 3px 0px 3px 10px;
+ padding-left: 6px;
+ border-left: 1px solid lightgray;
+}
+
+.docson .desc img {
+ vertical-align: middle;
+}
+
+.docson .desc hr {
+ border: 0;
+ height: 1px;
+ background: lightgrey;
+ color: lightgrey;
+ width: 50%;
+}
+
+.docson .source {
+ display: none;
+ padding-left: 16px;
+ padding-right: 30px;
+}
+
+.docson .json, .json-schema {
+ font-family: "Lucida Console", Monaco, monospace;
+}
+
+.docson .json-punctuation {
+ font-weight: bold;
+}
+
+.docson .json-null, .json-true, .json-false {
+ font-weight: bold;
+}
+
+.docson .json-true {
+ color: #080;
+}
+
+.docson .json-false {
+ color: #800;
+}
+
+.docson .json-object-key {
+ color: #246;
+}
+
+.docson .json-keyword {
+ font-weight: bold;
+ color: #036;
+}
+
+.docson .json-number {
+ font-weight: bold;
+ color: #660;
+}
+
+.docson .json-string {
+ color: #800;
+}
+
+.docson .json-schema-map > .json-object-key {
+ color: #080;
+ font-style: italic;
+}
+
--- /dev/null
+/*
+ * Copyright 2013 Laurent Bovet <laurent.bovet@windmaster.ch>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var allDefinitions;
+var counter = 0;
+
+function createDoc(definitions, type) {
+ counter++;
+ var docson = "/docson/index.html";
+ if(!allDefinitions) {
+ allDefinitions = {};
+ function receiveMessage(event) {
+ if (event.data.id && event.data.id == "docson") {
+ var frame = $("#docson-"+event.data.url.split("$")[2]);
+ if (event.data.action == "resized") {
+ frame.get(0).width = event.data.width + 18;
+ frame.get(0).height = event.data.height + 36;
+ frame.parents("td").width(event.data.width + 24)
+ }
+ if (event.data.action == "ready") {
+ frame.get(0).contentWindow.postMessage({ id: "docson", action: "load", definitions: allDefinitions, type: event.data.url.split("$")[1]}, "*");
+ }
+ }
+ }
+ window.addEventListener("message", receiveMessage, false);
+ }
+ $.extend(allDefinitions, definitions);
+ return "<iframe class='docson-frame' id='docson-" + counter + "' style='padding: 0; border: 0; width:100%; background: transparent' src='" + docson + "#$" + type + "$"+counter+"'></iframe>"
+}
+
+SwaggerOperation.prototype.getSignature = function(type, models) {
+ var collectionType, isPrimitive;
+ if(this.isCollectionType) {
+ collectionType = this.isCollectionType(type);
+ } else {
+ collectionType = this.isListType(type);
+ }
+ isPrimitive = ((collectionType != null) && models[collectionType]) || (models[type] != null) ? false : true;
+ if (isPrimitive) {
+ return type;
+ } else {
+ if (collectionType != null) {
+ return "<p class='stronger'>" + type + "</p>" + createDoc(this.resource.rawModels, collectionType);
+ } else {
+ return createDoc(this.resource.rawModels, type);
+ }
+ }
+};
+
+$(document).on("click", ".toggleOperation", function() {
+ $(this).parents(".operations").find(".docson-frame").each(function(k, frame) {
+ frame.contentWindow.postMessage({id: "docson", action: "resize"}, "*");
+ });
+});
--- /dev/null
+/*
+ * Copyright 2013 Laurent Bovet <laurent.bovet@windmaster.ch>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var docson = docson || {};
+
+docson.templateBaseUrl="templates";
+
+define(["lib/jquery", "lib/handlebars", "lib/highlight", "lib/jsonpointer", "lib/marked", "lib/traverse"], function(jquery, handlebars, highlight, jsonpointer, marked) {
+
+ var ready = $.Deferred();
+ var boxTemplate;
+ var signatureTemplate;
+ var source;
+ var stack = [];
+ var boxes=[];
+
+ Handlebars.registerHelper('scope', function(schema, options) {
+ var result;
+ boxes.push([]);
+ if(schema && (schema.id || schema.root)) {
+ stack.push( schema );
+ result = options.fn(this);
+ stack.pop();
+ } else {
+ result = options.fn(this);
+ }
+ boxes.pop();
+ return result;
+ });
+
+ Handlebars.registerHelper('source', function(schema) {
+ delete schema.root;
+ delete schema.__boxId;
+ delete schema.__name;
+ delete schema.__ref;
+ return JSON.stringify(schema, null, 2);
+ });
+
+ Handlebars.registerHelper('desc', function(schema) {
+ var description = schema.description;
+
+ if( !description ) return "";
+ var text = description;
+ if(marked) {
+ marked.setOptions({gfm: true, breaks: true})
+ return new Handlebars.SafeString(marked(text));
+ } else {
+ return text;
+ }
+ });
+
+ Handlebars.registerHelper('equals', function(lvalue, rvalue, options) {
+ if (arguments.length < 3)
+ throw new Error("Handlebars Helper equals needs 2 parameters");
+ if( lvalue!=rvalue ) {
+ return options.inverse(this);
+ } else {
+ return options.fn(this);
+ }
+ });
+
+ Handlebars.registerHelper('contains', function(arr, item, options) {;
+ if(arr && arr instanceof Array && arr.indexOf(item) != -1) {
+ return options.fn(this);
+ }
+ });
+
+ Handlebars.registerHelper('primitive', function(schema, options) {
+ if(schema.type && schema.type != "object" && schema.type != "array" || schema.enum) {
+ return withType(this, options, true)
+ }
+ });
+
+ Handlebars.registerHelper('exists', function(value, options) {
+ if(value !== undefined) {
+ value = value === null ? "null": value;
+ value = value === true ? "true": value;
+ value = value === false ? "false": value;
+ value = typeof value === "object" ? JSON.stringify(value): value;
+ this.__default = value;
+ var result = options.fn(this);
+ delete this.__default;
+ return result;
+ }
+ });
+
+ Handlebars.registerHelper('range', function(from, to, replFrom, replTo, exclFrom, exclTo, sep) {
+ var result = "";
+ if(from !== undefined || to !== undefined) {
+ result += exclFrom ? "]" : "[";
+ result += from !== undefined ? from : replFrom;
+ if( (from || replFrom) !== (to || replTo)) {
+ result += (from !== undefined || replFrom !== null) && (to !== undefined || replTo !== null) ? sep : "";
+ result += to !== undefined ? to : replTo;
+ }
+ result += exclTo ? "[" : "]";
+ return result;
+ }
+ });
+
+ var sub = function(schema) {
+ return schema.type == "array" || schema.allOf || schema.anyOf || schema.oneOf || schema.not;
+ }
+
+ Handlebars.registerHelper('sub', function(schema, options) {
+ if(sub(schema) || (schema.type && schema.type != "object" && schema.type != "array") || schema.enum) {
+ return options.fn(this);
+ }
+ });
+
+ Handlebars.registerHelper('main', function(schema, options) {
+ if(!sub(schema)) {
+ return options.fn(this);
+ }
+ });
+
+ var simpleSchema = function(schema) {
+ var result = schema.description===undefined && schema.title===undefined && schema.id===undefined;
+ result &= schema.properties===undefined;
+ return result;
+ };
+
+ Handlebars.registerHelper('simple', function(schema, options) {
+ if(simpleSchema(schema) && !schema.$ref) {
+ return withType(schema, options, true);
+ }
+ });
+
+ var withType = function(schema, options, hideAny) {
+ schema.__type = schema.type;
+ if(!schema.type && !hideAny) {
+ schema.__type="any";
+ }
+ if(schema.format) {
+ schema.__type=schema.format;
+ }
+ if( (schema.__type == "any" || schema.__type == "object") && schema.title) {
+ schema.__type = schema.title;
+ }
+ var result = options.fn(schema);
+ delete schema.__type;
+ return result;
+ }
+
+ Handlebars.registerHelper('complex', function(schema, options) {
+ if(!simpleSchema(schema) && !schema.$ref || schema.properties) {
+ return withType(schema, options);
+ }
+ });
+
+ Handlebars.registerHelper('enum', function(schema) {
+ if(schema.enum) {
+ return (schema.enum.length > 1) ? "enum": "constant";
+ }
+ });
+
+ Handlebars.registerHelper('obj', function(schema, options) {
+ if(schema.properties || schema.type == "object") {
+ return withType(schema, options);
+ }
+ });
+
+ var pushBox = function(schema) {
+ boxes[boxes.length-1].push(schema);
+ }
+
+ Handlebars.registerHelper('box', function(schema, options) {
+ if(schema) {
+ pushBox(schema);
+ return options.fn(schema);
+ }
+ });
+
+ Handlebars.registerHelper('boxId', function() {
+ return boxes[boxes.length-1].length
+ });
+
+ Handlebars.registerHelper('boxes', function(options) {
+ var result="";
+ $.each(boxes[boxes.length-1], function(k, box) {
+ box.__boxId = k+1;
+ result=result+options.fn(box);
+ });
+ boxes[boxes.length-1] = []
+ return result;
+ });
+
+ var resolveIdRef = function(ref) {
+ if(stack) {
+ var i;
+ for(i=stack.length-1; i>=0; i--) {
+ if(stack[i][ref]) {
+ return stack[i][ref];
+ }
+ }
+ }
+ return null;
+ }
+
+ var resolvePointerRef = function(ref) {
+ var root = stack[1];
+ if(ref=="#") {
+ return root;
+ }
+ try {
+ return jsonpointer.get(stack[1], ref);
+ } catch(e) {
+ console.log(e);
+ return null;
+ }
+ }
+
+ var resolveRef = function(ref) {
+ if(ref.indexOf("#") == 0) {
+ return resolvePointerRef(ref);
+ } else {
+ return resolveIdRef(ref);
+ }
+ }
+
+ var getName = function(schema) {
+ if(!schema) {
+ return "<error>";
+ }
+ var name = schema.title;
+ name = !name && schema.id ? schema.id: name;
+ name = !name ? schema.__name: name;
+ return name;
+ }
+
+ Handlebars.registerHelper('name', function(schema, options) {
+ schema.__name = getName(schema);
+ if(schema.__name) {
+ return options.fn(schema);
+ }
+ });
+
+ var refName = function(ref) {
+ var name = getName(resolveRef(ref));
+ if(!name) {
+ if(ref == "#") {
+ name = "<root>";
+ } else {
+ name = ref.replace("#", "/")
+ }
+ }
+ var segments = name.split("/");
+ name = segments[segments.length-1];
+ return name;
+ }
+
+ function renderSchema(schema) {
+ if(stack.indexOf(schema) == -1) { // avoid recursion
+ stack.push(schema);
+ var ret = new Handlebars.SafeString(boxTemplate(schema));
+ stack.pop();
+ return ret;
+ } else {
+ return new Handlebars.SafeString(boxTemplate({"description": "_circular reference_"}));
+ }
+ }
+
+ Handlebars.registerHelper('ref', function(schema, options) {
+ if(schema.$ref) {
+ var target = resolveRef(schema.$ref);
+ if(target) {
+ target.__name = refName(schema.$ref);
+ target.__ref = schema.$ref.replace("#", "");
+ }
+ var result;
+ if(target) {
+ result = options.fn(target);
+ } else {
+ result = new Handlebars.SafeString("<span class='signature-type-ref'>"+schema.$ref+"</span>");
+ }
+ if(target) {
+ delete target.__ref;
+ }
+ return result;
+ }
+ });
+
+ Handlebars.registerHelper('schema', function(schema) {
+ return renderSchema(schema);
+ });
+
+ Handlebars.registerHelper('signature', function(schema, keyword, schemas) {
+ if(!schemas) {
+ schemas = []
+ }
+ schemas = schemas instanceof Array ? schemas : [schemas];
+ return new Handlebars.SafeString(signatureTemplate({ schema: schema, keyword: keyword, schemas: schemas}));
+ });
+
+ Handlebars.registerHelper('l', function(context) {
+ console.log(context);
+ });
+
+ function init() {
+ $.when( $.get(docson.templateBaseUrl+"/box.html").done(function(content) {
+ source = content
+ boxTemplate = Handlebars.compile(source);
+ }), $.get(docson.templateBaseUrl+"/signature.html").done(function(content) {
+ source = content
+ signatureTemplate = Handlebars.compile(source);
+ })).always(function() {
+ ready.resolve();
+ });
+ };
+
+ docson.doc = function(element, schema, ref, baseUrl) {
+ var d = $.Deferred();
+ if(baseUrl === undefined) baseUrl='';
+ init();
+ ready.done(function() {
+ if(typeof element == "string") {
+ element = $("#"+element);
+ }
+ if(typeof schema == "string") {
+ schema = JSON.parse(schema);
+ }
+
+ var refsPromise = $.Deferred().resolve().promise();
+ var refs = {};
+
+
+ var renderBox = function() {
+ stack.push(refs);
+ var target = schema;
+ if(ref) {
+ ref = ref[0] !== '/' ? '/'+ref : ref;
+ target = jsonpointer.get(schema, ref);
+ stack.push( schema );
+ }
+ target.root = true;
+ target.__ref = "<root>";
+ var html = boxTemplate(target);
+
+ if(ref) {
+ stack.pop();
+ }
+ stack.pop();
+
+ element.addClass("docson").html(html);
+
+ var resizeHandler = element.get(0).onresize;
+ function resized() {
+ if(resizeHandler) {
+ var box = element.find(".box").first();
+ element.get(0).onresize(box.outerWidth(), box.outerHeight());
+ }
+ }
+ element.get(0).resized = resized;
+ resized();
+
+ if(highlight) {
+ element.find(".json-schema").each(function(k, schemaElement) {
+ highlight.highlightSchema(schemaElement);
+ });
+ }
+ element.find(".box-title").each(function() {
+ var ref = $(this).attr("ref");
+ if(ref) {
+ if(window.location.href.indexOf("docson/index.html") > -1) {
+ $(this).find(".box-name").css("cursor", "pointer").attr("title", "Open in new window")
+ .hover(
+ function(){ $(this).addClass('link') },
+ function(){ $(this).removeClass('link') })
+ .click(function() {
+ var url = window.location.href+"$$expand";
+ if(ref !=="<root>") {
+ url = url.replace(/(docson\/index.html#[^\$]*).*/, "$1$"+ref+"$$expand");
+ }
+ var w;
+ function receiveMessage(event) {
+ if (event.data.id && event.data.id == "docson" && event.data.action == "ready") {
+ w.postMessage({ id: "docson", action: "load", definitions: schema, type: event.data.url.split("$")[1], expand: true}, "*");
+ }
+ }
+ window.addEventListener("message", receiveMessage, false);
+ w = window.open(url, "_blank");
+ });
+ }
+ }
+ });
+ element.find(".box").mouseenter(function() {
+ $(this).children(".source-button").fadeIn(300);
+ $(this).children(".box-body").children(".expand-button").fadeIn(300);
+ });
+ element.find(".box").mouseleave(function() {
+ $(this).children(".source-button").fadeOut(300);
+ $(this).children(".box-body").children(".expand-button").fadeOut(300);
+ });
+ element.find(".signature-type-expandable").click(function() {
+ var boxId = $(this).attr("boxid");
+ $(this).toggleClass("signature-type-expanded");
+ $(this).parent().parent().parent().children(".signature-box-container").
+ children("[boxid='"+boxId+"']").toggle(resizeHandler ? 0 : 300);
+ resized();
+ });
+ element.find(".expand-button").click(function() {
+ if($(this).attr("expanded")) {
+ $(this).parent().parent().find(".expand-button").html(" + ").attr("title", "Expand all");
+ $(this).parent().parent().find(".signature-type-expandable").removeClass("signature-type-expanded");
+ $(this).parent().parent().find(".box-container").hide( resizeHandler ? 0 : 300);
+ $(this).parent().parent().find(".expand-button").removeAttr("expanded");
+ resized();
+ } else {
+ $(this).parent().parent().find(".expand-button").html(" - ").attr("title", "Collapse all");
+ $(this).parent().parent().find(".signature-type-expandable").addClass("signature-type-expanded");
+ $(this).parent().parent().find(".box-container").show(resizeHandler ? 0 : 300);
+ $(this).parent().parent().find(".expand-button").attr("expanded", true);
+ resized();
+ }
+ });
+ element.find(".source-button").click(function() {
+ $(this).parent().children(".box-body").toggle();
+ $(this).parent().children(".source").toggle();
+ resized();
+ });
+ };
+
+ var resolveRefsReentrant = function(schema){
+ traverse(schema).forEach(function(item) {
+ // Fix Swagger weird generation for array.
+ if(item && item.$ref == "array") {
+ delete item.$ref;
+ item.type ="array";
+ }
+
+ // Fetch external schema
+ if(this.key === "$ref") {
+ var external = false;
+ //Local meaning local to this server, but not in this file.
+ var local = false;
+ if((/^https?:\/\//).test(item)) {
+ external = true;
+ }
+ else if((/^[^#]/).test(item)) {
+ local = true;
+ } else if(item.indexOf('#') > 0) {
+ //Internal reference
+ //Turning relative refs to absolute ones
+ external = true;
+ item = baseUrl + item;
+ this.update(item);
+ }
+ if(external){
+ //External reference, fetch it.
+ var segments = item.split("#");
+ refs[item] = null;
+ var p = $.get(segments[0]).then(function(content) {
+ if(typeof content != "object") {
+ try {
+ content = JSON.parse(content);
+ } catch(e) {
+ console.error("Unable to parse "+segments[0], e);
+ }
+ }
+ if(content) {
+ refs[item] = content;
+ renderBox();
+ resolveRefsReentrant(content);
+ }
+ });
+ }
+ else if(local) {
+ //Local to this server, fetch relative
+ var segments = item.split("#");
+ refs[item] = null;
+ var p = $.get(baseUrl + segments[0]).then(function(content) {
+ if(typeof content != "object") {
+ try {
+ content = JSON.parse(content);
+ } catch(e) {
+ console.error("Unable to parse "+segments[0], e);
+ }
+ }
+ if(content) {
+ refs[item] = content;
+ renderBox();
+ resolveRefsReentrant(content);
+ }
+ });
+ }
+ }
+ });
+ };
+
+ resolveRefsReentrant(schema);
+ renderBox();
+
+ d.resolve();
+ })
+ return d.promise();
+ }
+
+ return docson;
+});
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Docson Example</title>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="css/docson.css">
+ <script src="lib/require.js"></script></head>
+<body>
+<div id="doc"></div>
+<script charset="utf-8">
+ require.config({ baseUrl: ""});
+ require(["docson", "lib/jquery"], function(docson) {
+ $(function() {
+ var schema =
+ {"$schema":"http://json-schema.org/draft-04/schema#","id":"http://jsonschema.net","type":"object","properties":{"seqs":{"id":"http://jsonschema.net/seqs","type":"array","items":{"id":"http://jsonschema.net/seqs/0","type":"object","properties":{"name":{"id":"http://jsonschema.net/seqs/0/name","type":"string","description":"Sequence name"},"start":{"id":"http://jsonschema.net/seqs/0/start","type":"integer","description":"Start residue position"},"svid":{"id":"http://jsonschema.net/seqs/0/svid","type":"string","description":"Serial version id for sequence object"},"end":{"id":"http://jsonschema.net/seqs/0/end","type":"integer","description":"End residue position"},"id":{"id":"http://jsonschema.net/seqs/0/id","type":"string","description":"Sequence unique identifier"},"seq":{"id":"http://jsonschema.net/seqs/0/seq","type":"string","description":"Sequence Residues"},"order":{"id":"http://jsonschema.net/seqs/0/order","type":"integer","description":"Sequence order in an alignment space"}},"required":["name","start","svid","end","id","seq"]},"required":["0"],"description":"Sequences in the Alignemnt","minItems":"1","maxItems":"*"},"appSettings":{"id":"http://jsonschema.net/appSettings","type":"object","properties":{"globalColorScheme":{"id":"http://jsonschema.net/appSettings/globalColorScheme","type":"string","description":"Global colour schem for the alignment"},"webStartUrl":{"id":"http://jsonschema.net/appSettings/webStartUrl","type":"string","description":"Jalview specific setting which points to a url for launching Jalview"},"application":{"id":"http://jsonschema.net/appSettings/application","type":"string","description":"Application which generated the Json"},"showSeqFeatures":{"id":"http://jsonschema.net/appSettings/showSeqFeatures","type":"string","description":"Determines if sequence features are visible or not"},"version":{"id":"http://jsonschema.net/appSettings/version","type":"string","description":"Verion of the application which generated the JSON"},"hiddenCols":{"id":"http://jsonschema.net/appSettings/hiddenCols","type":"string","description":"Delimited lists of hidden colums ranges i.e [2-3,5-5,11-23]"}},"description":"Application specific settings"},"seqGroups":{"id":"http://jsonschema.net/seqGroups","type":"array","items":[{"id":"http://jsonschema.net/seqGroups/0","type":"object","properties":{"displayText":{"id":"http://jsonschema.net/seqGroups/0/displayText","type":"boolean","description":"Determines if the texts of the group is displayed or not"},"startRes":{"id":"http://jsonschema.net/seqGroups/0/startRes","type":"integer","description":"Start residue position for a given group"},"groupName":{"id":"http://jsonschema.net/seqGroups/0/groupName","type":"string","description":"Group name"},"endRes":{"id":"http://jsonschema.net/seqGroups/0/endRes","type":"integer","description":"End residue position for a given group"},"colourText":{"id":"http://jsonschema.net/seqGroups/0/colourText","type":"boolean","description":"Determines if the Residues text for the group is coloured"},"seqsHash":{"id":"http://jsonschema.net/seqGroups/0/seqsHash","type":"array","items":[],"minItems":"0","maxItems":"*","description":"The id's of the sequences which belongs to the group"},"svid":{"id":"http://jsonschema.net/seqGroups/0/svid","type":"string","description":"Serial version id for a given group"},"showNonconserved":{"id":"http://jsonschema.net/seqGroups/0/showNonconserved","type":"boolean","description":"Determines if non conserved regions of a group is shown or not"},"colourScheme":{"id":"http://jsonschema.net/seqGroups/0/colourScheme","type":"string","description":"Colour Scheme for the sequence group"},"displayBoxes":{"id":"http://jsonschema.net/seqGroups/0/displayBoxes","type":"boolean","description":"Determines if the group border should be visible or not"}}}],"description":"Sequence groups in the Alignment","minItems":"0","maxItems":"*"},"alignAnnotation":{"id":"http://jsonschema.net/alignAnnotation","type":"array","items":{"id":"http://jsonschema.net/alignAnnotation/0","type":"object","properties":{"svid":{"id":"http://jsonschema.net/alignAnnotation/0/svid","type":"string","description":"Serial version id for the annotation object"},"annotations":{"id":"http://jsonschema.net/alignAnnotation/0/annotations","type":"array","items":[{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0","type":"object","properties":{"displayCharacter":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0/displayCharacter","type":"string","description":"Display character to denote the given annotation"},"value":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0/value","type":"integer","description":"Value of the annotation"},"secondaryStructure":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0/secondaryStructure","type":"string","description":"Secondary structure symbol for the given annotation"}}},{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1","type":"object","properties":{"displayCharacter":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1/displayCharacter","type":"string"},"value":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1/value","type":"integer"},"secondaryStructure":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1/secondaryStructure","type":"string"}}},{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2","type":"object","properties":{"displayCharacter":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2/displayCharacter","type":"string"},"value":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2/value","type":"integer"},"secondaryStructure":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2/secondaryStructure","type":"string"}}}]},"description":{"id":"http://jsonschema.net/alignAnnotation/0/description","type":"string","description":"Description of the Alignment Annotation"},"label":{"id":"http://jsonschema.net/alignAnnotation/0/label","type":"string","description":"Label for the Annotation"}}},"description":"Alignment Annotations","minItems":"0","maxItems":"*"},"svid":{"id":"http://jsonschema.net/svid","type":"string","description":"Serial version id"},"seqFeatures":{"id":"http://jsonschema.net/seqFeatures","type":"array","items":{"id":"http://jsonschema.net/seqFeatures/0","type":"object","properties":{"fillColor":{"id":"http://jsonschema.net/seqFeatures/0/fillColor","type":"string","description":"Fill colour"},"score":{"id":"http://jsonschema.net/seqFeatures/0/score","type":"integer","description":"Score"},"sequenceRef":{"id":"http://jsonschema.net/seqFeatures/0/sequenceRef","type":"string","description":"Reference to the Sequence in the alignement (More like a foreign key)"},"featureGroup":{"id":"http://jsonschema.net/seqFeatures/0/featureGroup","type":"string","description":"Feature Group"},"svid":{"id":"http://jsonschema.net/seqFeatures/0/svid","type":"string","description":"Serial version id for the SeqFeature object"},"description":{"id":"http://jsonschema.net/seqFeatures/0/description","type":"string","description":"Description of Feature"},"xStart":{"id":"http://jsonschema.net/seqFeatures/0/xStart","type":"integer","description":"Start residue position for the sequence feature"},"xEnd":{"id":"http://jsonschema.net/seqFeatures/0/xEnd","type":"integer","description":"End residue position for the sequence feature"},"type":{"id":"http://jsonschema.net/seqFeatures/0/type","type":"string","description":"The name of the SequenceFeature"}}},"minItems":"0","maxItems":"*","description":"Sequence Features within the alignment"}},"required":["seqs","appSettings","seqGroups","alignAnnotation","svid","seqFeatures"]}
+ docson.templateBaseUrl="templates";
+ docson.doc("doc", schema);
+ });
+ });
+</script>
+</body>
+</html>
--- /dev/null
+/*!
+
+ handlebars v1.1.2
+
+Copyright (C) 2011 by Yehuda Katz
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+@license
+*/
+var Handlebars = (function() {
+// handlebars/safe-string.js
+var __module4__ = (function() {
+ "use strict";
+ var __exports__;
+ // Build out our basic SafeString type
+ function SafeString(string) {
+ this.string = string;
+ }
+
+ SafeString.prototype.toString = function() {
+ return "" + this.string;
+ };
+
+ __exports__ = SafeString;
+ return __exports__;
+})();
+
+// handlebars/utils.js
+var __module3__ = (function(__dependency1__) {
+ "use strict";
+ var __exports__ = {};
+ var SafeString = __dependency1__;
+
+ var escape = {
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ '"': """,
+ "'": "'",
+ "`": "`"
+ };
+
+ var badChars = /[&<>"'`]/g;
+ var possible = /[&<>"'`]/;
+
+ function escapeChar(chr) {
+ return escape[chr] || "&";
+ }
+
+ function extend(obj, value) {
+ for(var key in value) {
+ if(value.hasOwnProperty(key)) {
+ obj[key] = value[key];
+ }
+ }
+ }
+
+ __exports__.extend = extend;var toString = Object.prototype.toString;
+ __exports__.toString = toString;
+ // Sourced from lodash
+ // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
+ var isFunction = function(value) {
+ return typeof value === 'function';
+ };
+ // fallback for older versions of Chrome and Safari
+ if (isFunction(/x/)) {
+ isFunction = function(value) {
+ return typeof value === 'function' && toString.call(value) === '[object Function]';
+ };
+ }
+ var isFunction;
+ __exports__.isFunction = isFunction;
+ var isArray = Array.isArray || function(value) {
+ return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
+ };
+ __exports__.isArray = isArray;
+
+ function escapeExpression(string) {
+ // don't escape SafeStrings, since they're already safe
+ if (string instanceof SafeString) {
+ return string.toString();
+ } else if (!string && string !== 0) {
+ return "";
+ }
+
+ // Force a string conversion as this will be done by the append regardless and
+ // the regex test will do this transparently behind the scenes, causing issues if
+ // an object's to string has escaped characters in it.
+ string = "" + string;
+
+ if(!possible.test(string)) { return string; }
+ return string.replace(badChars, escapeChar);
+ }
+
+ __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
+ if (!value && value !== 0) {
+ return true;
+ } else if (isArray(value) && value.length === 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ __exports__.isEmpty = isEmpty;
+ return __exports__;
+})(__module4__);
+
+// handlebars/exception.js
+var __module5__ = (function() {
+ "use strict";
+ var __exports__;
+
+ var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
+
+ function Exception(/* message */) {
+ var tmp = Error.prototype.constructor.apply(this, arguments);
+
+ // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
+ for (var idx = 0; idx < errorProps.length; idx++) {
+ this[errorProps[idx]] = tmp[errorProps[idx]];
+ }
+ }
+
+ Exception.prototype = new Error();
+
+ __exports__ = Exception;
+ return __exports__;
+})();
+
+// handlebars/base.js
+var __module2__ = (function(__dependency1__, __dependency2__) {
+ "use strict";
+ var __exports__ = {};
+ /*globals Exception, Utils */
+ var Utils = __dependency1__;
+ var Exception = __dependency2__;
+
+ var VERSION = "1.1.2";
+ __exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
+ __exports__.COMPILER_REVISION = COMPILER_REVISION;
+ var REVISION_CHANGES = {
+ 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
+ 2: '== 1.0.0-rc.3',
+ 3: '== 1.0.0-rc.4',
+ 4: '>= 1.0.0'
+ };
+ __exports__.REVISION_CHANGES = REVISION_CHANGES;
+ var isArray = Utils.isArray,
+ isFunction = Utils.isFunction,
+ toString = Utils.toString,
+ objectType = '[object Object]';
+
+ function HandlebarsEnvironment(helpers, partials) {
+ this.helpers = helpers || {};
+ this.partials = partials || {};
+
+ registerDefaultHelpers(this);
+ }
+
+ __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
+ constructor: HandlebarsEnvironment,
+
+ logger: logger,
+ log: log,
+
+ registerHelper: function(name, fn, inverse) {
+ if (toString.call(name) === objectType) {
+ if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
+ Utils.extend(this.helpers, name);
+ } else {
+ if (inverse) { fn.not = inverse; }
+ this.helpers[name] = fn;
+ }
+ },
+
+ registerPartial: function(name, str) {
+ if (toString.call(name) === objectType) {
+ Utils.extend(this.partials, name);
+ } else {
+ this.partials[name] = str;
+ }
+ }
+ };
+
+ function registerDefaultHelpers(instance) {
+ instance.registerHelper('helperMissing', function(arg) {
+ if(arguments.length === 2) {
+ return undefined;
+ } else {
+ throw new Error("Missing helper: '" + arg + "'");
+ }
+ });
+
+ instance.registerHelper('blockHelperMissing', function(context, options) {
+ var inverse = options.inverse || function() {}, fn = options.fn;
+
+ if (isFunction(context)) { context = context.call(this); }
+
+ if(context === true) {
+ return fn(this);
+ } else if(context === false || context == null) {
+ return inverse(this);
+ } else if (isArray(context)) {
+ if(context.length > 0) {
+ return instance.helpers.each(context, options);
+ } else {
+ return inverse(this);
+ }
+ } else {
+ return fn(context);
+ }
+ });
+
+ instance.registerHelper('each', function(context, options) {
+ var fn = options.fn, inverse = options.inverse;
+ var i = 0, ret = "", data;
+
+ if (isFunction(context)) { context = context.call(this); }
+
+ if (options.data) {
+ data = createFrame(options.data);
+ }
+
+ if(context && typeof context === 'object') {
+ if (isArray(context)) {
+ for(var j = context.length; i<j; i++) {
+ if (data) {
+ data.index = i;
+ data.first = (i === 0)
+ data.last = (i === (context.length-1));
+ }
+ ret = ret + fn(context[i], { data: data });
+ }
+ } else {
+ for(var key in context) {
+ if(context.hasOwnProperty(key)) {
+ if(data) { data.key = key; }
+ ret = ret + fn(context[key], {data: data});
+ i++;
+ }
+ }
+ }
+ }
+
+ if(i === 0){
+ ret = inverse(this);
+ }
+
+ return ret;
+ });
+
+ instance.registerHelper('if', function(conditional, options) {
+ if (isFunction(conditional)) { conditional = conditional.call(this); }
+
+ // Default behavior is to render the positive path if the value is truthy and not empty.
+ // The `includeZero` option may be set to treat the condtional as purely not empty based on the
+ // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
+ if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
+ return options.inverse(this);
+ } else {
+ return options.fn(this);
+ }
+ });
+
+ instance.registerHelper('unless', function(conditional, options) {
+ return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
+ });
+
+ instance.registerHelper('with', function(context, options) {
+ if (isFunction(context)) { context = context.call(this); }
+
+ if (!Utils.isEmpty(context)) return options.fn(context);
+ });
+
+ instance.registerHelper('log', function(context, options) {
+ var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
+ instance.log(level, context);
+ });
+ }
+
+ var logger = {
+ methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
+
+ // State enum
+ DEBUG: 0,
+ INFO: 1,
+ WARN: 2,
+ ERROR: 3,
+ level: 3,
+
+ // can be overridden in the host environment
+ log: function(level, obj) {
+ if (logger.level <= level) {
+ var method = logger.methodMap[level];
+ if (typeof console !== 'undefined' && console[method]) {
+ console[method].call(console, obj);
+ }
+ }
+ }
+ };
+ __exports__.logger = logger;
+ function log(level, obj) { logger.log(level, obj); }
+
+ __exports__.log = log;var createFrame = function(object) {
+ var obj = {};
+ Utils.extend(obj, object);
+ return obj;
+ };
+ __exports__.createFrame = createFrame;
+ return __exports__;
+})(__module3__, __module5__);
+
+// handlebars/runtime.js
+var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
+ "use strict";
+ var __exports__ = {};
+ /*global Utils */
+ var Utils = __dependency1__;
+ var Exception = __dependency2__;
+ var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
+ var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
+
+ function checkRevision(compilerInfo) {
+ var compilerRevision = compilerInfo && compilerInfo[0] || 1,
+ currentRevision = COMPILER_REVISION;
+
+ if (compilerRevision !== currentRevision) {
+ if (compilerRevision < currentRevision) {
+ var runtimeVersions = REVISION_CHANGES[currentRevision],
+ compilerVersions = REVISION_CHANGES[compilerRevision];
+ throw new Error("Template was precompiled with an older version of Handlebars than the current runtime. "+
+ "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
+ } else {
+ // Use the embedded version info since the runtime doesn't know about this revision yet
+ throw new Error("Template was precompiled with a newer version of Handlebars than the current runtime. "+
+ "Please update your runtime to a newer version ("+compilerInfo[1]+").");
+ }
+ }
+ }
+
+ // TODO: Remove this line and break up compilePartial
+
+ function template(templateSpec, env) {
+ if (!env) {
+ throw new Error("No environment passed to template");
+ }
+
+ var invokePartialWrapper;
+ if (env.compile) {
+ invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
+ // TODO : Check this for all inputs and the options handling (partial flag, etc). This feels
+ // like there should be a common exec path
+ var result = invokePartial.apply(this, arguments);
+ if (result) { return result; }
+
+ var options = { helpers: helpers, partials: partials, data: data };
+ partials[name] = env.compile(partial, { data: data !== undefined }, env);
+ return partials[name](context, options);
+ };
+ } else {
+ invokePartialWrapper = function(partial, name /* , context, helpers, partials, data */) {
+ var result = invokePartial.apply(this, arguments);
+ if (result) { return result; }
+ throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
+ };
+ }
+
+ // Just add water
+ var container = {
+ escapeExpression: Utils.escapeExpression,
+ invokePartial: invokePartialWrapper,
+ programs: [],
+ program: function(i, fn, data) {
+ var programWrapper = this.programs[i];
+ if(data) {
+ programWrapper = program(i, fn, data);
+ } else if (!programWrapper) {
+ programWrapper = this.programs[i] = program(i, fn);
+ }
+ return programWrapper;
+ },
+ merge: function(param, common) {
+ var ret = param || common;
+
+ if (param && common && (param !== common)) {
+ ret = {};
+ Utils.extend(ret, common);
+ Utils.extend(ret, param);
+ }
+ return ret;
+ },
+ programWithDepth: programWithDepth,
+ noop: noop,
+ compilerInfo: null
+ };
+
+ return function(context, options) {
+ options = options || {};
+ var namespace = options.partial ? options : env,
+ helpers,
+ partials;
+
+ if (!options.partial) {
+ helpers = options.helpers;
+ partials = options.partials;
+ }
+ var result = templateSpec.call(
+ container,
+ namespace, context,
+ helpers,
+ partials,
+ options.data);
+
+ if (!options.partial) {
+ checkRevision(container.compilerInfo);
+ }
+
+ return result;
+ };
+ }
+
+ __exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
+ var args = Array.prototype.slice.call(arguments, 3);
+
+ var prog = function(context, options) {
+ options = options || {};
+
+ return fn.apply(this, [context, options.data || data].concat(args));
+ };
+ prog.program = i;
+ prog.depth = args.length;
+ return prog;
+ }
+
+ __exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
+ var prog = function(context, options) {
+ options = options || {};
+
+ return fn(context, options.data || data);
+ };
+ prog.program = i;
+ prog.depth = 0;
+ return prog;
+ }
+
+ __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
+ var options = { partial: true, helpers: helpers, partials: partials, data: data };
+
+ if(partial === undefined) {
+ throw new Exception("The partial " + name + " could not be found");
+ } else if(partial instanceof Function) {
+ return partial(context, options);
+ }
+ }
+
+ __exports__.invokePartial = invokePartial;function noop() { return ""; }
+
+ __exports__.noop = noop;
+ return __exports__;
+})(__module3__, __module5__, __module2__);
+
+// handlebars.runtime.js
+var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
+ "use strict";
+ var __exports__;
+ var base = __dependency1__;
+
+ // Each of these augment the Handlebars object. No need to setup here.
+ // (This is done to easily share code between commonjs and browse envs)
+ var SafeString = __dependency2__;
+ var Exception = __dependency3__;
+ var Utils = __dependency4__;
+ var runtime = __dependency5__;
+
+ // For compatibility and usage outside of module systems, make the Handlebars object a namespace
+ var create = function() {
+ var hb = new base.HandlebarsEnvironment();
+
+ Utils.extend(hb, base);
+ hb.SafeString = SafeString;
+ hb.Exception = Exception;
+ hb.Utils = Utils;
+
+ hb.VM = runtime;
+ hb.template = function(spec) {
+ return runtime.template(spec, hb);
+ };
+
+ return hb;
+ };
+
+ var Handlebars = create();
+ Handlebars.create = create;
+
+ __exports__ = Handlebars;
+ return __exports__;
+})(__module2__, __module4__, __module5__, __module3__, __module6__);
+
+// handlebars/compiler/ast.js
+var __module7__ = (function(__dependency1__) {
+ "use strict";
+ var __exports__ = {};
+ var Exception = __dependency1__;
+
+ function ProgramNode(statements, inverseStrip, inverse) {
+ this.type = "program";
+ this.statements = statements;
+ this.strip = {};
+
+ if(inverse) {
+ this.inverse = new ProgramNode(inverse, inverseStrip);
+ this.strip.right = inverseStrip.left;
+ } else if (inverseStrip) {
+ this.strip.left = inverseStrip.right;
+ }
+ }
+
+ __exports__.ProgramNode = ProgramNode;function MustacheNode(rawParams, hash, open, strip) {
+ this.type = "mustache";
+ this.hash = hash;
+ this.strip = strip;
+
+ var escapeFlag = open[3] || open[2];
+ this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
+
+ var id = this.id = rawParams[0];
+ var params = this.params = rawParams.slice(1);
+
+ // a mustache is an eligible helper if:
+ // * its id is simple (a single part, not `this` or `..`)
+ var eligibleHelper = this.eligibleHelper = id.isSimple;
+
+ // a mustache is definitely a helper if:
+ // * it is an eligible helper, and
+ // * it has at least one parameter or hash segment
+ this.isHelper = eligibleHelper && (params.length || hash);
+
+ // if a mustache is an eligible helper but not a definite
+ // helper, it is ambiguous, and will be resolved in a later
+ // pass or at runtime.
+ }
+
+ __exports__.MustacheNode = MustacheNode;function PartialNode(partialName, context, strip) {
+ this.type = "partial";
+ this.partialName = partialName;
+ this.context = context;
+ this.strip = strip;
+ }
+
+ __exports__.PartialNode = PartialNode;function BlockNode(mustache, program, inverse, close) {
+ if(mustache.id.original !== close.path.original) {
+ throw new Exception(mustache.id.original + " doesn't match " + close.path.original);
+ }
+
+ this.type = "block";
+ this.mustache = mustache;
+ this.program = program;
+ this.inverse = inverse;
+
+ this.strip = {
+ left: mustache.strip.left,
+ right: close.strip.right
+ };
+
+ (program || inverse).strip.left = mustache.strip.right;
+ (inverse || program).strip.right = close.strip.left;
+
+ if (inverse && !program) {
+ this.isInverse = true;
+ }
+ }
+
+ __exports__.BlockNode = BlockNode;function ContentNode(string) {
+ this.type = "content";
+ this.string = string;
+ }
+
+ __exports__.ContentNode = ContentNode;function HashNode(pairs) {
+ this.type = "hash";
+ this.pairs = pairs;
+ }
+
+ __exports__.HashNode = HashNode;function IdNode(parts) {
+ this.type = "ID";
+
+ var original = "",
+ dig = [],
+ depth = 0;
+
+ for(var i=0,l=parts.length; i<l; i++) {
+ var part = parts[i].part;
+ original += (parts[i].separator || '') + part;
+
+ if (part === ".." || part === "." || part === "this") {
+ if (dig.length > 0) { throw new Exception("Invalid path: " + original); }
+ else if (part === "..") { depth++; }
+ else { this.isScoped = true; }
+ }
+ else { dig.push(part); }
+ }
+
+ this.original = original;
+ this.parts = dig;
+ this.string = dig.join('.');
+ this.depth = depth;
+
+ // an ID is simple if it only has one part, and that part is not
+ // `..` or `this`.
+ this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
+
+ this.stringModeValue = this.string;
+ }
+
+ __exports__.IdNode = IdNode;function PartialNameNode(name) {
+ this.type = "PARTIAL_NAME";
+ this.name = name.original;
+ }
+
+ __exports__.PartialNameNode = PartialNameNode;function DataNode(id) {
+ this.type = "DATA";
+ this.id = id;
+ }
+
+ __exports__.DataNode = DataNode;function StringNode(string) {
+ this.type = "STRING";
+ this.original =
+ this.string =
+ this.stringModeValue = string;
+ }
+
+ __exports__.StringNode = StringNode;function IntegerNode(integer) {
+ this.type = "INTEGER";
+ this.original =
+ this.integer = integer;
+ this.stringModeValue = Number(integer);
+ }
+
+ __exports__.IntegerNode = IntegerNode;function BooleanNode(bool) {
+ this.type = "BOOLEAN";
+ this.bool = bool;
+ this.stringModeValue = bool === "true";
+ }
+
+ __exports__.BooleanNode = BooleanNode;function CommentNode(comment) {
+ this.type = "comment";
+ this.comment = comment;
+ }
+
+ __exports__.CommentNode = CommentNode;
+ return __exports__;
+})(__module5__);
+
+// handlebars/compiler/parser.js
+var __module9__ = (function() {
+ "use strict";
+ var __exports__;
+ /* Jison generated parser */
+ var handlebars = (function(){
+ var parser = {trace: function trace() { },
+ yy: {},
+ symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"inMustache_repetition0":28,"inMustache_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"hash":35,"hash_repetition_plus0":36,"hashSegment":37,"ID":38,"EQUALS":39,"DATA":40,"pathSegments":41,"SEP":42,"$accept":0,"$end":1},
+ terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",38:"ID",39:"EQUALS",40:"DATA",42:"SEP"},
+ productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[35,1],[37,3],[26,1],[26,1],[26,1],[30,2],[21,1],[41,3],[41,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[36,1],[36,2]],
+ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
+
+ var $0 = $$.length - 1;
+ switch (yystate) {
+ case 1: return new yy.ProgramNode($$[$0-1]);
+ break;
+ case 2: return new yy.ProgramNode([]);
+ break;
+ case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0]);
+ break;
+ case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0]);
+ break;
+ case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], []);
+ break;
+ case 6:this.$ = new yy.ProgramNode($$[$0]);
+ break;
+ case 7:this.$ = new yy.ProgramNode([]);
+ break;
+ case 8:this.$ = new yy.ProgramNode([]);
+ break;
+ case 9:this.$ = [$$[$0]];
+ break;
+ case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
+ break;
+ case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
+ break;
+ case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
+ break;
+ case 13:this.$ = $$[$0];
+ break;
+ case 14:this.$ = $$[$0];
+ break;
+ case 15:this.$ = new yy.ContentNode($$[$0]);
+ break;
+ case 16:this.$ = new yy.CommentNode($$[$0]);
+ break;
+ case 17:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
+ break;
+ case 18:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
+ break;
+ case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
+ break;
+ case 20:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
+ break;
+ case 21:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
+ break;
+ case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]));
+ break;
+ case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
+ break;
+ case 24:this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]];
+ break;
+ case 25:this.$ = [[$$[$0]], null];
+ break;
+ case 26:this.$ = $$[$0];
+ break;
+ case 27:this.$ = new yy.StringNode($$[$0]);
+ break;
+ case 28:this.$ = new yy.IntegerNode($$[$0]);
+ break;
+ case 29:this.$ = new yy.BooleanNode($$[$0]);
+ break;
+ case 30:this.$ = $$[$0];
+ break;
+ case 31:this.$ = new yy.HashNode($$[$0]);
+ break;
+ case 32:this.$ = [$$[$0-2], $$[$0]];
+ break;
+ case 33:this.$ = new yy.PartialNameNode($$[$0]);
+ break;
+ case 34:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0]));
+ break;
+ case 35:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0]));
+ break;
+ case 36:this.$ = new yy.DataNode($$[$0]);
+ break;
+ case 37:this.$ = new yy.IdNode($$[$0]);
+ break;
+ case 38: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
+ break;
+ case 39:this.$ = [{part: $$[$0]}];
+ break;
+ case 42:this.$ = [];
+ break;
+ case 43:$$[$0-1].push($$[$0]);
+ break;
+ case 46:this.$ = [$$[$0]];
+ break;
+ case 47:$$[$0-1].push($$[$0]);
+ break;
+ }
+ },
+ table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:29,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:30,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:31,21:24,30:25,38:[1,28],40:[1,27],41:26},{21:33,26:32,32:[1,34],33:[1,35],38:[1,28],41:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,38:[1,28],40:[1,27],41:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,42],24:[2,42],28:43,32:[2,42],33:[2,42],34:[2,42],38:[2,42],40:[2,42]},{18:[2,25],24:[2,25]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],38:[2,37],40:[2,37],42:[1,44]},{21:45,38:[1,28],41:26},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],38:[2,39],40:[2,39],42:[2,39]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,40],21:50,27:49,38:[1,28],41:26},{18:[2,33],38:[2,33]},{18:[2,34],38:[2,34]},{18:[2,35],38:[2,35]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,38:[1,28],41:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,44],21:56,24:[2,44],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:55,36:61,37:62,38:[1,63],40:[1,27],41:26},{38:[1,64]},{18:[2,36],24:[2,36],32:[2,36],33:[2,36],34:[2,36],38:[2,36],40:[2,36]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,65]},{18:[2,41]},{18:[1,66]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24]},{18:[2,43],24:[2,43],32:[2,43],33:[2,43],34:[2,43],38:[2,43],40:[2,43]},{18:[2,45],24:[2,45]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],38:[2,26],40:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],38:[2,27],40:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],38:[2,28],40:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],38:[2,29],40:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],38:[2,30],40:[2,30]},{18:[2,31],24:[2,31],37:67,38:[1,68]},{18:[2,46],24:[2,46],38:[2,46]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],38:[2,39],39:[1,69],40:[2,39],42:[2,39]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],38:[2,38],40:[2,38],42:[2,38]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{18:[2,47],24:[2,47],38:[2,47]},{39:[1,69]},{21:56,30:60,31:70,32:[1,57],33:[1,58],34:[1,59],38:[1,28],40:[1,27],41:26},{18:[2,32],24:[2,32],38:[2,32]}],
+ defaultActions: {3:[2,2],16:[2,1],50:[2,41]},
+ parseError: function parseError(str, hash) {
+ throw new Error(str);
+ },
+ parse: function parse(input) {
+ var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
+ this.lexer.setInput(input);
+ this.lexer.yy = this.yy;
+ this.yy.lexer = this.lexer;
+ this.yy.parser = this;
+ if (typeof this.lexer.yylloc == "undefined")
+ this.lexer.yylloc = {};
+ var yyloc = this.lexer.yylloc;
+ lstack.push(yyloc);
+ var ranges = this.lexer.options && this.lexer.options.ranges;
+ if (typeof this.yy.parseError === "function")
+ this.parseError = this.yy.parseError;
+ function popStack(n) {
+ stack.length = stack.length - 2 * n;
+ vstack.length = vstack.length - n;
+ lstack.length = lstack.length - n;
+ }
+ function lex() {
+ var token;
+ token = self.lexer.lex() || 1;
+ if (typeof token !== "number") {
+ token = self.symbols_[token] || token;
+ }
+ return token;
+ }
+ var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
+ while (true) {
+ state = stack[stack.length - 1];
+ if (this.defaultActions[state]) {
+ action = this.defaultActions[state];
+ } else {
+ if (symbol === null || typeof symbol == "undefined") {
+ symbol = lex();
+ }
+ action = table[state] && table[state][symbol];
+ }
+ if (typeof action === "undefined" || !action.length || !action[0]) {
+ var errStr = "";
+ if (!recovering) {
+ expected = [];
+ for (p in table[state])
+ if (this.terminals_[p] && p > 2) {
+ expected.push("'" + this.terminals_[p] + "'");
+ }
+ if (this.lexer.showPosition) {
+ errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
+ } else {
+ errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
+ }
+ this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
+ }
+ }
+ if (action[0] instanceof Array && action.length > 1) {
+ throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
+ }
+ switch (action[0]) {
+ case 1:
+ stack.push(symbol);
+ vstack.push(this.lexer.yytext);
+ lstack.push(this.lexer.yylloc);
+ stack.push(action[1]);
+ symbol = null;
+ if (!preErrorSymbol) {
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ if (recovering > 0)
+ recovering--;
+ } else {
+ symbol = preErrorSymbol;
+ preErrorSymbol = null;
+ }
+ break;
+ case 2:
+ len = this.productions_[action[1]][1];
+ yyval.$ = vstack[vstack.length - len];
+ yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
+ if (ranges) {
+ yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
+ }
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
+ if (typeof r !== "undefined") {
+ return r;
+ }
+ if (len) {
+ stack = stack.slice(0, -1 * len * 2);
+ vstack = vstack.slice(0, -1 * len);
+ lstack = lstack.slice(0, -1 * len);
+ }
+ stack.push(this.productions_[action[1]][0]);
+ vstack.push(yyval.$);
+ lstack.push(yyval._$);
+ newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
+ stack.push(newState);
+ break;
+ case 3:
+ return true;
+ }
+ }
+ return true;
+ }
+ };
+
+
+ function stripFlags(open, close) {
+ return {
+ left: open[2] === '~',
+ right: close[0] === '~' || close[1] === '~'
+ };
+ }
+
+ /* Jison generated lexer */
+ var lexer = (function(){
+ var lexer = ({EOF:1,
+ parseError:function parseError(str, hash) {
+ if (this.yy.parser) {
+ this.yy.parser.parseError(str, hash);
+ } else {
+ throw new Error(str);
+ }
+ },
+ setInput:function (input) {
+ this._input = input;
+ this._more = this._less = this.done = false;
+ this.yylineno = this.yyleng = 0;
+ this.yytext = this.matched = this.match = '';
+ this.conditionStack = ['INITIAL'];
+ this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
+ if (this.options.ranges) this.yylloc.range = [0,0];
+ this.offset = 0;
+ return this;
+ },
+ input:function () {
+ var ch = this._input[0];
+ this.yytext += ch;
+ this.yyleng++;
+ this.offset++;
+ this.match += ch;
+ this.matched += ch;
+ var lines = ch.match(/(?:\r\n?|\n).*/g);
+ if (lines) {
+ this.yylineno++;
+ this.yylloc.last_line++;
+ } else {
+ this.yylloc.last_column++;
+ }
+ if (this.options.ranges) this.yylloc.range[1]++;
+
+ this._input = this._input.slice(1);
+ return ch;
+ },
+ unput:function (ch) {
+ var len = ch.length;
+ var lines = ch.split(/(?:\r\n?|\n)/g);
+
+ this._input = ch + this._input;
+ this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
+ //this.yyleng -= len;
+ this.offset -= len;
+ var oldLines = this.match.split(/(?:\r\n?|\n)/g);
+ this.match = this.match.substr(0, this.match.length-1);
+ this.matched = this.matched.substr(0, this.matched.length-1);
+
+ if (lines.length-1) this.yylineno -= lines.length-1;
+ var r = this.yylloc.range;
+
+ this.yylloc = {first_line: this.yylloc.first_line,
+ last_line: this.yylineno+1,
+ first_column: this.yylloc.first_column,
+ last_column: lines ?
+ (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
+ this.yylloc.first_column - len
+ };
+
+ if (this.options.ranges) {
+ this.yylloc.range = [r[0], r[0] + this.yyleng - len];
+ }
+ return this;
+ },
+ more:function () {
+ this._more = true;
+ return this;
+ },
+ less:function (n) {
+ this.unput(this.match.slice(n));
+ },
+ pastInput:function () {
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
+ },
+ upcomingInput:function () {
+ var next = this.match;
+ if (next.length < 20) {
+ next += this._input.substr(0, 20-next.length);
+ }
+ return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
+ },
+ showPosition:function () {
+ var pre = this.pastInput();
+ var c = new Array(pre.length + 1).join("-");
+ return pre + this.upcomingInput() + "\n" + c+"^";
+ },
+ next:function () {
+ if (this.done) {
+ return this.EOF;
+ }
+ if (!this._input) this.done = true;
+
+ var token,
+ match,
+ tempMatch,
+ index,
+ col,
+ lines;
+ if (!this._more) {
+ this.yytext = '';
+ this.match = '';
+ }
+ var rules = this._currentRules();
+ for (var i=0;i < rules.length; i++) {
+ tempMatch = this._input.match(this.rules[rules[i]]);
+ if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
+ match = tempMatch;
+ index = i;
+ if (!this.options.flex) break;
+ }
+ }
+ if (match) {
+ lines = match[0].match(/(?:\r\n?|\n).*/g);
+ if (lines) this.yylineno += lines.length;
+ this.yylloc = {first_line: this.yylloc.last_line,
+ last_line: this.yylineno+1,
+ first_column: this.yylloc.last_column,
+ last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
+ this.yytext += match[0];
+ this.match += match[0];
+ this.matches = match;
+ this.yyleng = this.yytext.length;
+ if (this.options.ranges) {
+ this.yylloc.range = [this.offset, this.offset += this.yyleng];
+ }
+ this._more = false;
+ this._input = this._input.slice(match[0].length);
+ this.matched += match[0];
+ token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
+ if (this.done && this._input) this.done = false;
+ if (token) return token;
+ else return;
+ }
+ if (this._input === "") {
+ return this.EOF;
+ } else {
+ return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
+ {text: "", token: null, line: this.yylineno});
+ }
+ },
+ lex:function lex() {
+ var r = this.next();
+ if (typeof r !== 'undefined') {
+ return r;
+ } else {
+ return this.lex();
+ }
+ },
+ begin:function begin(condition) {
+ this.conditionStack.push(condition);
+ },
+ popState:function popState() {
+ return this.conditionStack.pop();
+ },
+ _currentRules:function _currentRules() {
+ return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
+ },
+ topState:function () {
+ return this.conditionStack[this.conditionStack.length-2];
+ },
+ pushState:function begin(condition) {
+ this.begin(condition);
+ }});
+ lexer.options = {};
+ lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
+
+
+ function strip(start, end) {
+ return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
+ }
+
+
+ var YYSTATE=YY_START
+ switch($avoiding_name_collisions) {
+ case 0:
+ if(yy_.yytext.slice(-2) === "\\\\") {
+ strip(0,1);
+ this.begin("mu");
+ } else if(yy_.yytext.slice(-1) === "\\") {
+ strip(0,1);
+ this.begin("emu");
+ } else {
+ this.begin("mu");
+ }
+ if(yy_.yytext) return 14;
+
+ break;
+ case 1:return 14;
+ break;
+ case 2:
+ if(yy_.yytext.slice(-1) !== "\\") this.popState();
+ if(yy_.yytext.slice(-1) === "\\") strip(0,1);
+ return 14;
+
+ break;
+ case 3:strip(0,4); this.popState(); return 15;
+ break;
+ case 4:return 25;
+ break;
+ case 5:return 16;
+ break;
+ case 6:return 20;
+ break;
+ case 7:return 19;
+ break;
+ case 8:return 19;
+ break;
+ case 9:return 23;
+ break;
+ case 10:return 22;
+ break;
+ case 11:this.popState(); this.begin('com');
+ break;
+ case 12:strip(3,5); this.popState(); return 15;
+ break;
+ case 13:return 22;
+ break;
+ case 14:return 39;
+ break;
+ case 15:return 38;
+ break;
+ case 16:return 38;
+ break;
+ case 17:return 42;
+ break;
+ case 18:/*ignore whitespace*/
+ break;
+ case 19:this.popState(); return 24;
+ break;
+ case 20:this.popState(); return 18;
+ break;
+ case 21:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
+ break;
+ case 22:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
+ break;
+ case 23:return 40;
+ break;
+ case 24:return 34;
+ break;
+ case 25:return 34;
+ break;
+ case 26:return 33;
+ break;
+ case 27:return 38;
+ break;
+ case 28:yy_.yytext = strip(1,2); return 38;
+ break;
+ case 29:return 'INVALID';
+ break;
+ case 30:return 5;
+ break;
+ }
+ };
+ lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s])))/,/^(?:false(?=([~}\s])))/,/^(?:-?[0-9]+(?=([~}\s])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
+ lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,30],"inclusive":true}};
+ return lexer;})()
+ parser.lexer = lexer;
+ function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
+ return new Parser;
+ })();__exports__ = handlebars;
+ return __exports__;
+})();
+
+// handlebars/compiler/base.js
+var __module8__ = (function(__dependency1__, __dependency2__) {
+ "use strict";
+ var __exports__ = {};
+ var parser = __dependency1__;
+ var AST = __dependency2__;
+
+ __exports__.parser = parser;
+
+ function parse(input) {
+ // Just return if an already-compile AST was passed in.
+ if(input.constructor === AST.ProgramNode) { return input; }
+
+ parser.yy = AST;
+ return parser.parse(input);
+ }
+
+ __exports__.parse = parse;
+ return __exports__;
+})(__module9__, __module7__);
+
+// handlebars/compiler/javascript-compiler.js
+var __module11__ = (function(__dependency1__) {
+ "use strict";
+ var __exports__;
+ var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
+ var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
+ var log = __dependency1__.log;
+
+ function Literal(value) {
+ this.value = value;
+ }
+
+ function JavaScriptCompiler() {}
+
+ JavaScriptCompiler.prototype = {
+ // PUBLIC API: You can override these methods in a subclass to provide
+ // alternative compiled forms for name lookup and buffering semantics
+ nameLookup: function(parent, name /* , type*/) {
+ var wrap,
+ ret;
+ if (parent.indexOf('depth') === 0) {
+ wrap = true;
+ }
+
+ if (/^[0-9]+$/.test(name)) {
+ ret = parent + "[" + name + "]";
+ } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
+ ret = parent + "." + name;
+ }
+ else {
+ ret = parent + "['" + name + "']";
+ }
+
+ if (wrap) {
+ return '(' + parent + ' && ' + ret + ')';
+ } else {
+ return ret;
+ }
+ },
+
+ appendToBuffer: function(string) {
+ if (this.environment.isSimple) {
+ return "return " + string + ";";
+ } else {
+ return {
+ appendToBuffer: true,
+ content: string,
+ toString: function() { return "buffer += " + string + ";"; }
+ };
+ }
+ },
+
+ initializeBuffer: function() {
+ return this.quotedString("");
+ },
+
+ namespace: "Handlebars",
+ // END PUBLIC API
+
+ compile: function(environment, options, context, asObject) {
+ this.environment = environment;
+ this.options = options || {};
+
+ log('debug', this.environment.disassemble() + "\n\n");
+
+ this.name = this.environment.name;
+ this.isChild = !!context;
+ this.context = context || {
+ programs: [],
+ environments: [],
+ aliases: { }
+ };
+
+ this.preamble();
+
+ this.stackSlot = 0;
+ this.stackVars = [];
+ this.registers = { list: [] };
+ this.compileStack = [];
+ this.inlineStack = [];
+
+ this.compileChildren(environment, options);
+
+ var opcodes = environment.opcodes, opcode;
+
+ this.i = 0;
+
+ for(var l=opcodes.length; this.i<l; this.i++) {
+ opcode = opcodes[this.i];
+
+ if(opcode.opcode === 'DECLARE') {
+ this[opcode.name] = opcode.value;
+ } else {
+ this[opcode.opcode].apply(this, opcode.args);
+ }
+
+ // Reset the stripNext flag if it was not set by this operation.
+ if (opcode.opcode !== this.stripNext) {
+ this.stripNext = false;
+ }
+ }
+
+ // Flush any trailing content that might be pending.
+ this.pushSource('');
+
+ return this.createFunctionContext(asObject);
+ },
+
+ preamble: function() {
+ var out = [];
+
+ if (!this.isChild) {
+ var namespace = this.namespace;
+
+ var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
+ if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
+ if (this.options.data) { copies = copies + " data = data || {};"; }
+ out.push(copies);
+ } else {
+ out.push('');
+ }
+
+ if (!this.environment.isSimple) {
+ out.push(", buffer = " + this.initializeBuffer());
+ } else {
+ out.push("");
+ }
+
+ // track the last context pushed into place to allow skipping the
+ // getContext opcode when it would be a noop
+ this.lastContext = 0;
+ this.source = out;
+ },
+
+ createFunctionContext: function(asObject) {
+ var locals = this.stackVars.concat(this.registers.list);
+
+ if(locals.length > 0) {
+ this.source[1] = this.source[1] + ", " + locals.join(", ");
+ }
+
+ // Generate minimizer alias mappings
+ if (!this.isChild) {
+ for (var alias in this.context.aliases) {
+ if (this.context.aliases.hasOwnProperty(alias)) {
+ this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
+ }
+ }
+ }
+
+ if (this.source[1]) {
+ this.source[1] = "var " + this.source[1].substring(2) + ";";
+ }
+
+ // Merge children
+ if (!this.isChild) {
+ this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
+ }
+
+ if (!this.environment.isSimple) {
+ this.pushSource("return buffer;");
+ }
+
+ var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
+
+ for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
+ params.push("depth" + this.environment.depths.list[i]);
+ }
+
+ // Perform a second pass over the output to merge content when possible
+ var source = this.mergeSource();
+
+ if (!this.isChild) {
+ var revision = COMPILER_REVISION,
+ versions = REVISION_CHANGES[revision];
+ source = "this.compilerInfo = ["+revision+",'"+versions+"'];\n"+source;
+ }
+
+ if (asObject) {
+ params.push(source);
+
+ return Function.apply(this, params);
+ } else {
+ var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
+ log('debug', functionSource + "\n\n");
+ return functionSource;
+ }
+ },
+ mergeSource: function() {
+ // WARN: We are not handling the case where buffer is still populated as the source should
+ // not have buffer append operations as their final action.
+ var source = '',
+ buffer;
+ for (var i = 0, len = this.source.length; i < len; i++) {
+ var line = this.source[i];
+ if (line.appendToBuffer) {
+ if (buffer) {
+ buffer = buffer + '\n + ' + line.content;
+ } else {
+ buffer = line.content;
+ }
+ } else {
+ if (buffer) {
+ source += 'buffer += ' + buffer + ';\n ';
+ buffer = undefined;
+ }
+ source += line + '\n ';
+ }
+ }
+ return source;
+ },
+
+ // [blockValue]
+ //
+ // On stack, before: hash, inverse, program, value
+ // On stack, after: return value of blockHelperMissing
+ //
+ // The purpose of this opcode is to take a block of the form
+ // `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
+ // replace it on the stack with the result of properly
+ // invoking blockHelperMissing.
+ blockValue: function() {
+ this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
+
+ var params = ["depth0"];
+ this.setupParams(0, params);
+
+ this.replaceStack(function(current) {
+ params.splice(1, 0, current);
+ return "blockHelperMissing.call(" + params.join(", ") + ")";
+ });
+ },
+
+ // [ambiguousBlockValue]
+ //
+ // On stack, before: hash, inverse, program, value
+ // Compiler value, before: lastHelper=value of last found helper, if any
+ // On stack, after, if no lastHelper: same as [blockValue]
+ // On stack, after, if lastHelper: value
+ ambiguousBlockValue: function() {
+ this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
+
+ var params = ["depth0"];
+ this.setupParams(0, params);
+
+ var current = this.topStack();
+ params.splice(1, 0, current);
+
+ // Use the options value generated from the invocation
+ params[params.length-1] = 'options';
+
+ this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
+ },
+
+ // [appendContent]
+ //
+ // On stack, before: ...
+ // On stack, after: ...
+ //
+ // Appends the string value of `content` to the current buffer
+ appendContent: function(content) {
+ if (this.pendingContent) {
+ content = this.pendingContent + content;
+ }
+ if (this.stripNext) {
+ content = content.replace(/^\s+/, '');
+ }
+
+ this.pendingContent = content;
+ },
+
+ // [strip]
+ //
+ // On stack, before: ...
+ // On stack, after: ...
+ //
+ // Removes any trailing whitespace from the prior content node and flags
+ // the next operation for stripping if it is a content node.
+ strip: function() {
+ if (this.pendingContent) {
+ this.pendingContent = this.pendingContent.replace(/\s+$/, '');
+ }
+ this.stripNext = 'strip';
+ },
+
+ // [append]
+ //
+ // On stack, before: value, ...
+ // On stack, after: ...
+ //
+ // Coerces `value` to a String and appends it to the current buffer.
+ //
+ // If `value` is truthy, or 0, it is coerced into a string and appended
+ // Otherwise, the empty string is appended
+ append: function() {
+ // Force anything that is inlined onto the stack so we don't have duplication
+ // when we examine local
+ this.flushInline();
+ var local = this.popStack();
+ this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
+ if (this.environment.isSimple) {
+ this.pushSource("else { " + this.appendToBuffer("''") + " }");
+ }
+ },
+
+ // [appendEscaped]
+ //
+ // On stack, before: value, ...
+ // On stack, after: ...
+ //
+ // Escape `value` and append it to the buffer
+ appendEscaped: function() {
+ this.context.aliases.escapeExpression = 'this.escapeExpression';
+
+ this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
+ },
+
+ // [getContext]
+ //
+ // On stack, before: ...
+ // On stack, after: ...
+ // Compiler value, after: lastContext=depth
+ //
+ // Set the value of the `lastContext` compiler value to the depth
+ getContext: function(depth) {
+ if(this.lastContext !== depth) {
+ this.lastContext = depth;
+ }
+ },
+
+ // [lookupOnContext]
+ //
+ // On stack, before: ...
+ // On stack, after: currentContext[name], ...
+ //
+ // Looks up the value of `name` on the current context and pushes
+ // it onto the stack.
+ lookupOnContext: function(name) {
+ this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
+ },
+
+ // [pushContext]
+ //
+ // On stack, before: ...
+ // On stack, after: currentContext, ...
+ //
+ // Pushes the value of the current context onto the stack.
+ pushContext: function() {
+ this.pushStackLiteral('depth' + this.lastContext);
+ },
+
+ // [resolvePossibleLambda]
+ //
+ // On stack, before: value, ...
+ // On stack, after: resolved value, ...
+ //
+ // If the `value` is a lambda, replace it on the stack by
+ // the return value of the lambda
+ resolvePossibleLambda: function() {
+ this.context.aliases.functionType = '"function"';
+
+ this.replaceStack(function(current) {
+ return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
+ });
+ },
+
+ // [lookup]
+ //
+ // On stack, before: value, ...
+ // On stack, after: value[name], ...
+ //
+ // Replace the value on the stack with the result of looking
+ // up `name` on `value`
+ lookup: function(name) {
+ this.replaceStack(function(current) {
+ return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
+ });
+ },
+
+ // [lookupData]
+ //
+ // On stack, before: ...
+ // On stack, after: data, ...
+ //
+ // Push the data lookup operator
+ lookupData: function() {
+ this.push('data');
+ },
+
+ // [pushStringParam]
+ //
+ // On stack, before: ...
+ // On stack, after: string, currentContext, ...
+ //
+ // This opcode is designed for use in string mode, which
+ // provides the string value of a parameter along with its
+ // depth rather than resolving it immediately.
+ pushStringParam: function(string, type) {
+ this.pushStackLiteral('depth' + this.lastContext);
+
+ this.pushString(type);
+
+ if (typeof string === 'string') {
+ this.pushString(string);
+ } else {
+ this.pushStackLiteral(string);
+ }
+ },
+
+ emptyHash: function() {
+ this.pushStackLiteral('{}');
+
+ if (this.options.stringParams) {
+ this.register('hashTypes', '{}');
+ this.register('hashContexts', '{}');
+ }
+ },
+ pushHash: function() {
+ this.hash = {values: [], types: [], contexts: []};
+ },
+ popHash: function() {
+ var hash = this.hash;
+ this.hash = undefined;
+
+ if (this.options.stringParams) {
+ this.register('hashContexts', '{' + hash.contexts.join(',') + '}');
+ this.register('hashTypes', '{' + hash.types.join(',') + '}');
+ }
+ this.push('{\n ' + hash.values.join(',\n ') + '\n }');
+ },
+
+ // [pushString]
+ //
+ // On stack, before: ...
+ // On stack, after: quotedString(string), ...
+ //
+ // Push a quoted version of `string` onto the stack
+ pushString: function(string) {
+ this.pushStackLiteral(this.quotedString(string));
+ },
+
+ // [push]
+ //
+ // On stack, before: ...
+ // On stack, after: expr, ...
+ //
+ // Push an expression onto the stack
+ push: function(expr) {
+ this.inlineStack.push(expr);
+ return expr;
+ },
+
+ // [pushLiteral]
+ //
+ // On stack, before: ...
+ // On stack, after: value, ...
+ //
+ // Pushes a value onto the stack. This operation prevents
+ // the compiler from creating a temporary variable to hold
+ // it.
+ pushLiteral: function(value) {
+ this.pushStackLiteral(value);
+ },
+
+ // [pushProgram]
+ //
+ // On stack, before: ...
+ // On stack, after: program(guid), ...
+ //
+ // Push a program expression onto the stack. This takes
+ // a compile-time guid and converts it into a runtime-accessible
+ // expression.
+ pushProgram: function(guid) {
+ if (guid != null) {
+ this.pushStackLiteral(this.programExpression(guid));
+ } else {
+ this.pushStackLiteral(null);
+ }
+ },
+
+ // [invokeHelper]
+ //
+ // On stack, before: hash, inverse, program, params..., ...
+ // On stack, after: result of helper invocation
+ //
+ // Pops off the helper's parameters, invokes the helper,
+ // and pushes the helper's return value onto the stack.
+ //
+ // If the helper is not found, `helperMissing` is called.
+ invokeHelper: function(paramSize, name) {
+ this.context.aliases.helperMissing = 'helpers.helperMissing';
+
+ var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
+ var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
+
+ this.push(helper.name + ' || ' + nonHelper);
+ this.replaceStack(function(name) {
+ return name + ' ? ' + name + '.call(' +
+ helper.callParams + ") " + ": helperMissing.call(" +
+ helper.helperMissingParams + ")";
+ });
+ },
+
+ // [invokeKnownHelper]
+ //
+ // On stack, before: hash, inverse, program, params..., ...
+ // On stack, after: result of helper invocation
+ //
+ // This operation is used when the helper is known to exist,
+ // so a `helperMissing` fallback is not required.
+ invokeKnownHelper: function(paramSize, name) {
+ var helper = this.setupHelper(paramSize, name);
+ this.push(helper.name + ".call(" + helper.callParams + ")");
+ },
+
+ // [invokeAmbiguous]
+ //
+ // On stack, before: hash, inverse, program, params..., ...
+ // On stack, after: result of disambiguation
+ //
+ // This operation is used when an expression like `{{foo}}`
+ // is provided, but we don't know at compile-time whether it
+ // is a helper or a path.
+ //
+ // This operation emits more code than the other options,
+ // and can be avoided by passing the `knownHelpers` and
+ // `knownHelpersOnly` flags at compile-time.
+ invokeAmbiguous: function(name, helperCall) {
+ this.context.aliases.functionType = '"function"';
+
+ this.pushStackLiteral('{}'); // Hash value
+ var helper = this.setupHelper(0, name, helperCall);
+
+ var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
+
+ var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
+ var nextStack = this.nextStack();
+
+ this.pushSource('if (' + nextStack + ' = ' + helperName + ') { ' + nextStack + ' = ' + nextStack + '.call(' + helper.callParams + '); }');
+ this.pushSource('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '.call(' + helper.callParams + ') : ' + nextStack + '; }');
+ },
+
+ // [invokePartial]
+ //
+ // On stack, before: context, ...
+ // On stack after: result of partial invocation
+ //
+ // This operation pops off a context, invokes a partial with that context,
+ // and pushes the result of the invocation back.
+ invokePartial: function(name) {
+ var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
+
+ if (this.options.data) {
+ params.push("data");
+ }
+
+ this.context.aliases.self = "this";
+ this.push("self.invokePartial(" + params.join(", ") + ")");
+ },
+
+ // [assignToHash]
+ //
+ // On stack, before: value, hash, ...
+ // On stack, after: hash, ...
+ //
+ // Pops a value and hash off the stack, assigns `hash[key] = value`
+ // and pushes the hash back onto the stack.
+ assignToHash: function(key) {
+ var value = this.popStack(),
+ context,
+ type;
+
+ if (this.options.stringParams) {
+ type = this.popStack();
+ context = this.popStack();
+ }
+
+ var hash = this.hash;
+ if (context) {
+ hash.contexts.push("'" + key + "': " + context);
+ }
+ if (type) {
+ hash.types.push("'" + key + "': " + type);
+ }
+ hash.values.push("'" + key + "': (" + value + ")");
+ },
+
+ // HELPERS
+
+ compiler: JavaScriptCompiler,
+
+ compileChildren: function(environment, options) {
+ var children = environment.children, child, compiler;
+
+ for(var i=0, l=children.length; i<l; i++) {
+ child = children[i];
+ compiler = new this.compiler();
+
+ var index = this.matchExistingProgram(child);
+
+ if (index == null) {
+ this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
+ index = this.context.programs.length;
+ child.index = index;
+ child.name = 'program' + index;
+ this.context.programs[index] = compiler.compile(child, options, this.context);
+ this.context.environments[index] = child;
+ } else {
+ child.index = index;
+ child.name = 'program' + index;
+ }
+ }
+ },
+ matchExistingProgram: function(child) {
+ for (var i = 0, len = this.context.environments.length; i < len; i++) {
+ var environment = this.context.environments[i];
+ if (environment && environment.equals(child)) {
+ return i;
+ }
+ }
+ },
+
+ programExpression: function(guid) {
+ this.context.aliases.self = "this";
+
+ if(guid == null) {
+ return "self.noop";
+ }
+
+ var child = this.environment.children[guid],
+ depths = child.depths.list, depth;
+
+ var programParams = [child.index, child.name, "data"];
+
+ for(var i=0, l = depths.length; i<l; i++) {
+ depth = depths[i];
+
+ if(depth === 1) { programParams.push("depth0"); }
+ else { programParams.push("depth" + (depth - 1)); }
+ }
+
+ return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
+ },
+
+ register: function(name, val) {
+ this.useRegister(name);
+ this.pushSource(name + " = " + val + ";");
+ },
+
+ useRegister: function(name) {
+ if(!this.registers[name]) {
+ this.registers[name] = true;
+ this.registers.list.push(name);
+ }
+ },
+
+ pushStackLiteral: function(item) {
+ return this.push(new Literal(item));
+ },
+
+ pushSource: function(source) {
+ if (this.pendingContent) {
+ this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
+ this.pendingContent = undefined;
+ }
+
+ if (source) {
+ this.source.push(source);
+ }
+ },
+
+ pushStack: function(item) {
+ this.flushInline();
+
+ var stack = this.incrStack();
+ if (item) {
+ this.pushSource(stack + " = " + item + ";");
+ }
+ this.compileStack.push(stack);
+ return stack;
+ },
+
+ replaceStack: function(callback) {
+ var prefix = '',
+ inline = this.isInline(),
+ stack;
+
+ // If we are currently inline then we want to merge the inline statement into the
+ // replacement statement via ','
+ if (inline) {
+ var top = this.popStack(true);
+
+ if (top instanceof Literal) {
+ // Literals do not need to be inlined
+ stack = top.value;
+ } else {
+ // Get or create the current stack name for use by the inline
+ var name = this.stackSlot ? this.topStackName() : this.incrStack();
+
+ prefix = '(' + this.push(name) + ' = ' + top + '),';
+ stack = this.topStack();
+ }
+ } else {
+ stack = this.topStack();
+ }
+
+ var item = callback.call(this, stack);
+
+ if (inline) {
+ if (this.inlineStack.length || this.compileStack.length) {
+ this.popStack();
+ }
+ this.push('(' + prefix + item + ')');
+ } else {
+ // Prevent modification of the context depth variable. Through replaceStack
+ if (!/^stack/.test(stack)) {
+ stack = this.nextStack();
+ }
+
+ this.pushSource(stack + " = (" + prefix + item + ");");
+ }
+ return stack;
+ },
+
+ nextStack: function() {
+ return this.pushStack();
+ },
+
+ incrStack: function() {
+ this.stackSlot++;
+ if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
+ return this.topStackName();
+ },
+ topStackName: function() {
+ return "stack" + this.stackSlot;
+ },
+ flushInline: function() {
+ var inlineStack = this.inlineStack;
+ if (inlineStack.length) {
+ this.inlineStack = [];
+ for (var i = 0, len = inlineStack.length; i < len; i++) {
+ var entry = inlineStack[i];
+ if (entry instanceof Literal) {
+ this.compileStack.push(entry);
+ } else {
+ this.pushStack(entry);
+ }
+ }
+ }
+ },
+ isInline: function() {
+ return this.inlineStack.length;
+ },
+
+ popStack: function(wrapped) {
+ var inline = this.isInline(),
+ item = (inline ? this.inlineStack : this.compileStack).pop();
+
+ if (!wrapped && (item instanceof Literal)) {
+ return item.value;
+ } else {
+ if (!inline) {
+ this.stackSlot--;
+ }
+ return item;
+ }
+ },
+
+ topStack: function(wrapped) {
+ var stack = (this.isInline() ? this.inlineStack : this.compileStack),
+ item = stack[stack.length - 1];
+
+ if (!wrapped && (item instanceof Literal)) {
+ return item.value;
+ } else {
+ return item;
+ }
+ },
+
+ quotedString: function(str) {
+ return '"' + str
+ .replace(/\\/g, '\\\\')
+ .replace(/"/g, '\\"')
+ .replace(/\n/g, '\\n')
+ .replace(/\r/g, '\\r')
+ .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
+ .replace(/\u2029/g, '\\u2029') + '"';
+ },
+
+ setupHelper: function(paramSize, name, missingParams) {
+ var params = [];
+ this.setupParams(paramSize, params, missingParams);
+ var foundHelper = this.nameLookup('helpers', name, 'helper');
+
+ return {
+ params: params,
+ name: foundHelper,
+ callParams: ["depth0"].concat(params).join(", "),
+ helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
+ };
+ },
+
+ // the params and contexts arguments are passed in arrays
+ // to fill in
+ setupParams: function(paramSize, params, useRegister) {
+ var options = [], contexts = [], types = [], param, inverse, program;
+
+ options.push("hash:" + this.popStack());
+
+ inverse = this.popStack();
+ program = this.popStack();
+
+ // Avoid setting fn and inverse if neither are set. This allows
+ // helpers to do a check for `if (options.fn)`
+ if (program || inverse) {
+ if (!program) {
+ this.context.aliases.self = "this";
+ program = "self.noop";
+ }
+
+ if (!inverse) {
+ this.context.aliases.self = "this";
+ inverse = "self.noop";
+ }
+
+ options.push("inverse:" + inverse);
+ options.push("fn:" + program);
+ }
+
+ for(var i=0; i<paramSize; i++) {
+ param = this.popStack();
+ params.push(param);
+
+ if(this.options.stringParams) {
+ types.push(this.popStack());
+ contexts.push(this.popStack());
+ }
+ }
+
+ if (this.options.stringParams) {
+ options.push("contexts:[" + contexts.join(",") + "]");
+ options.push("types:[" + types.join(",") + "]");
+ options.push("hashContexts:hashContexts");
+ options.push("hashTypes:hashTypes");
+ }
+
+ if(this.options.data) {
+ options.push("data:data");
+ }
+
+ options = "{" + options.join(",") + "}";
+ if (useRegister) {
+ this.register('options', options);
+ params.push('options');
+ } else {
+ params.push(options);
+ }
+ return params.join(", ");
+ }
+ };
+
+ var reservedWords = (
+ "break else new var" +
+ " case finally return void" +
+ " catch for switch while" +
+ " continue function this with" +
+ " default if throw" +
+ " delete in try" +
+ " do instanceof typeof" +
+ " abstract enum int short" +
+ " boolean export interface static" +
+ " byte extends long super" +
+ " char final native synchronized" +
+ " class float package throws" +
+ " const goto private transient" +
+ " debugger implements protected volatile" +
+ " double import public let yield"
+ ).split(" ");
+
+ var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
+
+ for(var i=0, l=reservedWords.length; i<l; i++) {
+ compilerWords[reservedWords[i]] = true;
+ }
+
+ JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
+ if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
+ return true;
+ }
+ return false;
+ };
+
+ __exports__ = JavaScriptCompiler;
+ return __exports__;
+})(__module2__);
+
+// handlebars/compiler/compiler.js
+var __module10__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) {
+ "use strict";
+ var __exports__ = {};
+ var Exception = __dependency1__;
+ var parse = __dependency2__.parse;
+ var JavaScriptCompiler = __dependency3__;
+ var AST = __dependency4__;
+
+ function Compiler() {}
+
+ __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
+ // function in a context. This is necessary for mustache compatibility, which
+ // requires that context functions in blocks are evaluated by blockHelperMissing,
+ // and then proceed as if the resulting value was provided to blockHelperMissing.
+
+ Compiler.prototype = {
+ compiler: Compiler,
+
+ disassemble: function() {
+ var opcodes = this.opcodes, opcode, out = [], params, param;
+
+ for (var i=0, l=opcodes.length; i<l; i++) {
+ opcode = opcodes[i];
+
+ if (opcode.opcode === 'DECLARE') {
+ out.push("DECLARE " + opcode.name + "=" + opcode.value);
+ } else {
+ params = [];
+ for (var j=0; j<opcode.args.length; j++) {
+ param = opcode.args[j];
+ if (typeof param === "string") {
+ param = "\"" + param.replace("\n", "\\n") + "\"";
+ }
+ params.push(param);
+ }
+ out.push(opcode.opcode + " " + params.join(" "));
+ }
+ }
+
+ return out.join("\n");
+ },
+
+ equals: function(other) {
+ var len = this.opcodes.length;
+ if (other.opcodes.length !== len) {
+ return false;
+ }
+
+ for (var i = 0; i < len; i++) {
+ var opcode = this.opcodes[i],
+ otherOpcode = other.opcodes[i];
+ if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
+ return false;
+ }
+ for (var j = 0; j < opcode.args.length; j++) {
+ if (opcode.args[j] !== otherOpcode.args[j]) {
+ return false;
+ }
+ }
+ }
+
+ len = this.children.length;
+ if (other.children.length !== len) {
+ return false;
+ }
+ for (i = 0; i < len; i++) {
+ if (!this.children[i].equals(other.children[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ guid: 0,
+
+ compile: function(program, options) {
+ this.opcodes = [];
+ this.children = [];
+ this.depths = {list: []};
+ this.options = options;
+
+ // These changes will propagate to the other compiler components
+ var knownHelpers = this.options.knownHelpers;
+ this.options.knownHelpers = {
+ 'helperMissing': true,
+ 'blockHelperMissing': true,
+ 'each': true,
+ 'if': true,
+ 'unless': true,
+ 'with': true,
+ 'log': true
+ };
+ if (knownHelpers) {
+ for (var name in knownHelpers) {
+ this.options.knownHelpers[name] = knownHelpers[name];
+ }
+ }
+
+ return this.accept(program);
+ },
+
+ accept: function(node) {
+ var strip = node.strip || {},
+ ret;
+ if (strip.left) {
+ this.opcode('strip');
+ }
+
+ ret = this[node.type](node);
+
+ if (strip.right) {
+ this.opcode('strip');
+ }
+
+ return ret;
+ },
+
+ program: function(program) {
+ var statements = program.statements;
+
+ for(var i=0, l=statements.length; i<l; i++) {
+ this.accept(statements[i]);
+ }
+ this.isSimple = l === 1;
+
+ this.depths.list = this.depths.list.sort(function(a, b) {
+ return a - b;
+ });
+
+ return this;
+ },
+
+ compileProgram: function(program) {
+ var result = new this.compiler().compile(program, this.options);
+ var guid = this.guid++, depth;
+
+ this.usePartial = this.usePartial || result.usePartial;
+
+ this.children[guid] = result;
+
+ for(var i=0, l=result.depths.list.length; i<l; i++) {
+ depth = result.depths.list[i];
+
+ if(depth < 2) { continue; }
+ else { this.addDepth(depth - 1); }
+ }
+
+ return guid;
+ },
+
+ block: function(block) {
+ var mustache = block.mustache,
+ program = block.program,
+ inverse = block.inverse;
+
+ if (program) {
+ program = this.compileProgram(program);
+ }
+
+ if (inverse) {
+ inverse = this.compileProgram(inverse);
+ }
+
+ var type = this.classifyMustache(mustache);
+
+ if (type === "helper") {
+ this.helperMustache(mustache, program, inverse);
+ } else if (type === "simple") {
+ this.simpleMustache(mustache);
+
+ // now that the simple mustache is resolved, we need to
+ // evaluate it by executing `blockHelperMissing`
+ this.opcode('pushProgram', program);
+ this.opcode('pushProgram', inverse);
+ this.opcode('emptyHash');
+ this.opcode('blockValue');
+ } else {
+ this.ambiguousMustache(mustache, program, inverse);
+
+ // now that the simple mustache is resolved, we need to
+ // evaluate it by executing `blockHelperMissing`
+ this.opcode('pushProgram', program);
+ this.opcode('pushProgram', inverse);
+ this.opcode('emptyHash');
+ this.opcode('ambiguousBlockValue');
+ }
+
+ this.opcode('append');
+ },
+
+ hash: function(hash) {
+ var pairs = hash.pairs, pair, val;
+
+ this.opcode('pushHash');
+
+ for(var i=0, l=pairs.length; i<l; i++) {
+ pair = pairs[i];
+ val = pair[1];
+
+ if (this.options.stringParams) {
+ if(val.depth) {
+ this.addDepth(val.depth);
+ }
+ this.opcode('getContext', val.depth || 0);
+ this.opcode('pushStringParam', val.stringModeValue, val.type);
+ } else {
+ this.accept(val);
+ }
+
+ this.opcode('assignToHash', pair[0]);
+ }
+ this.opcode('popHash');
+ },
+
+ partial: function(partial) {
+ var partialName = partial.partialName;
+ this.usePartial = true;
+
+ if(partial.context) {
+ this.ID(partial.context);
+ } else {
+ this.opcode('push', 'depth0');
+ }
+
+ this.opcode('invokePartial', partialName.name);
+ this.opcode('append');
+ },
+
+ content: function(content) {
+ this.opcode('appendContent', content.string);
+ },
+
+ mustache: function(mustache) {
+ var options = this.options;
+ var type = this.classifyMustache(mustache);
+
+ if (type === "simple") {
+ this.simpleMustache(mustache);
+ } else if (type === "helper") {
+ this.helperMustache(mustache);
+ } else {
+ this.ambiguousMustache(mustache);
+ }
+
+ if(mustache.escaped && !options.noEscape) {
+ this.opcode('appendEscaped');
+ } else {
+ this.opcode('append');
+ }
+ },
+
+ ambiguousMustache: function(mustache, program, inverse) {
+ var id = mustache.id,
+ name = id.parts[0],
+ isBlock = program != null || inverse != null;
+
+ this.opcode('getContext', id.depth);
+
+ this.opcode('pushProgram', program);
+ this.opcode('pushProgram', inverse);
+
+ this.opcode('invokeAmbiguous', name, isBlock);
+ },
+
+ simpleMustache: function(mustache) {
+ var id = mustache.id;
+
+ if (id.type === 'DATA') {
+ this.DATA(id);
+ } else if (id.parts.length) {
+ this.ID(id);
+ } else {
+ // Simplified ID for `this`
+ this.addDepth(id.depth);
+ this.opcode('getContext', id.depth);
+ this.opcode('pushContext');
+ }
+
+ this.opcode('resolvePossibleLambda');
+ },
+
+ helperMustache: function(mustache, program, inverse) {
+ var params = this.setupFullMustacheParams(mustache, program, inverse),
+ name = mustache.id.parts[0];
+
+ if (this.options.knownHelpers[name]) {
+ this.opcode('invokeKnownHelper', params.length, name);
+ } else if (this.options.knownHelpersOnly) {
+ throw new Error("You specified knownHelpersOnly, but used the unknown helper " + name);
+ } else {
+ this.opcode('invokeHelper', params.length, name);
+ }
+ },
+
+ ID: function(id) {
+ this.addDepth(id.depth);
+ this.opcode('getContext', id.depth);
+
+ var name = id.parts[0];
+ if (!name) {
+ this.opcode('pushContext');
+ } else {
+ this.opcode('lookupOnContext', id.parts[0]);
+ }
+
+ for(var i=1, l=id.parts.length; i<l; i++) {
+ this.opcode('lookup', id.parts[i]);
+ }
+ },
+
+ DATA: function(data) {
+ this.options.data = true;
+ if (data.id.isScoped || data.id.depth) {
+ throw new Exception('Scoped data references are not supported: ' + data.original);
+ }
+
+ this.opcode('lookupData');
+ var parts = data.id.parts;
+ for(var i=0, l=parts.length; i<l; i++) {
+ this.opcode('lookup', parts[i]);
+ }
+ },
+
+ STRING: function(string) {
+ this.opcode('pushString', string.string);
+ },
+
+ INTEGER: function(integer) {
+ this.opcode('pushLiteral', integer.integer);
+ },
+
+ BOOLEAN: function(bool) {
+ this.opcode('pushLiteral', bool.bool);
+ },
+
+ comment: function() {},
+
+ // HELPERS
+ opcode: function(name) {
+ this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
+ },
+
+ declare: function(name, value) {
+ this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
+ },
+
+ addDepth: function(depth) {
+ if(isNaN(depth)) { throw new Error("EWOT"); }
+ if(depth === 0) { return; }
+
+ if(!this.depths[depth]) {
+ this.depths[depth] = true;
+ this.depths.list.push(depth);
+ }
+ },
+
+ classifyMustache: function(mustache) {
+ var isHelper = mustache.isHelper;
+ var isEligible = mustache.eligibleHelper;
+ var options = this.options;
+
+ // if ambiguous, we can possibly resolve the ambiguity now
+ if (isEligible && !isHelper) {
+ var name = mustache.id.parts[0];
+
+ if (options.knownHelpers[name]) {
+ isHelper = true;
+ } else if (options.knownHelpersOnly) {
+ isEligible = false;
+ }
+ }
+
+ if (isHelper) { return "helper"; }
+ else if (isEligible) { return "ambiguous"; }
+ else { return "simple"; }
+ },
+
+ pushParams: function(params) {
+ var i = params.length, param;
+
+ while(i--) {
+ param = params[i];
+
+ if(this.options.stringParams) {
+ if(param.depth) {
+ this.addDepth(param.depth);
+ }
+
+ this.opcode('getContext', param.depth || 0);
+ this.opcode('pushStringParam', param.stringModeValue, param.type);
+ } else {
+ this[param.type](param);
+ }
+ }
+ },
+
+ setupMustacheParams: function(mustache) {
+ var params = mustache.params;
+ this.pushParams(params);
+
+ if(mustache.hash) {
+ this.hash(mustache.hash);
+ } else {
+ this.opcode('emptyHash');
+ }
+
+ return params;
+ },
+
+ // this will replace setupMustacheParams when we're done
+ setupFullMustacheParams: function(mustache, program, inverse) {
+ var params = mustache.params;
+ this.pushParams(params);
+
+ this.opcode('pushProgram', program);
+ this.opcode('pushProgram', inverse);
+
+ if(mustache.hash) {
+ this.hash(mustache.hash);
+ } else {
+ this.opcode('emptyHash');
+ }
+
+ return params;
+ }
+ };
+
+ function precompile(input, options) {
+ if (input == null || (typeof input !== 'string' && input.constructor !== AST.ProgramNode)) {
+ throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
+ }
+
+ options = options || {};
+ if (!('data' in options)) {
+ options.data = true;
+ }
+
+ var ast = parse(input);
+ var environment = new Compiler().compile(ast, options);
+ return new JavaScriptCompiler().compile(environment, options);
+ }
+
+ __exports__.precompile = precompile;function compile(input, options, env) {
+ if (input == null || (typeof input !== 'string' && input.constructor !== AST.ProgramNode)) {
+ throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
+ }
+
+ options = options || {};
+
+ if (!('data' in options)) {
+ options.data = true;
+ }
+
+ var compiled;
+
+ function compileInput() {
+ var ast = parse(input);
+ var environment = new Compiler().compile(ast, options);
+ var templateSpec = new JavaScriptCompiler().compile(environment, options, undefined, true);
+ return env.template(templateSpec);
+ }
+
+ // Template is only compiled on first use and cached after that point.
+ return function(context, options) {
+ if (!compiled) {
+ compiled = compileInput();
+ }
+ return compiled.call(this, context, options);
+ };
+ }
+
+ __exports__.compile = compile;
+ return __exports__;
+})(__module5__, __module8__, __module11__, __module7__);
+
+// handlebars.js
+var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
+ "use strict";
+ var __exports__;
+ var Handlebars = __dependency1__;
+
+ // Compiler imports
+ var AST = __dependency2__;
+ var Parser = __dependency3__.parser;
+ var parse = __dependency3__.parse;
+ var Compiler = __dependency4__.Compiler;
+ var compile = __dependency4__.compile;
+ var precompile = __dependency4__.precompile;
+ var JavaScriptCompiler = __dependency5__;
+
+ var _create = Handlebars.create;
+ var create = function() {
+ var hb = _create();
+
+ hb.compile = function(input, options) {
+ return compile(input, options, hb);
+ };
+ hb.precompile = precompile;
+
+ hb.AST = AST;
+ hb.Compiler = Compiler;
+ hb.JavaScriptCompiler = JavaScriptCompiler;
+ hb.Parser = Parser;
+ hb.parse = parse;
+
+ return hb;
+ };
+
+ Handlebars = create();
+ Handlebars.create = create;
+
+ __exports__ = Handlebars;
+ return __exports__;
+})(__module1__, __module7__, __module8__, __module10__, __module11__);
+
+ return __module0__;
+})();
--- /dev/null
+
+/*
+ * Copyright 2013 Geraint Luff <http://geraintluff.github.io/tv4/>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+define(function() {
+
+ var highlight = {};
+
+ var REGEX = {
+ whitespace: /^([ \r\n\t]| )*/,
+ number: /^-?[0-9]+(\.[0-9]+)?([eE][+\-]?[0-9]+)?/
+ };
+
+ function Highlighter(stringData) {
+ this.remaining = stringData;
+ this.html = "";
+ }
+ Highlighter.prototype = {
+ unshift: function (next) {
+ this.remaining = next + this.remaining;
+ },
+ next: function () {
+ this.whitespace();
+ return this.nextCharacter();
+ },
+ nextCharacter: function () {
+ if (this.remaining.length == 0) {
+ throw new Error("Unexpected end of input");
+ }
+ if (this.remaining[0] == "&") {
+ var endIndex = this.remaining.indexOf(";") + 1;
+ if (endIndex == -1) {
+ endIndex = 1;
+ }
+ var result = this.remaining.substring(0, endIndex);
+ this.remaining = this.remaining.substring(endIndex);
+ return result;
+ }
+ var result = this.remaining[0];
+ this.remaining = this.remaining.substring(1);
+ return result;
+ },
+ whitespace: function () {
+ var ws = this.remaining.match(REGEX.whitespace)[0];
+ this.html += ws;
+ this.remaining = this.remaining.substring(ws.length);
+ },
+ highlightJson: function (keywords) {
+ if (keywords != undefined) {
+ this.html += keywords.wrapper[0];
+ }
+ this.whitespace();
+ var next = this.next();
+ if (next == "{") {
+ this.highlightObject(keywords);
+ } else if (next == '[') {
+ this.highlightArray(keywords);
+ } else if (next == '"' || next == """) {
+ this.highlightString();
+ } else if ((next + this.remaining).match(REGEX.number)) {
+ var numberString = (next + this.remaining).match(REGEX.number)[0];
+ this.html += '<span class="json-number">' + numberString + '</span>';
+ this.remaining = this.remaining.substring(numberString.length - 1);
+ } else if (next == "n" && this.remaining.substring(0, 3) == "ull") {
+ this.remaining = this.remaining.substring(3);
+ this.html += '<span class="json-null">null</span>';
+ } else if (next == "t" && this.remaining.substring(0, 3) == "rue") {
+ this.remaining = this.remaining.substring(3);
+ this.html += '<span class="json-true">true</span>';
+ } else if (next == "f" && this.remaining.substring(0, 4) == "alse") {
+ this.remaining = this.remaining.substring(4);
+ this.html += '<span class="json-false">false</span>';
+ } else {
+ this.html += next;
+ this.highlightJson(keywords);
+ }
+ if (keywords != undefined) {
+ this.html += keywords.wrapper[1];
+ }
+ },
+ highlightObject: function (keywords) {
+ this.html += '<span class="json-punctuation">{</span>';
+ var next = this.next();
+ while (next != "}") {
+ if (next == '"' || next == """) {
+ var keyHtml = "";
+ next = this.next();
+ while (next != '"' && next != '"') {
+ if (next == "\\") {
+ keyHtml += next;
+ next = this.nextCharacter();
+ }
+ keyHtml += next;
+ next = this.next();
+ }
+ if (keywords != undefined && keywords.isKeyword(keyHtml)) {
+ this.html += '<span class="json-keyword">"'
+ + keyHtml
+ + '"</span>';
+ } else {
+ this.html += '<span class="json-object-key">"'
+ + keyHtml
+ + '"</span>';
+ }
+ next = this.next();
+ while (next != ":") {
+ this.html += next;
+ next = this.next();
+ }
+ this.html += '<span class="json-punctuation">:</span>';
+ var nextKeywords = null;
+ if (keywords != undefined) {
+ nextKeywords = keywords.forKey(keyHtml);
+ }
+ this.highlightJson(nextKeywords);
+ next = this.next();
+ if (next == ",") {
+ this.html += '<span class="json-punctuation">,</span>';
+ next = this.next();
+ continue;
+ } else while (next != "}") {
+ this.html += next;
+ next = this.next();
+ }
+ } else {
+ this.html += next;
+ next = this.next();
+ }
+ }
+ this.html += '<span class="json-punctuation">}</span>';
+ },
+ highlightArray: function (keywords) {
+ this.html += '<span class="json-punctuation">[</span>';
+ var next = this.next();
+ var i = 0;
+ while (next != "]") {
+ this.unshift(next);
+ this.highlightJson(keywords != undefined ? keywords.forItem(i) : null);
+ next = this.next();
+ if (next == ",") {
+ this.html += '<span class="json-punctuation">,</span>';
+ next = this.next();
+ i++;
+ continue;
+ } else while (next != "]") {
+ this.html += next;
+ next = this.next();
+ }
+ }
+ this.html += '<span class="json-punctuation">]</span>';
+ },
+ highlightString: function () {
+ this.html += '<span class="json-punctuation">"</span><span class="json-string">';
+ next = this.next();
+ while (next != '"' && next != '"') {
+ if (next == "\\") {
+ this.html += next;
+ next = this.nextCharacter();
+ }
+ this.html += next;
+ next = this.next();
+ }
+ this.html += '</span><span class="json-punctuation">"</span>';
+ }
+ };
+
+ function KeywordMap() {
+ }
+ KeywordMap.prototype = {
+ wrapper: ["<span>", "</span>"],
+ keywords: {},
+ isKeyword: function (keyHtml) {
+ return this.keywords[keyHtml] !== undefined;
+ },
+ forKey: function (keyHtml) {
+ return this.keywords[keyHtml];
+ },
+ forItem: function (keyHtml) {
+ return null;
+ }
+ };
+ var schema = new KeywordMap();
+ var schemaMedia = new KeywordMap();
+ var mapToSchemas = new KeywordMap();
+ var links = new KeywordMap();
+ schema.keywords = {
+ // from v3
+ type: null,
+ properties: mapToSchemas,
+ patternProperties: mapToSchemas,
+ additionalProperties: schema,
+ items: schema,
+ additionalItems: schema,
+ required: null,
+ dependencies: mapToSchemas,
+ minimum: null,
+ maximum: null,
+ exclusiveMinimum: null,
+ exclusiveMaximum: null,
+ minItems: null,
+ maxItems: null,
+ uniqueItems: null,
+ pattern: null,
+ minLength: null,
+ maxLength: null,
+ "enum": null,
+ "default": null,
+ title: null,
+ description: null,
+ format: null,
+ divisibleBy: null,
+ disallow: schema,
+ "extends": schema,
+ "id": null,
+ "$ref": null,
+ "$schema": null,
+ // from v4 core
+ multipleOf: null,
+ maxProperties: null,
+ minProperties: null,
+ allOf: schema,
+ anyOf: schema,
+ oneOf: schema,
+ not: schema,
+ definitions: mapToSchemas,
+ // from v4 hyper-schema
+ media: schemaMedia,
+ links: links,
+ pathStart: null,
+ fragmentResolution: null
+ };
+ schema.forItem = function () {
+ return schema;
+ };
+ schemaMedia.keywords = {
+ binaryEncoding: null,
+ type: null
+ };
+ mapToSchemas.wrapper = ['<span class="json-schema-map">', '</span>'];
+ mapToSchemas.forKey = function () {
+ return schema;
+ };
+ links.keywords = {
+ rel: null,
+ href:null,
+ method: null,
+ encType: null,
+ pathStart: null,
+ schema: schema,
+ targetSchema: schema
+ };
+ links.forItem = function () {
+ return links;
+ };
+
+ function highlightElement(element, keywords) {
+ var highlighter = new Highlighter(element.innerHTML);
+ try {
+ highlighter.highlightJson(keywords);
+ } catch (e) {
+ throw e;
+ }
+ element.innerHTML = highlighter.html + highlighter.remaining;
+ }
+
+ if (document.getElementsByClassName == undefined) {
+ document.getElementsByClassName = function(className)
+ {
+ var hasClassName = new RegExp("(?:^|\\s)" + className + "(?:$|\\s)");
+ var allElements = document.getElementsByTagName("*");
+ var results = [];
+
+ var element;
+ for (var i = 0; (element = allElements[i]) != null; i++) {
+ var elementClass = element.className;
+ if (elementClass && elementClass.indexOf(className) != -1 && hasClassName.test(elementClass))
+ results.push(element);
+ }
+
+ return results;
+ }
+ }
+
+ highlight.highlightSchema = function(element) {
+ highlightElement(element, schema);
+ }
+
+ return highlight;
+});
--- /dev/null
+/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
+//@ sourceMappingURL=jquery-1.10.2.min.map
+*/
+(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.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%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t
+}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle);
+u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
--- /dev/null
+/**
+ * @author Alexey Kuzmin <alex.s.kuzmin@gmail.com>
+ * @fileoverview JavaScript implementation of JSON Pointer.
+ * @see http://tools.ietf.org/html/rfc6901
+ */
+
+
+
+;(function() {
+ 'use strict';
+
+ /**
+ * List of special characters and their escape sequences.
+ * Special characters will be unescaped in order they are listed.
+ * Section 3 of spec.
+ * @type {Array.<Array.<string>>}
+ * @const
+ */
+ var SPECIAL_CHARACTERS = [
+ ['/', '~1'],
+ ['~', '~0']
+ ];
+
+
+ /**
+ * Tokens' separator in JSON pointer string.
+ * Section 3 of spec.
+ * @type {string}
+ * @const
+ */
+ var TOKENS_SEPARATOR = '/';
+
+
+ /**
+ * Prefix for error messages.
+ * @type {string}
+ * @const
+ */
+ var ERROR_MESSAGE_PREFIX = 'JSON Pointer: ';
+
+
+ /**
+ * Validates non-empty pointer string.
+ * @type {RegExp}
+ * @const
+ */
+ var NON_EMPTY_POINTER_REGEXP = /(\/[^\/]*)+/;
+
+
+ /**
+ * List of error messages.
+ * Please keep it in alphabetical order.
+ * @enum {string}
+ */
+ var ErrorMessage = {
+ HYPHEN_IS_NOT_SUPPORTED_IN_ARRAY_CONTEXT:
+ 'Implementation does not support "-" token for arrays.',
+ INVALID_DOCUMENT: 'JSON document is not valid.',
+ INVALID_DOCUMENT_TYPE: 'JSON document must be a string or object.',
+ INVALID_POINTER: 'Pointer is not valid.',
+ NON_NUMBER_TOKEN_IN_ARRAY_CONTEXT:
+ 'Non-number tokens cannot be used in array context.',
+ TOKEN_WITH_LEADING_ZERO_IN_ARRAY_CONTEXT:
+ 'Token with leading zero cannot be used in array context.'
+ };
+
+
+ /**
+ * Returns |target| object's value pointed by |opt_pointer|, returns undefined
+ * if |opt_pointer| points to non-existing value.
+ * If pointer is not provided, validates first argument and returns
+ * evaluator function that takes pointer as argument.
+ * @param {(string|Object|Array)} target Evaluation target.
+ * @param {string=} opt_pointer JSON Pointer string.
+ * @returns {*} Some value.
+ */
+ function getPointedValue(target, opt_pointer) {
+ // .get() method implementation.
+
+ // First argument must be either string or object.
+ if (isString(target)) {
+
+ // If string it must be valid JSON document.
+ try {
+ // Let's try to parse it as JSON.
+ target = JSON.parse(target);
+ }
+ catch (e) {
+ // If parsing failed, an exception will be thrown.
+ throw getError(ErrorMessage.INVALID_DOCUMENT);
+ }
+ }
+ else if (!isObject(target)) {
+ // If not object or string, an exception will be thrown.
+ throw getError(ErrorMessage.INVALID_DOCUMENT_TYPE);
+ }
+
+ // |target| is already parsed, let's create evaluator function for it.
+ var evaluator = createPointerEvaluator(target);
+
+ if (isUndefined(opt_pointer)) {
+ // If pointer was not provided, return evaluator function.
+ return evaluator;
+ }
+ else {
+ // If pointer is provided, return evaluation result.
+ return evaluator(opt_pointer);
+ }
+ }
+
+
+ /**
+ * Returns function that takes JSON Pointer as single argument
+ * and evaluates it in given |target| context.
+ * Returned function throws an exception if pointer is not valid
+ * or any error occurs during evaluation.
+ * @param {*} target Evaluation target.
+ * @returns {Function}
+ */
+ function createPointerEvaluator(target) {
+
+ // Use cache to store already received values.
+ var cache = {};
+
+ return function(pointer) {
+
+ if (!isValidJSONPointer(pointer)) {
+ // If it's not, an exception will be thrown.
+ throw getError(ErrorMessage.INVALID_POINTER);
+ }
+
+ // First, look up in the cache.
+ if (cache.hasOwnProperty(pointer)) {
+ // If cache entry exists, return it's value.
+ return cache[pointer];
+ }
+
+ // Now, when all arguments are valid, we can start evaluation.
+ // First of all, let's convert JSON pointer string to tokens list.
+ var tokensList = parsePointer(pointer);
+ var token;
+ var value = target;
+
+ // Evaluation will be continued till tokens list is not empty
+ // and returned value is not an undefined.
+ while (!isUndefined(value) && !isUndefined(token = tokensList.pop())) {
+ // Let's evaluate token in current context.
+ // `getValue()` might throw an exception, but we won't handle it.
+ value = getValue(value, token);
+ }
+
+ // Pointer evaluation is done, save value in the cache and return it.
+ cache[pointer] = value;
+ return value;
+ };
+ }
+
+
+ /**
+ * Returns true if given |pointer| is valid, returns false otherwise.
+ * @param {!string} pointer
+ * @returns {boolean} Whether pointer is valid.
+ */
+ function isValidJSONPointer(pointer) {
+ // Validates JSON pointer string.
+
+ if (!isString(pointer)) {
+ // If it's not a string, it obviously is not valid.
+ return false;
+ }
+
+ if ('' === pointer) {
+ // If it is string and is an empty string, it's valid.
+ return true;
+ }
+
+ // If it is non-empty string, it must match spec defined format.
+ // Check Section 3 of specification for concrete syntax.
+ return NON_EMPTY_POINTER_REGEXP.test(pointer);
+ }
+
+
+ /**
+ * Returns tokens list for given |pointer|. List is reversed, e.g.
+ * '/simple/path' -> ['path', 'simple']
+ * @param {!string} pointer JSON pointer string.
+ * @returns {Array} List of tokens.
+ */
+ function parsePointer(pointer) {
+ // Converts JSON pointer string into tokens list.
+
+ // Let's split pointer string by tokens' separator character.
+ // Also we will reverse resulting array to simplify it's further usage.
+ var tokens = pointer.split(TOKENS_SEPARATOR).reverse();
+
+ // Last item in resulting array is always an empty string,
+ // we don't need it, let's remove it.
+ tokens.pop();
+
+ // Now tokens' array is ready to use, let's return it.
+ return tokens;
+ }
+
+
+ /**
+ * Decodes all escape sequences in given |rawReferenceToken|.
+ * @param {!string} rawReferenceToken
+ * @returns {string} Unescaped reference token.
+ */
+ function unescapeReferenceToken(rawReferenceToken) {
+ // Unescapes reference token. See Section 3 of specification.
+
+ var referenceToken = rawReferenceToken;
+ var character;
+ var escapeSequence;
+ var replaceRegExp;
+
+ // Order of unescaping does matter.
+ // That's why an array is used here and not hash.
+ SPECIAL_CHARACTERS.forEach(function(pair) {
+ character = pair[0];
+ escapeSequence = pair[1];
+ replaceRegExp = new RegExp(escapeSequence, 'g');
+ referenceToken = referenceToken.replace(replaceRegExp, character);
+ });
+
+ return referenceToken;
+ }
+
+
+ /**
+ * Returns value pointed by |token| in evaluation |context|.
+ * Throws an exception if any error occurs.
+ * @param {*} context Current evaluation context.
+ * @param {!string} token Unescaped reference token.
+ * @returns {*} Some value or undefined if value if not found.
+ */
+ function getValue(context, token) {
+ // Reference token evaluation. See Section 4 of spec.
+
+ // First of all we should unescape all special characters in token.
+ token = unescapeReferenceToken(token);
+
+ // Further actions depend of context of evaluation.
+
+ if (isArray(context)) {
+ // In array context there are more strict requirements
+ // for token value.
+
+ if ('-' === token) {
+ // Token cannot be a "-" character,
+ // it has no sense in current implementation.
+ throw getError(ErrorMessage.HYPHEN_IS_NOT_SUPPORTED_IN_ARRAY_CONTEXT);
+ }
+ if (!isNumber(token)) {
+ // Token cannot be non-number.
+ throw getError(ErrorMessage.NON_NUMBER_TOKEN_IN_ARRAY_CONTEXT);
+ }
+ if (token.length > 1 && '0' === token[0]) {
+ // Token cannot be non-zero number with leading zero.
+ throw getError(ErrorMessage.TOKEN_WITH_LEADING_ZERO_IN_ARRAY_CONTEXT);
+ }
+ // If all conditions are met, simply return element
+ // with token's value index.
+ // It might be undefined, but it's ok.
+ return context[token];
+ }
+
+ if (isObject(context)) {
+ // In object context we can simply return element w/ key equal to token.
+ // It might be undefined, but it's ok.
+ return context[token];
+ }
+
+ // If context is not an array or an object,
+ // token evaluation is not possible.
+ // This is the expected situation and so we won't throw an error,
+ // undefined value is perfectly suitable here.
+ return;
+ }
+
+
+ /**
+ * Returns Error instance for throwing.
+ * @param {string} message Error message.
+ * @returns {Error}
+ */
+ function getError(message) {
+ return new Error(ERROR_MESSAGE_PREFIX + message);
+ }
+
+
+ function isObject(o) {
+ return 'object' === typeof o && null !== o;
+ }
+
+
+ function isArray(a) {
+ return Array.isArray(a);
+ }
+
+
+ function isNumber(n) {
+ return !isNaN(Number(n));
+ }
+
+
+ function isString(s) {
+ return 'string' === typeof s || s instanceof String;
+ }
+
+
+ function isUndefined(v) {
+ return 'undefined' === typeof v;
+ }
+
+
+ // Let's expose API to the world.
+
+ var jsonpointer = {
+ get: getPointedValue
+ };
+
+ if ('object' === typeof exports) {
+ // If `exports` is an object, we are in Node.js context.
+ // We are supposed to act as Node.js package.
+ module.exports = jsonpointer;
+ } else if ('function' === typeof define && define.amd) {
+ // If there is global function `define()` and `define.amd` is defined,
+ // we are supposed to act as AMD module.
+ define(function() {
+ return jsonpointer;
+ });
+ } else {
+ // Last resort.
+ // Let's create global `jsonpointer` object.
+ this.jsonpointer = jsonpointer;
+ }
+
+}).call((function() {
+ 'use strict';
+ return (typeof window !== 'undefined' ? window : global);
+})());
--- /dev/null
+/*
+ * Copyright 2013 Laurent Bovet <laurent.bovet@windmaster.ch>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+;(function() {
+
+ /**
+ * Block-Level Grammar
+ */
+
+ var block = {
+ newline: /^\n+/,
+ code: /^( {4}[^\n]+\n*)+/,
+ fences: noop,
+ hr: /^( *[-*_]){3,} *(?:\n+|$)/,
+ heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
+ nptable: noop,
+ lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
+ blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/,
+ list: /^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
+ html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,
+ def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
+ table: noop,
+ paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+ text: /^[^\n]+/
+ };
+
+ block.bullet = /(?:[*+-]|\d+\.)/;
+ block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
+ block.item = replace(block.item, 'gm')
+ (/bull/g, block.bullet)
+ ();
+
+ block.list = replace(block.list)
+ (/bull/g, block.bullet)
+ ('hr', /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)
+ ();
+
+ block._tag = '(?!(?:'
+ + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
+ + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
+ + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b';
+
+ block.html = replace(block.html)
+ ('comment', /<!--[\s\S]*?-->/)
+ ('closed', /<(tag)[\s\S]+?<\/\1>/)
+ ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
+ (/tag/g, block._tag)
+ ();
+
+ block.paragraph = replace(block.paragraph)
+ ('hr', block.hr)
+ ('heading', block.heading)
+ ('lheading', block.lheading)
+ ('blockquote', block.blockquote)
+ ('tag', '<' + block._tag)
+ ('def', block.def)
+ ();
+
+ /**
+ * Normal Block Grammar
+ */
+
+ block.normal = merge({}, block);
+
+ /**
+ * GFM Block Grammar
+ */
+
+ block.gfm = merge({}, block.normal, {
+ fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
+ paragraph: /^/
+ });
+
+ block.gfm.paragraph = replace(block.paragraph)
+ ('(?!', '(?!'
+ + block.gfm.fences.source.replace('\\1', '\\2') + '|'
+ + block.list.source.replace('\\1', '\\3') + '|')
+ ();
+
+ /**
+ * GFM + Tables Block Grammar
+ */
+
+ block.tables = merge({}, block.gfm, {
+ nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
+ table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
+ });
+
+ /**
+ * Block Lexer
+ */
+
+ function Lexer(options) {
+ this.tokens = [];
+ this.tokens.links = {};
+ this.options = options || marked.defaults;
+ this.rules = block.normal;
+
+ if (this.options.gfm) {
+ if (this.options.tables) {
+ this.rules = block.tables;
+ } else {
+ this.rules = block.gfm;
+ }
+ }
+ }
+
+ /**
+ * Expose Block Rules
+ */
+
+ Lexer.rules = block;
+
+ /**
+ * Static Lex Method
+ */
+
+ Lexer.lex = function(src, options) {
+ var lexer = new Lexer(options);
+ return lexer.lex(src);
+ };
+
+ /**
+ * Preprocessing
+ */
+
+ Lexer.prototype.lex = function(src) {
+ src = src
+ .replace(/\r\n|\r/g, '\n')
+ .replace(/\t/g, ' ')
+ .replace(/\u00a0/g, ' ')
+ .replace(/\u2424/g, '\n');
+
+ return this.token(src, true);
+ };
+
+ /**
+ * Lexing
+ */
+
+ Lexer.prototype.token = function(src, top) {
+ var src = src.replace(/^ +$/gm, '')
+ , next
+ , loose
+ , cap
+ , bull
+ , b
+ , item
+ , space
+ , i
+ , l;
+
+ while (src) {
+ // newline
+ if (cap = this.rules.newline.exec(src)) {
+ src = src.substring(cap[0].length);
+ if (cap[0].length > 1) {
+ this.tokens.push({
+ type: 'space'
+ });
+ }
+ }
+
+ // code
+ if (cap = this.rules.code.exec(src)) {
+ src = src.substring(cap[0].length);
+ cap = cap[0].replace(/^ {4}/gm, '');
+ this.tokens.push({
+ type: 'code',
+ text: !this.options.pedantic
+ ? cap.replace(/\n+$/, '')
+ : cap
+ });
+ continue;
+ }
+
+ // fences (gfm)
+ if (cap = this.rules.fences.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'code',
+ lang: cap[2],
+ text: cap[3]
+ });
+ continue;
+ }
+
+ // heading
+ if (cap = this.rules.heading.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'heading',
+ depth: cap[1].length,
+ text: cap[2]
+ });
+ continue;
+ }
+
+ // table no leading pipe (gfm)
+ if (top && (cap = this.rules.nptable.exec(src))) {
+ src = src.substring(cap[0].length);
+
+ item = {
+ type: 'table',
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+ cells: cap[3].replace(/\n$/, '').split('\n')
+ };
+
+ for (i = 0; i < item.align.length; i++) {
+ if (/^ *-+: *$/.test(item.align[i])) {
+ item.align[i] = 'right';
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
+ item.align[i] = 'center';
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
+ item.align[i] = 'left';
+ } else {
+ item.align[i] = null;
+ }
+ }
+
+ for (i = 0; i < item.cells.length; i++) {
+ item.cells[i] = item.cells[i].split(/ *\| */);
+ }
+
+ this.tokens.push(item);
+
+ continue;
+ }
+
+ // lheading
+ if (cap = this.rules.lheading.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'heading',
+ depth: cap[2] === '=' ? 1 : 2,
+ text: cap[1]
+ });
+ continue;
+ }
+
+ // hr
+ if (cap = this.rules.hr.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'hr'
+ });
+ continue;
+ }
+
+ // blockquote
+ if (cap = this.rules.blockquote.exec(src)) {
+ src = src.substring(cap[0].length);
+
+ this.tokens.push({
+ type: 'blockquote_start'
+ });
+
+ cap = cap[0].replace(/^ *> ?/gm, '');
+
+ // Pass `top` to keep the current
+ // "toplevel" state. This is exactly
+ // how markdown.pl works.
+ this.token(cap, top);
+
+ this.tokens.push({
+ type: 'blockquote_end'
+ });
+
+ continue;
+ }
+
+ // list
+ if (cap = this.rules.list.exec(src)) {
+ src = src.substring(cap[0].length);
+ bull = cap[2];
+
+ this.tokens.push({
+ type: 'list_start',
+ ordered: bull.length > 1
+ });
+
+ // Get each top-level item.
+ cap = cap[0].match(this.rules.item);
+
+ next = false;
+ l = cap.length;
+ i = 0;
+
+ for (; i < l; i++) {
+ item = cap[i];
+
+ // Remove the list item's bullet
+ // so it is seen as the next token.
+ space = item.length;
+ item = item.replace(/^ *([*+-]|\d+\.) +/, '');
+
+ // Outdent whatever the
+ // list item contains. Hacky.
+ if (~item.indexOf('\n ')) {
+ space -= item.length;
+ item = !this.options.pedantic
+ ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
+ : item.replace(/^ {1,4}/gm, '');
+ }
+
+ // Determine whether the next list item belongs here.
+ // Backpedal if it does not belong in this list.
+ if (this.options.smartLists && i !== l - 1) {
+ b = block.bullet.exec(cap[i + 1])[0];
+ if (bull !== b && !(bull.length > 1 && b.length > 1)) {
+ src = cap.slice(i + 1).join('\n') + src;
+ i = l - 1;
+ }
+ }
+
+ // Determine whether item is loose or not.
+ // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
+ // for discount behavior.
+ loose = next || /\n\n(?!\s*$)/.test(item);
+ if (i !== l - 1) {
+ next = item.charAt(item.length - 1) === '\n';
+ if (!loose) loose = next;
+ }
+
+ this.tokens.push({
+ type: loose
+ ? 'loose_item_start'
+ : 'list_item_start'
+ });
+
+ // Recurse.
+ this.token(item, false);
+
+ this.tokens.push({
+ type: 'list_item_end'
+ });
+ }
+
+ this.tokens.push({
+ type: 'list_end'
+ });
+
+ continue;
+ }
+
+ // html
+ if (cap = this.rules.html.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: this.options.sanitize
+ ? 'paragraph'
+ : 'html',
+ pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
+ text: cap[0]
+ });
+ continue;
+ }
+
+ // def
+ if (top && (cap = this.rules.def.exec(src))) {
+ src = src.substring(cap[0].length);
+ this.tokens.links[cap[1].toLowerCase()] = {
+ href: cap[2],
+ title: cap[3]
+ };
+ continue;
+ }
+
+ // table (gfm)
+ if (top && (cap = this.rules.table.exec(src))) {
+ src = src.substring(cap[0].length);
+
+ item = {
+ type: 'table',
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+ cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
+ };
+
+ for (i = 0; i < item.align.length; i++) {
+ if (/^ *-+: *$/.test(item.align[i])) {
+ item.align[i] = 'right';
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
+ item.align[i] = 'center';
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
+ item.align[i] = 'left';
+ } else {
+ item.align[i] = null;
+ }
+ }
+
+ for (i = 0; i < item.cells.length; i++) {
+ item.cells[i] = item.cells[i]
+ .replace(/^ *\| *| *\| *$/g, '')
+ .split(/ *\| */);
+ }
+
+ this.tokens.push(item);
+
+ continue;
+ }
+
+ // top-level paragraph
+ if (top && (cap = this.rules.paragraph.exec(src))) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'paragraph',
+ text: cap[1].charAt(cap[1].length - 1) === '\n'
+ ? cap[1].slice(0, -1)
+ : cap[1]
+ });
+ continue;
+ }
+
+ // text
+ if (cap = this.rules.text.exec(src)) {
+ // Top-level should never reach here.
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'text',
+ text: cap[0]
+ });
+ continue;
+ }
+
+ if (src) {
+ throw new
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
+ }
+ }
+
+ return this.tokens;
+ };
+
+ /**
+ * Inline-Level Grammar
+ */
+
+ var inline = {
+ escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
+ autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
+ url: noop,
+ tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
+ link: /^!?\[(inside)\]\(href\)/,
+ reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
+ nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
+ strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
+ em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+ code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
+ br: /^ {2,}\n(?!\s*$)/,
+ del: noop,
+ text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
+ };
+
+ inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
+ inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
+
+ inline.link = replace(inline.link)
+ ('inside', inline._inside)
+ ('href', inline._href)
+ ();
+
+ inline.reflink = replace(inline.reflink)
+ ('inside', inline._inside)
+ ();
+
+ /**
+ * Normal Inline Grammar
+ */
+
+ inline.normal = merge({}, inline);
+
+ /**
+ * Pedantic Inline Grammar
+ */
+
+ inline.pedantic = merge({}, inline.normal, {
+ strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+ em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
+ });
+
+ /**
+ * GFM Inline Grammar
+ */
+
+ inline.gfm = merge({}, inline.normal, {
+ escape: replace(inline.escape)('])', '~|])')(),
+ url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
+ del: /^~~(?=\S)([\s\S]*?\S)~~/,
+ text: replace(inline.text)
+ (']|', '~]|')
+ ('|', '|https?://|')
+ ()
+ });
+
+ /**
+ * GFM + Line Breaks Inline Grammar
+ */
+
+ inline.breaks = merge({}, inline.gfm, {
+ br: replace(inline.br)('{2,}', '*')(),
+ text: replace(inline.gfm.text)('{2,}', '*')()
+ });
+
+ /**
+ * Inline Lexer & Compiler
+ */
+
+ function InlineLexer(links, options) {
+ this.options = options || marked.defaults;
+ this.links = links;
+ this.rules = inline.normal;
+ this.renderer = this.options.renderer || new Renderer;
+
+ if (!this.links) {
+ throw new
+ Error('Tokens array requires a `links` property.');
+ }
+
+ if (this.options.gfm) {
+ if (this.options.breaks) {
+ this.rules = inline.breaks;
+ } else {
+ this.rules = inline.gfm;
+ }
+ } else if (this.options.pedantic) {
+ this.rules = inline.pedantic;
+ }
+ }
+
+ /**
+ * Expose Inline Rules
+ */
+
+ InlineLexer.rules = inline;
+
+ /**
+ * Static Lexing/Compiling Method
+ */
+
+ InlineLexer.output = function(src, links, options) {
+ var inline = new InlineLexer(links, options);
+ return inline.output(src);
+ };
+
+ /**
+ * Lexing/Compiling
+ */
+
+ InlineLexer.prototype.output = function(src) {
+ var out = ''
+ , link
+ , text
+ , href
+ , cap;
+
+ while (src) {
+ // escape
+ if (cap = this.rules.escape.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += cap[1];
+ continue;
+ }
+
+ // autolink
+ if (cap = this.rules.autolink.exec(src)) {
+ src = src.substring(cap[0].length);
+ if (cap[2] === '@') {
+ text = cap[1].charAt(6) === ':'
+ ? this.mangle(cap[1].substring(7))
+ : this.mangle(cap[1]);
+ href = this.mangle('mailto:') + text;
+ } else {
+ text = escape(cap[1]);
+ href = text;
+ }
+ out += this.renderer.link(href, null, text);
+ continue;
+ }
+
+ // url (gfm)
+ if (cap = this.rules.url.exec(src)) {
+ src = src.substring(cap[0].length);
+ text = escape(cap[1]);
+ href = text;
+ out += this.renderer.link(href, null, text);
+ continue;
+ }
+
+ // tag
+ if (cap = this.rules.tag.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.options.sanitize
+ ? escape(cap[0])
+ : cap[0];
+ continue;
+ }
+
+ // link
+ if (cap = this.rules.link.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.outputLink(cap, {
+ href: cap[2],
+ title: cap[3]
+ });
+ continue;
+ }
+
+ // reflink, nolink
+ if ((cap = this.rules.reflink.exec(src))
+ || (cap = this.rules.nolink.exec(src))) {
+ src = src.substring(cap[0].length);
+ link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
+ link = this.links[link.toLowerCase()];
+ if (!link || !link.href) {
+ out += cap[0].charAt(0);
+ src = cap[0].substring(1) + src;
+ continue;
+ }
+ out += this.outputLink(cap, link);
+ continue;
+ }
+
+ // strong
+ if (cap = this.rules.strong.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.strong(this.output(cap[2] || cap[1]));
+ continue;
+ }
+
+ // em
+ if (cap = this.rules.em.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.em(this.output(cap[2] || cap[1]));
+ continue;
+ }
+
+ // code
+ if (cap = this.rules.code.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.codespan(escape(cap[2], true));
+ continue;
+ }
+
+ // br
+ if (cap = this.rules.br.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.br();
+ continue;
+ }
+
+ // del (gfm)
+ if (cap = this.rules.del.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.del(this.output(cap[1]));
+ continue;
+ }
+
+ // text
+ if (cap = this.rules.text.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += escape(this.smartypants(cap[0]));
+ continue;
+ }
+
+ if (src) {
+ throw new
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
+ }
+ }
+
+ return out;
+ };
+
+ /**
+ * Compile Link
+ */
+
+ InlineLexer.prototype.outputLink = function(cap, link) {
+ var href = escape(link.href)
+ , title = link.title ? escape(link.title) : null;
+
+ if (cap[0].charAt(0) !== '!') {
+ return this.renderer.link(href, title, this.output(cap[1]));
+ } else {
+ return this.renderer.image(href, title, escape(cap[1]));
+ }
+ };
+
+ /**
+ * Smartypants Transformations
+ */
+
+ InlineLexer.prototype.smartypants = function(text) {
+ if (!this.options.smartypants) return text;
+ return text
+ // em-dashes
+ .replace(/--/g, '\u2014')
+ // opening singles
+ .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
+ // closing singles & apostrophes
+ .replace(/'/g, '\u2019')
+ // opening doubles
+ .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
+ // closing doubles
+ .replace(/"/g, '\u201d')
+ // ellipses
+ .replace(/\.{3}/g, '\u2026');
+ };
+
+ /**
+ * Mangle Links
+ */
+
+ InlineLexer.prototype.mangle = function(text) {
+ var out = ''
+ , l = text.length
+ , i = 0
+ , ch;
+
+ for (; i < l; i++) {
+ ch = text.charCodeAt(i);
+ if (Math.random() > 0.5) {
+ ch = 'x' + ch.toString(16);
+ }
+ out += '&#' + ch + ';';
+ }
+
+ return out;
+ };
+
+ /**
+ * Renderer
+ */
+
+ function Renderer() {}
+
+ Renderer.prototype.code = function(code, lang) {
+ if (!lang) {
+ return '<pre><code>'
+ + escape(code, true)
+ + '\n</code></pre>';
+ }
+
+ return '<pre><code class="'
+ + 'lang-'
+ + lang
+ + '">'
+ + escape(code)
+ + '\n</code></pre>\n';
+ };
+
+ Renderer.prototype.blockquote = function(quote) {
+ return '<blockquote>\n' + quote + '</blockquote>\n';
+ };
+
+ Renderer.prototype.html = function(html) {
+ return html;
+ };
+
+ Renderer.prototype.heading = function(text, level, raw, options) {
+ return '<h'
+ + level
+ + '>'
+ + text
+ + '</h'
+ + level
+ + '>\n';
+ };
+
+ Renderer.prototype.hr = function() {
+ return '<hr>\n';
+ };
+
+ Renderer.prototype.list = function(body, ordered) {
+ var type = ordered ? 'ol' : 'ul';
+ return '<' + type + '>\n' + body + '</' + type + '>\n';
+ };
+
+ Renderer.prototype.listitem = function(text) {
+ return '<li>' + text + '</li>\n';
+ };
+
+ Renderer.prototype.paragraph = function(text) {
+ return '<p>' + text + '</p>\n';
+ };
+
+ Renderer.prototype.table = function(header, body) {
+ return '<table>\n'
+ + '<thead>\n'
+ + header
+ + '</thead>\n'
+ + '<tbody>\n'
+ + body
+ + '</tbody>\n'
+ + '</table>\n';
+ };
+
+ Renderer.prototype.tablerow = function(content) {
+ return '<tr>\n' + content + '</tr>\n';
+ };
+
+ Renderer.prototype.tablecell = function(content, flags) {
+ var type = flags.header ? 'th' : 'td';
+ var tag = flags.align
+ ? '<' + type + ' style="text-align:' + flags.align + '">'
+ : '<' + type + '>';
+ return tag + content + '</' + type + '>\n';
+ };
+
+// span level renderer
+ Renderer.prototype.strong = function(text) {
+ return '<strong>' + text + '</strong>';
+ };
+
+ Renderer.prototype.em = function(text) {
+ return '<em>' + text + '</em>';
+ };
+
+ Renderer.prototype.codespan = function(text) {
+ return '<code>' + text + '</code>';
+ };
+
+ Renderer.prototype.br = function() {
+ return '<br>';
+ };
+
+ Renderer.prototype.del = function(text) {
+ return '<del>' + text + '</del>';
+ };
+
+ Renderer.prototype.link = function(href, title, text) {
+ var out = '<a href="' + href + '"';
+ if (title) {
+ out += ' title="' + title + '"';
+ }
+ out += '>' + text + '</a>';
+ return out;
+ };
+
+ Renderer.prototype.image = function(href, title, text) {
+ var out = '<img src="' + href + '" alt="' + text + '"';
+ if (title) {
+ out += ' title="' + title + '"';
+ }
+ out += '>';
+ return out;
+ };
+
+ /**
+ * Parsing & Compiling
+ */
+
+ function Parser(options) {
+ this.tokens = [];
+ this.token = null;
+ this.options = options || marked.defaults;
+ this.options.renderer = this.options.renderer || new Renderer;
+ this.renderer = this.options.renderer;
+ }
+
+ /**
+ * Static Parse Method
+ */
+
+ Parser.parse = function(src, options, renderer) {
+ var parser = new Parser(options, renderer);
+ return parser.parse(src);
+ };
+
+ /**
+ * Parse Loop
+ */
+
+ Parser.prototype.parse = function(src) {
+ this.inline = new InlineLexer(src.links, this.options, this.renderer);
+ this.tokens = src.reverse();
+
+ var out = '';
+ while (this.next()) {
+ out += this.tok();
+ }
+
+ return out;
+ };
+
+ /**
+ * Next Token
+ */
+
+ Parser.prototype.next = function() {
+ return this.token = this.tokens.pop();
+ };
+
+ /**
+ * Preview Next Token
+ */
+
+ Parser.prototype.peek = function() {
+ return this.tokens[this.tokens.length - 1] || 0;
+ };
+
+ /**
+ * Parse Text Tokens
+ */
+
+ Parser.prototype.parseText = function() {
+ var body = this.token.text;
+
+ while (this.peek().type === 'text') {
+ body += '\n' + this.next().text;
+ }
+
+ return this.inline.output(body);
+ };
+
+ /**
+ * Parse Current Token
+ */
+
+ Parser.prototype.tok = function() {
+ switch (this.token.type) {
+ case 'space': {
+ return '';
+ }
+ case 'hr': {
+ return this.renderer.hr();
+ }
+ case 'heading': {
+ return this.renderer.heading(
+ this.inline.output(this.token.text),
+ this.token.depth
+ );
+ }
+ case 'code': {
+ return this.renderer.code(this.token.text, this.token.lang);
+ }
+ case 'table': {
+ var header = ''
+ , body = ''
+ , i
+ , row
+ , cell
+ , flags
+ , j;
+
+ // header
+ cell = '';
+ for (i = 0; i < this.token.header.length; i++) {
+ flags = { header: true, align: this.token.align[i] };
+ cell += this.renderer.tablecell(
+ this.inline.output(this.token.header[i]),
+ { header: true, align: this.token.align[i] }
+ );
+ }
+ header += this.renderer.tablerow(cell);
+
+ for (i = 0; i < this.token.cells.length; i++) {
+ row = this.token.cells[i];
+
+ cell = '';
+ for (j = 0; j < row.length; j++) {
+ cell += this.renderer.tablecell(
+ this.inline.output(row[j]),
+ { header: false, align: this.token.align[j] }
+ );
+ }
+
+ body += this.renderer.tablerow(cell);
+ }
+ return this.renderer.table(header, body);
+ }
+ case 'blockquote_start': {
+ var body = '';
+
+ while (this.next().type !== 'blockquote_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.blockquote(body);
+ }
+ case 'list_start': {
+ var body = ''
+ , ordered = this.token.ordered;
+
+ while (this.next().type !== 'list_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.list(body, ordered);
+ }
+ case 'list_item_start': {
+ var body = '';
+
+ while (this.next().type !== 'list_item_end') {
+ body += this.token.type === 'text'
+ ? this.parseText()
+ : this.tok();
+ }
+
+ return this.renderer.listitem(body);
+ }
+ case 'loose_item_start': {
+ var body = '';
+
+ while (this.next().type !== 'list_item_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.listitem(body);
+ }
+ case 'html': {
+ var html = !this.token.pre && !this.options.pedantic
+ ? this.inline.output(this.token.text)
+ : this.token.text;
+ return this.renderer.html(html);
+ }
+ case 'paragraph': {
+ return this.renderer.paragraph(this.inline.output(this.token.text));
+ }
+ case 'text': {
+ return this.renderer.paragraph(this.parseText());
+ }
+ }
+ };
+
+ /**
+ * Helpers
+ */
+
+ function escape(html, encode) {
+ return html
+ .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+ }
+
+ function replace(regex, opt) {
+ regex = regex.source;
+ opt = opt || '';
+ return function self(name, val) {
+ if (!name) return new RegExp(regex, opt);
+ val = val.source || val;
+ val = val.replace(/(^|[^\[])\^/g, '$1');
+ regex = regex.replace(name, val);
+ return self;
+ };
+ }
+
+ function noop() {}
+ noop.exec = noop;
+
+ function merge(obj) {
+ var i = 1
+ , target
+ , key;
+
+ for (; i < arguments.length; i++) {
+ target = arguments[i];
+ for (key in target) {
+ if (Object.prototype.hasOwnProperty.call(target, key)) {
+ obj[key] = target[key];
+ }
+ }
+ }
+
+ return obj;
+ }
+
+
+ /**
+ * Marked
+ */
+
+ function marked(src, opt, callback) {
+ if (callback || typeof opt === 'function') {
+ if (!callback) {
+ callback = opt;
+ opt = null;
+ }
+
+ opt = merge({}, marked.defaults, opt || {});
+
+ var highlight = opt.highlight
+ , tokens
+ , pending
+ , i = 0;
+
+ try {
+ tokens = Lexer.lex(src, opt)
+ } catch (e) {
+ return callback(e);
+ }
+
+ pending = tokens.length;
+
+ var done = function() {
+ var out, err;
+
+ try {
+ out = Parser.parse(tokens, opt);
+ } catch (e) {
+ err = e;
+ }
+
+ opt.highlight = highlight;
+
+ return err
+ ? callback(err)
+ : callback(null, out);
+ };
+
+ return done();
+ }
+ try {
+ if (opt) opt = merge({}, marked.defaults, opt);
+ return Parser.parse(Lexer.lex(src, opt), opt);
+ } catch (e) {
+ e.message += '\nPlease report this to https://github.com/chjj/marked.';
+ if ((opt || marked.defaults).silent) {
+ return '<p>An error occured:</p><pre>'
+ + escape(e.message + '', true)
+ + '</pre>';
+ }
+ throw e;
+ }
+ }
+
+ /**
+ * Options
+ */
+
+ marked.options =
+ marked.setOptions = function(opt) {
+ merge(marked.defaults, opt);
+ return marked;
+ };
+
+ marked.defaults = {
+ gfm: true,
+ tables: true,
+ breaks: false,
+ pedantic: false,
+ sanitize: false,
+ smartLists: false,
+ silent: false,
+ smartypants: false,
+ renderer: new Renderer
+ };
+
+ /**
+ * Expose
+ */
+
+ marked.Parser = Parser;
+ marked.parser = Parser.parse;
+
+ marked.Renderer = Renderer;
+
+ marked.Lexer = Lexer;
+ marked.lexer = Lexer.lex;
+
+ marked.InlineLexer = InlineLexer;
+ marked.inlineLexer = InlineLexer.output;
+
+ marked.parse = marked;
+
+ if (typeof exports === 'object') {
+ module.exports = marked;
+ } else if (typeof define === 'function' && define.amd) {
+ define(function() { return marked; });
+ } else {
+ this.marked = marked;
+ }
+
+}).call(function() {
+ return this || (typeof window !== 'undefined' ? window : global);
+ }());
--- /dev/null
+/*
+ RequireJS 2.1.9 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
+ Available via the MIT or new BSD license.
+ see: http://github.com/jrburke/requirejs for details
+*/
+var requirejs,require,define;
+(function(Z){function H(b){return"[object Function]"===L.call(b)}function I(b){return"[object Array]"===L.call(b)}function y(b,c){if(b){var e;for(e=0;e<b.length&&(!b[e]||!c(b[e],e,b));e+=1);}}function M(b,c){if(b){var e;for(e=b.length-1;-1<e&&(!b[e]||!c(b[e],e,b));e-=1);}}function t(b,c){return ga.call(b,c)}function l(b,c){return t(b,c)&&b[c]}function F(b,c){for(var e in b)if(t(b,e)&&c(b[e],e))break}function Q(b,c,e,h){c&&F(c,function(c,j){if(e||!t(b,j))h&&"string"!==typeof c?(b[j]||(b[j]={}),Q(b[j],
+c,e,h)):b[j]=c});return b}function u(b,c){return function(){return c.apply(b,arguments)}}function aa(b){throw b;}function ba(b){if(!b)return b;var c=Z;y(b.split("."),function(b){c=c[b]});return c}function A(b,c,e,h){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=h;e&&(c.originalError=e);return c}function ha(b){function c(a,f,b){var d,m,c,g,e,h,j,i=f&&f.split("/");d=i;var n=k.map,p=n&&n["*"];if(a&&"."===a.charAt(0))if(f){d=l(k.pkgs,f)?i=[f]:i.slice(0,i.length-
+1);f=a=d.concat(a.split("/"));for(d=0;f[d];d+=1)if(m=f[d],"."===m)f.splice(d,1),d-=1;else if(".."===m)if(1===d&&(".."===f[2]||".."===f[0]))break;else 0<d&&(f.splice(d-1,2),d-=2);d=l(k.pkgs,f=a[0]);a=a.join("/");d&&a===f+"/"+d.main&&(a=f)}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&n&&(i||p)){f=a.split("/");for(d=f.length;0<d;d-=1){c=f.slice(0,d).join("/");if(i)for(m=i.length;0<m;m-=1)if(b=l(n,i.slice(0,m).join("/")))if(b=l(b,c)){g=b;e=d;break}if(g)break;!h&&(p&&l(p,c))&&(h=l(p,c),j=d)}!g&&
+h&&(g=h,e=j);g&&(f.splice(0,e,g),a=f.join("/"))}return a}function e(a){z&&y(document.getElementsByTagName("script"),function(f){if(f.getAttribute("data-requiremodule")===a&&f.getAttribute("data-requirecontext")===i.contextName)return f.parentNode.removeChild(f),!0})}function h(a){var f=l(k.paths,a);if(f&&I(f)&&1<f.length)return f.shift(),i.require.undef(a),i.require([a]),!0}function $(a){var f,b=a?a.indexOf("!"):-1;-1<b&&(f=a.substring(0,b),a=a.substring(b+1,a.length));return[f,a]}function n(a,f,
+b,d){var m,B,g=null,e=f?f.name:null,h=a,j=!0,k="";a||(j=!1,a="_@r"+(L+=1));a=$(a);g=a[0];a=a[1];g&&(g=c(g,e,d),B=l(r,g));a&&(g?k=B&&B.normalize?B.normalize(a,function(a){return c(a,e,d)}):c(a,e,d):(k=c(a,e,d),a=$(k),g=a[0],k=a[1],b=!0,m=i.nameToUrl(k)));b=g&&!B&&!b?"_unnormalized"+(M+=1):"";return{prefix:g,name:k,parentMap:f,unnormalized:!!b,url:m,originalName:h,isDefine:j,id:(g?g+"!"+k:k)+b}}function q(a){var f=a.id,b=l(p,f);b||(b=p[f]=new i.Module(a));return b}function s(a,f,b){var d=a.id,m=l(p,
+d);if(t(r,d)&&(!m||m.defineEmitComplete))"defined"===f&&b(r[d]);else if(m=q(a),m.error&&"error"===f)b(m.error);else m.on(f,b)}function v(a,f){var b=a.requireModules,d=!1;if(f)f(a);else if(y(b,function(f){if(f=l(p,f))f.error=a,f.events.error&&(d=!0,f.emit("error",a))}),!d)j.onError(a)}function w(){R.length&&(ia.apply(G,[G.length-1,0].concat(R)),R=[])}function x(a){delete p[a];delete T[a]}function E(a,f,b){var d=a.map.id;a.error?a.emit("error",a.error):(f[d]=!0,y(a.depMaps,function(d,c){var g=d.id,
+e=l(p,g);e&&(!a.depMatched[c]&&!b[g])&&(l(f,g)?(a.defineDep(c,r[g]),a.check()):E(e,f,b))}),b[d]=!0)}function C(){var a,f,b,d,m=(b=1E3*k.waitSeconds)&&i.startTime+b<(new Date).getTime(),c=[],g=[],j=!1,l=!0;if(!U){U=!0;F(T,function(b){a=b.map;f=a.id;if(b.enabled&&(a.isDefine||g.push(b),!b.error))if(!b.inited&&m)h(f)?j=d=!0:(c.push(f),e(f));else if(!b.inited&&(b.fetched&&a.isDefine)&&(j=!0,!a.prefix))return l=!1});if(m&&c.length)return b=A("timeout","Load timeout for modules: "+c,null,c),b.contextName=
+i.contextName,v(b);l&&y(g,function(a){E(a,{},{})});if((!m||d)&&j)if((z||da)&&!V)V=setTimeout(function(){V=0;C()},50);U=!1}}function D(a){t(r,a[0])||q(n(a[0],null,!0)).init(a[1],a[2])}function J(a){var a=a.currentTarget||a.srcElement,b=i.onScriptLoad;a.detachEvent&&!W?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=i.onScriptError;(!a.detachEvent||W)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function K(){var a;for(w();G.length;){a=
+G.shift();if(null===a[0])return v(A("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));D(a)}}var U,X,i,N,V,k={waitSeconds:7,baseUrl:"./",paths:{},pkgs:{},shim:{},config:{}},p={},T={},Y={},G=[],r={},S={},L=1,M=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?a.exports:a.exports=r[a.map.id]={}},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){var b=
+l(k.pkgs,a.map.id);return(b?l(k.config,a.map.id+"/"+b.main):l(k.config,a.map.id))||{}},exports:r[a.map.id]}}};X=function(a){this.events=l(Y,a.id)||{};this.map=a;this.shim=l(k.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};X.prototype={init:function(a,b,c,d){d=d||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=u(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=c;this.inited=!0;
+this.ignore=d.ignore;d.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],u(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=
+this.map.url;S[a]||(S[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports;var d=this.exports,m=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(H(m)){if(this.events.error&&this.map.isDefine||j.onError!==aa)try{d=i.execCb(c,m,b,d)}catch(e){a=e}else d=i.execCb(c,m,b,d);this.map.isDefine&&((b=this.module)&&void 0!==b.exports&&b.exports!==
+this.exports?d=b.exports:void 0===d&&this.usingExports&&(d=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",v(this.error=a)}else d=m;this.exports=d;if(this.map.isDefine&&!this.ignore&&(r[c]=d,j.onResourceLoad))j.onResourceLoad(i,this.map,this.depMaps);x(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=
+!0)}}else this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,e=n(a.prefix);this.depMaps.push(e);s(e,"defined",u(this,function(d){var m,e;e=this.map.name;var g=this.map.parentMap?this.map.parentMap.name:null,h=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(d.normalize&&(e=d.normalize(e,function(a){return c(a,g,!0)})||""),d=n(a.prefix+"!"+e,this.map.parentMap),s(d,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),
+e=l(p,d.id)){this.depMaps.push(d);if(this.events.error)e.on("error",u(this,function(a){this.emit("error",a)}));e.enable()}}else m=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),m.error=u(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];F(p,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&x(a.map.id)});v(a)}),m.fromText=u(this,function(d,c){var e=a.name,g=n(e),B=O;c&&(d=c);B&&(O=!1);q(g);t(k.config,b)&&(k.config[e]=k.config[b]);try{j.exec(d)}catch(ca){return v(A("fromtexteval",
+"fromText eval for "+b+" failed: "+ca,ca,[b]))}B&&(O=!0);this.depMaps.push(g);i.completeLoad(e);h([e],m)}),d.load(a.name,h,m,k)}));i.enable(e,this);this.pluginMaps[e.id]=e},enable:function(){T[this.map.id]=this;this.enabling=this.enabled=!0;y(this.depMaps,u(this,function(a,b){var c,d;if("string"===typeof a){a=n(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=l(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;s(a,"defined",u(this,function(a){this.defineDep(b,
+a);this.check()}));this.errback&&s(a,"error",u(this,this.errback))}c=a.id;d=p[c];!t(N,c)&&(d&&!d.enabled)&&i.enable(a,this)}));F(this.pluginMaps,u(this,function(a){var b=l(p,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){y(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:k,contextName:b,registry:p,defined:r,urlFetched:S,defQueue:G,Module:X,makeModuleMap:n,
+nextTick:j.nextTick,onError:v,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=k.pkgs,c=k.shim,d={paths:!0,config:!0,map:!0};F(a,function(a,b){d[b]?"map"===b?(k.map||(k.map={}),Q(k[b],a,!0,!0)):Q(k[b],a,!0):k[b]=a});a.shim&&(F(a.shim,function(a,b){I(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);c[b]=a}),k.shim=c);a.packages&&(y(a.packages,function(a){a="string"===typeof a?{name:a}:a;b[a.name]={name:a.name,
+location:a.location||a.name,main:(a.main||"main").replace(ja,"").replace(ea,"")}}),k.pkgs=b);F(p,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=n(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(Z,arguments));return b||a.exports&&ba(a.exports)}},makeRequire:function(a,f){function h(d,c,e){var g,k;f.enableBuildCallback&&(c&&H(c))&&(c.__requireJsBuild=!0);if("string"===typeof d){if(H(c))return v(A("requireargs",
+"Invalid require call"),e);if(a&&t(N,d))return N[d](p[a.id]);if(j.get)return j.get(i,d,a,h);g=n(d,a,!1,!0);g=g.id;return!t(r,g)?v(A("notloaded",'Module name "'+g+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):r[g]}K();i.nextTick(function(){K();k=q(n(null,a));k.skipMap=f.skipMap;k.init(d,c,e,{enabled:!0});C()});return h}f=f||{};Q(h,{isBrowser:z,toUrl:function(b){var f,e=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==e&&(!("."===g||".."===g)||1<e))f=b.substring(e,b.length),b=
+b.substring(0,e);return i.nameToUrl(c(b,a&&a.id,!0),f,!0)},defined:function(b){return t(r,n(b,a,!1,!0).id)},specified:function(b){b=n(b,a,!1,!0).id;return t(r,b)||t(p,b)}});a||(h.undef=function(b){w();var c=n(b,a,!0),f=l(p,b);e(b);delete r[b];delete S[c.url];delete Y[b];f&&(f.events.defined&&(Y[b]=f.events),x(b))});return h},enable:function(a){l(p,a.id)&&q(a).enable()},completeLoad:function(a){var b,c,d=l(k.shim,a)||{},e=d.exports;for(w();G.length;){c=G.shift();if(null===c[0]){c[0]=a;if(b)break;b=
+!0}else c[0]===a&&(b=!0);D(c)}c=l(p,a);if(!b&&!t(r,a)&&c&&!c.inited){if(k.enforceDefine&&(!e||!ba(e)))return h(a)?void 0:v(A("nodefine","No define call for "+a,null,[a]));D([a,d.deps||[],d.exportsFn])}C()},nameToUrl:function(a,b,c){var d,e,h,g,i,n;if(j.jsExtRegExp.test(a))g=a+(b||"");else{d=k.paths;e=k.pkgs;g=a.split("/");for(i=g.length;0<i;i-=1)if(n=g.slice(0,i).join("/"),h=l(e,n),n=l(d,n)){I(n)&&(n=n[0]);g.splice(0,i,n);break}else if(h){a=a===h.name?h.location+"/"+h.main:h.location;g.splice(0,i,
+a);break}g=g.join("/");g+=b||(/^data\:|\?/.test(g)||c?"":".js");g=("/"===g.charAt(0)||g.match(/^[\w\+\.\-]+:/)?"":k.baseUrl)+g}return k.urlArgs?g+((-1===g.indexOf("?")?"?":"&")+k.urlArgs):g},load:function(a,b){j.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=J(a),i.completeLoad(a.id)},onScriptError:function(a){var b=J(a);if(!h(b.id))return v(A("scripterror","Script error for: "+b.id,
+a,[b.id]))}};i.require=i.makeRequire();return i}var j,w,x,C,J,D,P,K,q,fa,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,ea=/\.js$/,ja=/^\.\//;w=Object.prototype;var L=w.toString,ga=w.hasOwnProperty,ia=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),da=!z&&"undefined"!==typeof importScripts,ka=z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,W="undefined"!==typeof opera&&
+"[object Opera]"===opera.toString(),E={},s={},R=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(H(requirejs))return;s=requirejs;requirejs=void 0}"undefined"!==typeof require&&!H(require)&&(s=require,require=void 0);j=requirejs=function(b,c,e,h){var q,n="_";!I(b)&&"string"!==typeof b&&(q=b,I(c)?(b=c,c=e,e=h):b=[]);q&&q.context&&(n=q.context);(h=l(E,n))||(h=E[n]=j.s.newContext(n));q&&h.configure(q);return h.require(b,c,e)};j.config=function(b){return j(b)};j.nextTick="undefined"!==
+typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=j);j.version="2.1.9";j.jsExtRegExp=/^\/|:|\?|\.js$/;j.isBrowser=z;w=j.s={contexts:E,newContext:ha};j({});y(["toUrl","undef","defined","specified"],function(b){j[b]=function(){var c=E._;return c.require[b].apply(c,arguments)}});if(z&&(x=w.head=document.getElementsByTagName("head")[0],C=document.getElementsByTagName("base")[0]))x=w.head=C.parentNode;j.onError=aa;j.createNode=function(b){var c=b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml",
+"html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};j.load=function(b,c,e){var h=b&&b.config||{};if(z)return h=j.createNode(h,c,e),h.setAttribute("data-requirecontext",b.contextName),h.setAttribute("data-requiremodule",c),h.attachEvent&&!(h.attachEvent.toString&&0>h.attachEvent.toString().indexOf("[native code"))&&!W?(O=!0,h.attachEvent("onreadystatechange",b.onScriptLoad)):(h.addEventListener("load",b.onScriptLoad,!1),h.addEventListener("error",
+b.onScriptError,!1)),h.src=e,K=h,C?x.insertBefore(h,C):x.appendChild(h),K=null,h;if(da)try{importScripts(e),b.completeLoad(c)}catch(l){b.onError(A("importscripts","importScripts failed for "+c+" at "+e,l,[c]))}};z&&!s.skipDataMain&&M(document.getElementsByTagName("script"),function(b){x||(x=b.parentNode);if(J=b.getAttribute("data-main"))return q=J,s.baseUrl||(D=q.split("/"),q=D.pop(),fa=D.length?D.join("/")+"/":"./",s.baseUrl=fa),q=q.replace(ea,""),j.jsExtRegExp.test(q)&&(q=J),s.deps=s.deps?s.deps.concat(q):
+[q],!0});define=function(b,c,e){var h,j;"string"!==typeof b&&(e=c,c=b,b=null);I(c)||(e=c,c=null);!c&&H(e)&&(c=[],e.length&&(e.toString().replace(la,"").replace(ma,function(b,e){c.push(e)}),c=(1===e.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(h=K))P&&"interactive"===P.readyState||M(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),h=P;h&&(b||(b=h.getAttribute("data-requiremodule")),j=E[h.getAttribute("data-requirecontext")])}(j?
+j.defQueue:R).push([b,c,e])};define.amd={jQuery:!0};j.exec=function(b){return eval(b)};j(s)}})(this);
--- /dev/null
+/*
+ Copyright 2010 James Halliday (mail@substack.net)
+
+ This project is free software released under the MIT/X11 license:
+ http://www.opensource.org/licenses/mit-license.php
+
+ Copyright 2010 James Halliday (mail@substack.net)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+
+var traverse;
+
+(function(){
+ traverse = function (obj) {
+ return new Traverse(obj);
+ };
+
+ function Traverse (obj) {
+ this.value = obj;
+ }
+
+ Traverse.prototype.get = function (ps) {
+ var node = this.value;
+ for (var i = 0; i < ps.length; i ++) {
+ var key = ps[i];
+ if (!node || !hasOwnProperty.call(node, key)) {
+ node = undefined;
+ break;
+ }
+ node = node[key];
+ }
+ return node;
+ };
+
+ Traverse.prototype.has = function (ps) {
+ var node = this.value;
+ for (var i = 0; i < ps.length; i ++) {
+ var key = ps[i];
+ if (!node || !hasOwnProperty.call(node, key)) {
+ return false;
+ }
+ node = node[key];
+ }
+ return true;
+ };
+
+ Traverse.prototype.set = function (ps, value) {
+ var node = this.value;
+ for (var i = 0; i < ps.length - 1; i ++) {
+ var key = ps[i];
+ if (!hasOwnProperty.call(node, key)) node[key] = {};
+ node = node[key];
+ }
+ node[ps[i]] = value;
+ return value;
+ };
+
+ Traverse.prototype.map = function (cb) {
+ return walk(this.value, cb, true);
+ };
+
+ Traverse.prototype.forEach = function (cb) {
+ this.value = walk(this.value, cb, false);
+ return this.value;
+ };
+
+ Traverse.prototype.reduce = function (cb, init) {
+ var skip = arguments.length === 1;
+ var acc = skip ? this.value : init;
+ this.forEach(function (x) {
+ if (!this.isRoot || !skip) {
+ acc = cb.call(this, acc, x);
+ }
+ });
+ return acc;
+ };
+
+ Traverse.prototype.paths = function () {
+ var acc = [];
+ this.forEach(function (x) {
+ acc.push(this.path);
+ });
+ return acc;
+ };
+
+ Traverse.prototype.nodes = function () {
+ var acc = [];
+ this.forEach(function (x) {
+ acc.push(this.node);
+ });
+ return acc;
+ };
+
+ Traverse.prototype.clone = function () {
+ var parents = [], nodes = [];
+
+ return (function clone (src) {
+ for (var i = 0; i < parents.length; i++) {
+ if (parents[i] === src) {
+ return nodes[i];
+ }
+ }
+
+ if (typeof src === 'object' && src !== null) {
+ var dst = copy(src);
+
+ parents.push(src);
+ nodes.push(dst);
+
+ forEach(objectKeys(src), function (key) {
+ dst[key] = clone(src[key]);
+ });
+
+ parents.pop();
+ nodes.pop();
+ return dst;
+ }
+ else {
+ return src;
+ }
+ })(this.value);
+ };
+
+ function walk (root, cb, immutable) {
+ var path = [];
+ var parents = [];
+ var alive = true;
+
+ return (function walker (node_) {
+ var node = immutable ? copy(node_) : node_;
+ var modifiers = {};
+
+ var keepGoing = true;
+
+ var state = {
+ node : node,
+ node_ : node_,
+ path : [].concat(path),
+ parent : parents[parents.length - 1],
+ parents : parents,
+ key : path.slice(-1)[0],
+ isRoot : path.length === 0,
+ level : path.length,
+ circular : null,
+ update : function (x, stopHere) {
+ if (!state.isRoot) {
+ state.parent.node[state.key] = x;
+ }
+ state.node = x;
+ if (stopHere) keepGoing = false;
+ },
+ 'delete' : function (stopHere) {
+ delete state.parent.node[state.key];
+ if (stopHere) keepGoing = false;
+ },
+ remove : function (stopHere) {
+ if (isArray(state.parent.node)) {
+ state.parent.node.splice(state.key, 1);
+ }
+ else {
+ delete state.parent.node[state.key];
+ }
+ if (stopHere) keepGoing = false;
+ },
+ keys : null,
+ before : function (f) { modifiers.before = f },
+ after : function (f) { modifiers.after = f },
+ pre : function (f) { modifiers.pre = f },
+ post : function (f) { modifiers.post = f },
+ stop : function () { alive = false },
+ block : function () { keepGoing = false }
+ };
+
+ if (!alive) return state;
+
+ function updateState() {
+ if (typeof state.node === 'object' && state.node !== null) {
+ if (!state.keys || state.node_ !== state.node) {
+ state.keys = objectKeys(state.node)
+ }
+
+ state.isLeaf = state.keys.length == 0;
+
+ for (var i = 0; i < parents.length; i++) {
+ if (parents[i].node_ === node_) {
+ state.circular = parents[i];
+ break;
+ }
+ }
+ }
+ else {
+ state.isLeaf = true;
+ state.keys = null;
+ }
+
+ state.notLeaf = !state.isLeaf;
+ state.notRoot = !state.isRoot;
+ }
+
+ updateState();
+
+ // use return values to update if defined
+ var ret = cb.call(state, state.node);
+ if (ret !== undefined && state.update) state.update(ret);
+
+ if (modifiers.before) modifiers.before.call(state, state.node);
+
+ if (!keepGoing) return state;
+
+ if (typeof state.node == 'object'
+ && state.node !== null && !state.circular) {
+ parents.push(state);
+
+ updateState();
+
+ forEach(state.keys, function (key, i) {
+ path.push(key);
+
+ if (modifiers.pre) modifiers.pre.call(state, state.node[key], key);
+
+ var child = walker(state.node[key]);
+ if (immutable && hasOwnProperty.call(state.node, key)) {
+ state.node[key] = child.node;
+ }
+
+ child.isLast = i == state.keys.length - 1;
+ child.isFirst = i == 0;
+
+ if (modifiers.post) modifiers.post.call(state, child);
+
+ path.pop();
+ });
+ parents.pop();
+ }
+
+ if (modifiers.after) modifiers.after.call(state, state.node);
+
+ return state;
+ })(root).node;
+ }
+
+ function copy (src) {
+ if (typeof src === 'object' && src !== null) {
+ var dst;
+
+ if (isArray(src)) {
+ dst = [];
+ }
+ else if (isDate(src)) {
+ dst = new Date(src.getTime ? src.getTime() : src);
+ }
+ else if (isRegExp(src)) {
+ dst = new RegExp(src);
+ }
+ else if (isError(src)) {
+ dst = { message: src.message };
+ }
+ else if (isBoolean(src)) {
+ dst = new Boolean(src);
+ }
+ else if (isNumber(src)) {
+ dst = new Number(src);
+ }
+ else if (isString(src)) {
+ dst = new String(src);
+ }
+ else if (Object.create && Object.getPrototypeOf) {
+ dst = Object.create(Object.getPrototypeOf(src));
+ }
+ else if (src.constructor === Object) {
+ dst = {};
+ }
+ else {
+ var proto =
+ (src.constructor && src.constructor.prototype)
+ || src.__proto__
+ || {}
+ ;
+ var T = function () {};
+ T.prototype = proto;
+ dst = new T;
+ }
+
+ forEach(objectKeys(src), function (key) {
+ dst[key] = src[key];
+ });
+ return dst;
+ }
+ else return src;
+ }
+
+ var objectKeys = Object.keys || function keys (obj) {
+ var res = [];
+ for (var key in obj) res.push(key)
+ return res;
+ };
+
+ function toS (obj) { return Object.prototype.toString.call(obj) }
+ function isDate (obj) { return toS(obj) === '[object Date]' }
+ function isRegExp (obj) { return toS(obj) === '[object RegExp]' }
+ function isError (obj) { return toS(obj) === '[object Error]' }
+ function isBoolean (obj) { return toS(obj) === '[object Boolean]' }
+ function isNumber (obj) { return toS(obj) === '[object Number]' }
+ function isString (obj) { return toS(obj) === '[object String]' }
+
+ var isArray = Array.isArray || function isArray (xs) {
+ return Object.prototype.toString.call(xs) === '[object Array]';
+ };
+
+ var forEach = function (xs, fn) {
+ if (xs.forEach) return xs.forEach(fn)
+ else for (var i = 0; i < xs.length; i++) {
+ fn(xs[i], i, xs);
+ }
+ };
+
+ forEach(objectKeys(Traverse.prototype), function (key) {
+ traverse[key] = function (obj) {
+ var args = [].slice.call(arguments, 1);
+ var t = new Traverse(obj);
+ return t[key].apply(t, args);
+ };
+ });
+
+ var hasOwnProperty = Object.hasOwnProperty || function (obj, key) {
+ return key in obj;
+ };
+})();
--- /dev/null
+{{!
+ Copyright 2013 Laurent Bovet (laurent.bovet@windmaster.ch)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+}}
+{{#scope this}}
+ <div class="box">
+ <div class="box-header box-{{__boxId}}">
+ <div class="box-title" ref="{{__ref}}">
+ {{#name this}}<div class="box-name {{#if root}}title{{/if}}">{{__name}}</div>{{/name}}
+ <div class="box-description desc">{{desc this}}</div>
+ <div class="end"></div>
+ </div>
+ </div>
+ <div class="source-button button" title="Source">{}</div>
+ <div class="box-body">
+ <div class="expand-button button" title="Expand all">+</div>
+ {{#sub this}}
+ <div class="signature">
+ <div class="signature-header">
+ <div class="signature-type">
+ {{#primitive this}}
+ {{signature this null this}}
+ {{/primitive}}
+ {{#equals type "array"}}
+ {{signature this "array" items}}
+ {{/equals}}
+ {{#if allOf}}
+ {{signature this "all of" allOf}}
+ {{/if}}
+ {{#if anyOf}}
+ {{signature this "any of" anyOf}}
+ {{/if}}
+ {{#if oneOf}}
+ {{signature this "one of" oneOf}}
+ {{/if}}
+ {{#if not}}
+ {{signature this "not" not}}
+ {{/if}}
+ </div>
+ </div>
+ <div class="signature-box-container">
+ {{#boxes}}
+ <div class="box-container" boxid="{{__boxId}}">
+ {{schema this}}
+ </div>
+ {{/boxes}}
+ </div>
+ </div>
+ {{/sub}}
+ {{#if properties}}
+ {{#each properties}}
+ <div class="signature">
+ <div class="signature-header">
+ <div class="property-name {{#contains ../required @key}}required{{/contains}}">{{@key}}</div>
+ <div class="signature-type">
+ {{#main this}}
+ {{signature this null this}}
+ {{/main}}
+ {{#equals type "array"}}
+ {{signature this "array" items}}
+ {{/equals}}
+ {{#if allOf}}
+ {{signature this "all of" allOf}}
+ {{/if}}
+ {{#if anyOf}}
+ {{signature this "any of" anyOf}}
+ {{/if}}
+ {{#if oneOf}}
+ {{signature this "one of" oneOf}}
+ {{/if}}
+ {{#if additionalProperties}}
+ {{signature this "map" additionalProperties}}
+ {{/if}}
+ {{#if not}}
+ {{signature this "not" not}}
+ {{/if}}
+ </div>
+ <div class="signature-description desc">{{desc this}}</div>
+ </div>
+ <div class="signature-box-container">
+ {{#boxes}}
+ <div class="box-container" boxid="{{__boxId}}">
+ {{schema this}}
+ </div>
+ {{/boxes}}
+ </div>
+ </div>
+ {{/each}}
+ {{/if}}
+
+ {{#if patternProperties}}
+ {{#each patternProperties}}
+ <div class="signature">
+ <div class="signature-header">
+ <div class="property-name type-pattern">{{@key}}</div>
+ <div class="signature-type">
+ {{#main this}}
+ {{signature this null this}}
+ {{/main}}
+ {{#equals type "array"}}
+ {{signature this "array" items}}
+ {{/equals}}
+ {{#if allOf}}
+ {{signature this "all of" allOf}}
+ {{/if}}
+ {{#if anyOf}}
+ {{signature this "any of" anyOf}}
+ {{/if}}
+ {{#if oneOf}}
+ {{signature this "one of" oneOf}}
+ {{/if}}
+ {{#if not}}
+ {{signature this "not" not}}
+ {{/if}}
+ </div>
+ <div class="signature-description desc">{{desc this}}</div>
+ </div>
+ <div class="signature-box-container">
+ {{#boxes}}
+ <div class="box-container" boxid="{{__boxId}}">
+ {{schema this}}
+ </div>
+ {{/boxes}}
+ </div>
+ </div>
+ {{/each}}
+ {{/if}}
+
+ {{#if additionalProperties}}
+ <div class="signature">
+ <div class="signature-header">
+ <div class="property-name type-pattern">additional</div>
+ <div class="signature-type">
+ {{schema ../additionalProperties}}
+ </div>
+ </div>
+ </div>
+ {{/if}}
+ </div>
+ <div class="source">
+ <pre class="json-schema">
+{{source this}}</pre>
+ </div>
+</div>
+<div class="end"/>
+{{/scope}}
--- /dev/null
+{{!
+ Copyright 2013 Laurent Bovet (laurent.bovet@windmaster.ch)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+}}
+{{#if keyword}}
+ <span class="type-keyword">{{keyword}}{{range schema.minItems schema.maxItems 0 "" false false ".."}}</span>
+ {{#each schemas}}
+ <span class="type-keyword">{{enum this}}</span>
+ {{#simple this}}
+ <span class="signature-type-{{__type}}">
+ {{__type}}
+ </span>
+ <span class="type-keyword">
+ {{range minLength maxLength "" "" false false ".."}}{{range minimum maximum "-∞" "∞" exclusiveMinimum exclusiveMaximum ";"}}
+ </span>
+ {{/simple}}
+ {{#complex this}}
+ {{#box this}}
+ <span boxid="{{boxId}}" class="box-{{boxId}} signature-type-{{__type}} signature-button signature-type-expandable button">{{__type}}</span>
+ {{/box}}
+ {{/complex}}
+ {{#ref this}}
+ {{#box this}}
+ <span boxid="{{boxId}}" class="box-{{boxId}} signature-type-ref signature-button signature-type-expandable button">{{__name}}</span>
+ {{/box}}
+ {{/ref}}
+ {{#if pattern}}
+ <span class="type-pattern">/{{pattern}}/</span>
+ {{/if}}
+ {{#if enum}}
+ {{#each enum}}
+ <span class="type-enum">{{this}}</span>
+ {{/each}}
+ {{/if}}
+ {{#exists default}}
+ <span class="type-keyword">default</span>
+ <span class="type-default">{{__default}}</span>
+ {{/exists}}
+ {{/each}}
+{{/if}}
+{{#unless keyword}}
+ {{#each schemas}}
+ <span class="type-keyword">{{enum this}}</span>
+ {{#primitive this}}
+ <span class="signature-type-{{__type}}">
+ {{__type}}
+ </span>
+ <span class="type-keyword">
+ {{range minLength maxLength "" "" false false ".."}}{{range minimum maximum "-∞" "∞" exclusiveMinimum exclusiveMaximum ";"}}
+ </span>
+ {{/primitive}}
+ {{#ref this}}
+ {{#box this}}
+ <span boxid="{{boxId}}" class="box-{{boxId}} signature-type-ref signature-button signature-type-expandable button">{{__name}}</span>
+ {{/box}}
+ {{/ref}}
+ {{#obj this}}
+ {{#box this}}
+ <span boxid="{{boxId}}" class="box-{{boxId}} signature-type-{{__type}} signature-button signature-type-expandable button">{{__type}}</span>
+ {{/box}}
+ {{/obj}}
+ {{#if pattern}}
+ <span class="type-pattern">/{{pattern}}/</span>
+ {{/if}}
+ {{#if enum}}
+ {{#each enum}}
+ <span class="type-enum">{{this}}</span>
+ {{/each}}
+ {{/if}}
+ {{#exists default}}
+ <span class="type-keyword">default</span>
+ <span class="type-default">{{__default}}</span>
+ {{/exists}}
+ {{/each}}
+{{/unless}}
--- /dev/null
+[
+ {
+ "description": "additionalItems as schema",
+ "schema": {
+ "items": [{}],
+ "additionalItems": {"type": "integer"}
+ },
+ "tests": [
+ {
+ "description": "additional items match schema",
+ "data": [ null, 2, 3, 4 ],
+ "valid": true
+ },
+ {
+ "description": "additional items do not match schema",
+ "data": [ null, 2, 3, "foo" ],
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "items is schema, no additionalItems",
+ "schema": {
+ "items": {},
+ "additionalItems": false
+ },
+ "tests": [
+ {
+ "description": "all items match schema",
+ "data": [ 1, 2, 3, 4, 5 ],
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "array of items with no additionalItems",
+ "schema": {
+ "items": [{}, {}, {}],
+ "additionalItems": false
+ },
+ "tests": [
+ {
+ "description": "no additional items present",
+ "data": [ 1, 2, 3 ],
+ "valid": true
+ },
+ {
+ "description": "additional items are not permitted",
+ "data": [ 1, 2, 3, 4 ],
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "additionalItems as false without items",
+ "schema": {"additionalItems": false},
+ "tests": [
+ {
+ "description":
+ "items defaults to empty schema so everything is valid",
+ "data": [ 1, 2, 3, 4, 5 ],
+ "valid": true
+ },
+ {
+ "description": "ignores non-arrays",
+ "data": {"foo" : "bar"},
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "additionalItems are allowed by default",
+ "schema": {"items": [{"type": "integer"}]},
+ "tests": [
+ {
+ "description": "only the first item is validated",
+ "data": [1, "foo", false],
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description":
+ "additionalProperties being false does not allow other properties",
+ "schema": {
+ "properties": {"foo": {}, "bar": {}},
+ "patternProperties": { "^v": {} },
+ "additionalProperties": false
+ },
+ "tests": [
+ {
+ "description": "no additional properties is valid",
+ "data": {"foo": 1},
+ "valid": true
+ },
+ {
+ "description": "an additional property is invalid",
+ "data": {"foo" : 1, "bar" : 2, "quux" : "boom"},
+ "valid": false
+ },
+ {
+ "description": "ignores non-objects",
+ "data": [1, 2, 3],
+ "valid": true
+ },
+ {
+ "description": "patternProperties are not additional properties",
+ "data": {"foo":1, "vroom": 2},
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description":
+ "additionalProperties allows a schema which should validate",
+ "schema": {
+ "properties": {"foo": {}, "bar": {}},
+ "additionalProperties": {"type": "boolean"}
+ },
+ "tests": [
+ {
+ "description": "no additional properties is valid",
+ "data": {"foo": 1},
+ "valid": true
+ },
+ {
+ "description": "an additional valid property is valid",
+ "data": {"foo" : 1, "bar" : 2, "quux" : true},
+ "valid": true
+ },
+ {
+ "description": "an additional invalid property is invalid",
+ "data": {"foo" : 1, "bar" : 2, "quux" : 12},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "additionalProperties are allowed by default",
+ "schema": {"properties": {"foo": {}, "bar": {}}},
+ "tests": [
+ {
+ "description": "additional properties are allowed",
+ "data": {"foo": 1, "bar": 2, "quux": true},
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "schema" : {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+ "address": {
+ "type": "object",
+ "properties": {
+ "street_address": { "type": "string" },
+ "city": { "type": "string" },
+ "state": { "type": "string" }
+ },
+ "required": ["street_address", "city", "state"]
+ }
+ },
+
+ "type": "object",
+
+ "properties": {
+ "billing_address": { "$ref": "#/definitions/address" },
+ "shipping_address": {
+ "allOf": [
+ { "$ref": "#/definitions/address" },
+ { "properties":
+ { "type": { "enum": [ "residential", "business" ] } },
+ "required": ["type"]
+ }
+ ]
+ }
+ }
+ }
+ }]
--- /dev/null
+[
+ {
+ "description": "allOf",
+ "schema": {
+ "allOf": [
+ {
+ "properties": {
+ "bar": {"type": "integer"}
+ },
+ "required": ["bar"]
+ },
+ {
+ "properties": {
+ "foo": {"type": "string"}
+ },
+ "required": ["foo"]
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "allOf",
+ "data": {"foo": "baz", "bar": 2},
+ "valid": true
+ },
+ {
+ "description": "mismatch second",
+ "data": {"foo": "baz"},
+ "valid": false
+ },
+ {
+ "description": "mismatch first",
+ "data": {"bar": 2},
+ "valid": false
+ },
+ {
+ "description": "wrong type",
+ "data": {"foo": "baz", "bar": "quux"},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "allOf with base schema",
+ "schema": {
+ "properties": {"bar": {"type": "integer"}},
+ "required": ["bar"],
+ "allOf" : [
+ {
+ "properties": {
+ "foo": {"type": "string"}
+ },
+ "required": ["foo"]
+ },
+ {
+ "properties": {
+ "baz": {"type": "null"}
+ },
+ "required": ["baz"]
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "valid",
+ "data": {"foo": "quux", "bar": 2, "baz": null},
+ "valid": true
+ },
+ {
+ "description": "mismatch base schema",
+ "data": {"foo": "quux", "baz": null},
+ "valid": false
+ },
+ {
+ "description": "mismatch first allOf",
+ "data": {"bar": 2, "baz": null},
+ "valid": false
+ },
+ {
+ "description": "mismatch second allOf",
+ "data": {"foo": "quux", "bar": 2},
+ "valid": false
+ },
+ {
+ "description": "mismatch both",
+ "data": {"bar": 2},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "allOf simple types",
+ "schema": {
+ "allOf": [
+ {"maximum": 30},
+ {"minimum": 20}
+ ]
+ },
+ "tests": [
+ {
+ "description": "valid",
+ "data": 25,
+ "valid": true
+ },
+ {
+ "description": "mismatch one",
+ "data": 35,
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "anyOf",
+ "schema": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "minimum": 2
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "first anyOf valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "second anyOf valid",
+ "data": 2.5,
+ "valid": true
+ },
+ {
+ "description": "both anyOf valid",
+ "data": 3,
+ "valid": true
+ },
+ {
+ "description": "neither anyOf valid",
+ "data": 1.5,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "anyOf with base schema",
+ "schema": {
+ "type": "string",
+ "anyOf" : [
+ {
+ "maxLength": 2
+ },
+ {
+ "minLength": 4
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "mismatch base schema",
+ "data": 3,
+ "valid": false
+ },
+ {
+ "description": "one anyOf valid",
+ "data": "foobar",
+ "valid": true
+ },
+ {
+ "description": "both anyOf invalid",
+ "data": "foo",
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[{
+ "schema": {
+ "title": "Example Schema",
+ "type": "object",
+ "properties": {
+ "firstName": {
+ "type": "string"
+ },
+ "lastName": {
+ "type": "string"
+ },
+ "age": {
+ "description": "Age in years",
+ "type": "integer",
+ "minimum": 0
+ }
+ },
+ "required": ["firstName", "lastName"]
+ }
+}]
--- /dev/null
+[
+ {
+ "description": "valid definition",
+ "schema": {"$ref": "http://json-schema.org/draft-04/schema#"},
+ "tests": [
+ {
+ "description": "valid definition schema",
+ "data": {
+ "definitions": {
+ "foo": {"type": "integer"}
+ }
+ },
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "invalid definition",
+ "schema": {"$ref": "http://json-schema.org/draft-04/schema#"},
+ "tests": [
+ {
+ "description": "invalid definition schema",
+ "data": {
+ "definitions": {
+ "foo": {"type": 1}
+ }
+ },
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "dependencies",
+ "schema": {
+ "dependencies": {"bar": ["foo"]}
+ },
+ "tests": [
+ {
+ "description": "neither",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "nondependant",
+ "data": {"foo": 1},
+ "valid": true
+ },
+ {
+ "description": "with dependency",
+ "data": {"foo": 1, "bar": 2},
+ "valid": true
+ },
+ {
+ "description": "missing dependency",
+ "data": {"bar": 2},
+ "valid": false
+ },
+ {
+ "description": "ignores non-objects",
+ "data": "foo",
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "multiple dependencies",
+ "schema": {
+ "dependencies": {"quux": ["foo", "bar"]}
+ },
+ "tests": [
+ {
+ "description": "neither",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "nondependants",
+ "data": {"foo": 1, "bar": 2},
+ "valid": true
+ },
+ {
+ "description": "with dependencies",
+ "data": {"foo": 1, "bar": 2, "quux": 3},
+ "valid": true
+ },
+ {
+ "description": "missing dependency",
+ "data": {"foo": 1, "quux": 2},
+ "valid": false
+ },
+ {
+ "description": "missing other dependency",
+ "data": {"bar": 1, "quux": 2},
+ "valid": false
+ },
+ {
+ "description": "missing both dependencies",
+ "data": {"quux": 1},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "multiple dependencies subschema",
+ "schema": {
+ "dependencies": {
+ "bar": {
+ "properties": {
+ "foo": {"type": "integer"},
+ "bar": {"type": "integer"}
+ }
+ }
+ }
+ },
+ "tests": [
+ {
+ "description": "valid",
+ "data": {"foo": 1, "bar": 2},
+ "valid": true
+ },
+ {
+ "description": "no dependency",
+ "data": {"foo": "quux"},
+ "valid": true
+ },
+ {
+ "description": "wrong type",
+ "data": {"foo": "quux", "bar": 2},
+ "valid": false
+ },
+ {
+ "description": "wrong type other",
+ "data": {"foo": 2, "bar": "quux"},
+ "valid": false
+ },
+ {
+ "description": "wrong type both",
+ "data": {"foo": "quux", "bar": "quux"},
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "simple enum validation",
+ "schema": {"enum": [1, 2, 3]},
+ "tests": [
+ {
+ "description": "one of the enum is valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "something else is invalid",
+ "data": 4,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "heterogeneous enum validation",
+ "schema": {"enum": [6, "foo", [], true, {"foo": 12}]},
+ "tests": [
+ {
+ "description": "one of the enum is valid",
+ "data": [],
+ "valid": true
+ },
+ {
+ "description": "something else is invalid",
+ "data": null,
+ "valid": false
+ },
+ {
+ "description": "objects are deep compared",
+ "data": {"foo": false},
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "schema" : {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Product set",
+ "type": "array",
+ "items": {
+ "title": "Product",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "The unique identifier for a product",
+ "type": "number"
+ },
+ "name": {
+ "type": "string"
+ },
+ "price": {
+ "type": "number",
+ "minimum": 0,
+ "exclusiveMinimum": true
+ },
+ "tags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ },
+ "dimensions": {
+ "type": "object",
+ "properties": {
+ "length": {"type": "number"},
+ "width": {"type": "number"},
+ "height": {"type": "number"}
+ },
+ "required": ["length", "width", "height"]
+ },
+ "warehouseLocation": {
+ "description": "Coordinates of the warehouse with the product",
+ "$ref": "http://localhost:8000/docson/tests/geo.json"
+ }
+ },
+ "required": ["id", "name", "price"]
+ }
+ }
+ }
+]
--- /dev/null
+[
+ {
+ "schema": {
+ "id": "http://some.site.somewhere/entry-schema#",
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "schema for an fstab entry",
+ "type": "object",
+ "required": [ "storage" ],
+ "properties": {
+ "storage": {
+ "type": "object",
+ "oneOf": [
+ { "$ref": "#/definitions/diskDevice" },
+ { "$ref": "#/definitions/diskUUID" },
+ { "$ref": "#/definitions/nfs" },
+ { "$ref": "#/definitions/tmpfs" }
+ ]
+ },
+ "fstype": {
+ "enum": [ "ext3", "ext4", "btrfs" ],
+ "default": "ext3"
+ },
+ "options": {
+ "type": "array",
+ "minItems": 1,
+ "items": { "type": "string" },
+ "uniqueItems": true
+ },
+ "readonly": { "type": "boolean" }
+ },
+ "definitions": {
+ "diskDevice": {
+ "properties": {
+ "type": { "enum": [ "disk" ] },
+ "device": {
+ "type": "string",
+ "pattern": "^/dev/[^/]+(/[^/]+)*$"
+ }
+ },
+ "required": [ "type", "device" ],
+ "additionalProperties": false
+ },
+ "diskUUID": {
+ "properties": {
+ "type": { "enum": [ "disk" ] },
+ "label": {
+ "type": "string",
+ "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
+ }
+ },
+ "required": [ "type", "label" ],
+ "additionalProperties": false
+ },
+ "nfs": {
+ "properties": {
+ "type": { "enum": [ "nfs" ] },
+ "remotePath": {
+ "type": "string",
+ "pattern": "^(/[^/]+)+$"
+ },
+ "server": {
+ "type": "string",
+ "oneOf": [
+ { "format": "host-name" },
+ { "format": "ipv4" },
+ { "format": "ipv6" }
+ ]
+ }
+ },
+ "required": [ "type", "server", "remotePath" ],
+ "additionalProperties": false
+ },
+ "tmpfs": {
+ "properties": {
+ "type": { "enum": [ "tmpfs" ] },
+ "sizeInMB": {
+ "type": "integer",
+ "minimum": 16,
+ "maximum": 512
+ }
+ },
+ "required": [ "type", "sizeInMB" ],
+ "additionalProperties": false
+ }
+ }
+ }
+ }]
--- /dev/null
+{
+ "description": "A geographical coordinate",
+ "type": "object",
+ "properties": {
+ "latitude": { "type": "number" },
+ "longitude": { "type": "number" }
+ }
+}
--- /dev/null
+[
+ {
+ "schema": {
+ "Invoice": {
+ "id": "Invoice",
+ "description": "Represents the document sent to the customer for payment.",
+ "properties": {
+ "customer": {
+ "description": "Who will pay?\nNot me! éà è",
+ "type": "string"
+ },
+ "lines": {
+ "description": "Invoice content\n",
+ "minItems": "1",
+ "maxItems": "50",
+ "type": "array",
+ "items": {
+ "$ref": "InvoiceLine"
+ }
+ },
+ "dimension": {
+ "description": "Total dimension of the order ",
+ "$ref": "Dimension"
+ }
+ }
+ },
+ "InvoiceLine": {
+ "id": "InvoiceLine",
+ "properties": {
+ "product": {
+ "$ref": "Product"
+ },
+ "quantity": {
+ "minimum": "0",
+ "exclusiveMinimum": "true",
+ "maximum": "10",
+ "exclusiveMaximum": "false",
+ "type": "number"
+ }
+ }
+ },
+ "Dimension": {
+ "id": "Dimension",
+ "properties": {
+ "width": {
+ "description": "Width in cm ",
+ "type": "number"
+ },
+ "height": {
+ "description": "Height in cm ",
+ "type": "number"
+ },
+ "length": {
+ "description": "Length in cm ",
+ "type": "number"
+ }
+ }
+ },
+ "Product": {
+ "id": "Product",
+ "properties": {
+ "name": {
+ "description": "Uniquely defines the product ",
+ "type": "string"
+ },
+ "dimension": {
+ "description": "How big it is ",
+ "$ref": "Dimension"
+ },
+ "category": {
+ "description": "Classification ",
+ "$ref": "Category"
+ }
+ }
+ },
+ "Category": {
+ "id": "Category",
+ "properties": {
+ "name": {
+ "description": "Uniquely identifies the category ",
+ "type": "string"
+ },
+ "level": {
+ "description": "Classification level from 1 to 5 (highest) ",
+ "type": "number"
+ }
+ }
+ },
+ "CategoryIndex": {
+ "id": "CategoryIndex",
+ "properties": {
+ "categories": {},
+ "products": {},
+ "sizes": {}
+ }
+ }
+ }
+ }]
--- /dev/null
+[
+ {
+ "description": "a schema given for items",
+ "schema": {
+ "items": {"type": "integer"}
+ },
+ "tests": [
+ {
+ "description": "valid items",
+ "data": [ 1, 2, 3 ],
+ "valid": true
+ },
+ {
+ "description": "wrong type of items",
+ "data": [1, "x"],
+ "valid": false
+ },
+ {
+ "description": "ignores non-arrays",
+ "data": {"foo" : "bar"},
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "an array of schemas for items",
+ "schema": {
+ "items": [
+ {"type": "integer"},
+ {"type": "string"}
+ ]
+ },
+ "tests": [
+ {
+ "description": "correct types",
+ "data": [ 1, "foo" ],
+ "valid": true
+ },
+ {
+ "description": "wrong types",
+ "data": [ "foo", 1 ],
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "maxItems validation",
+ "schema": {"maxItems": 2},
+ "tests": [
+ {
+ "description": "shorter is valid",
+ "data": [1],
+ "valid": true
+ },
+ {
+ "description": "exact length is valid",
+ "data": [1, 2],
+ "valid": true
+ },
+ {
+ "description": "too long is invalid",
+ "data": [1, 2, 3],
+ "valid": false
+ },
+ {
+ "description": "ignores non-arrays",
+ "data": "foobar",
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "maxLength validation",
+ "schema": {"maxLength": 2},
+ "tests": [
+ {
+ "description": "shorter is valid",
+ "data": "f",
+ "valid": true
+ },
+ {
+ "description": "exact length is valid",
+ "data": "fo",
+ "valid": true
+ },
+ {
+ "description": "too long is invalid",
+ "data": "foo",
+ "valid": false
+ },
+ {
+ "description": "ignores non-strings",
+ "data": 10,
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "maxProperties validation",
+ "schema": {"maxProperties": 2},
+ "tests": [
+ {
+ "description": "shorter is valid",
+ "data": {"foo": 1},
+ "valid": true
+ },
+ {
+ "description": "exact length is valid",
+ "data": {"foo": 1, "bar": 2},
+ "valid": true
+ },
+ {
+ "description": "too long is invalid",
+ "data": {"foo": 1, "bar": 2, "baz": 3},
+ "valid": false
+ },
+ {
+ "description": "ignores non-objects",
+ "data": "foobar",
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "maximum validation",
+ "schema": {"maximum": 3.0},
+ "tests": [
+ {
+ "description": "below the maximum is valid",
+ "data": 2.6,
+ "valid": true
+ },
+ {
+ "description": "above the maximum is invalid",
+ "data": 3.5,
+ "valid": false
+ },
+ {
+ "description": "ignores non-numbers",
+ "data": "x",
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "exclusiveMaximum validation",
+ "schema": {
+ "maximum": 3.0,
+ "exclusiveMaximum": true
+ },
+ "tests": [
+ {
+ "description": "below the maximum is still valid",
+ "data": 2.2,
+ "valid": true
+ },
+ {
+ "description": "boundary point is invalid",
+ "data": 3.0,
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "minItems validation",
+ "schema": {"minItems": 1},
+ "tests": [
+ {
+ "description": "longer is valid",
+ "data": [1, 2],
+ "valid": true
+ },
+ {
+ "description": "exact length is valid",
+ "data": [1],
+ "valid": true
+ },
+ {
+ "description": "too short is invalid",
+ "data": [],
+ "valid": false
+ },
+ {
+ "description": "ignores non-arrays",
+ "data": "",
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "minLength validation",
+ "schema": {"minLength": 2},
+ "tests": [
+ {
+ "description": "longer is valid",
+ "data": "foo",
+ "valid": true
+ },
+ {
+ "description": "exact length is valid",
+ "data": "fo",
+ "valid": true
+ },
+ {
+ "description": "too short is invalid",
+ "data": "f",
+ "valid": false
+ },
+ {
+ "description": "ignores non-strings",
+ "data": 1,
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "minProperties validation",
+ "schema": {"minProperties": 1},
+ "tests": [
+ {
+ "description": "longer is valid",
+ "data": {"foo": 1, "bar": 2},
+ "valid": true
+ },
+ {
+ "description": "exact length is valid",
+ "data": {"foo": 1},
+ "valid": true
+ },
+ {
+ "description": "too short is invalid",
+ "data": {},
+ "valid": false
+ },
+ {
+ "description": "ignores non-objects",
+ "data": "",
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "minimum validation",
+ "schema": {"minimum": 1.1},
+ "tests": [
+ {
+ "description": "above the minimum is valid",
+ "data": 2.6,
+ "valid": true
+ },
+ {
+ "description": "below the minimum is invalid",
+ "data": 0.6,
+ "valid": false
+ },
+ {
+ "description": "ignores non-numbers",
+ "data": "x",
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "exclusiveMinimum validation",
+ "schema": {
+ "minimum": 1.1,
+ "exclusiveMinimum": true
+ },
+ "tests": [
+ {
+ "description": "above the minimum is still valid",
+ "data": 1.2,
+ "valid": true
+ },
+ {
+ "description": "boundary point is invalid",
+ "data": 1.1,
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "by int",
+ "schema": {"multipleOf": 2},
+ "tests": [
+ {
+ "description": "int by int",
+ "data": 10,
+ "valid": true
+ },
+ {
+ "description": "int by int fail",
+ "data": 7,
+ "valid": false
+ },
+ {
+ "description": "ignores non-numbers",
+ "data": "foo",
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "by number",
+ "schema": {"multipleOf": 1.5},
+ "tests": [
+ {
+ "description": "zero is multiple of anything",
+ "data": 0,
+ "valid": true
+ },
+ {
+ "description": "4.5 is multiple of 1.5",
+ "data": 4.5,
+ "valid": true
+ },
+ {
+ "description": "35 is not multiple of 1.5",
+ "data": 35,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "by small number",
+ "schema": {"multipleOf": 0.0001},
+ "tests": [
+ {
+ "description": "0.0075 is multiple of 0.0001",
+ "data": 0.0075,
+ "valid": true
+ },
+ {
+ "description": "0.00751 is not multiple of 0.0001",
+ "data": 0.00751,
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "not",
+ "schema": {
+ "not": {"type": "integer"}
+ },
+ "tests": [
+ {
+ "description": "allowed",
+ "data": "foo",
+ "valid": true
+ },
+ {
+ "description": "disallowed",
+ "data": 1,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "not multiple types",
+ "schema": {
+ "not": {"type": ["integer", "boolean"]}
+ },
+ "tests": [
+ {
+ "description": "valid",
+ "data": "foo",
+ "valid": true
+ },
+ {
+ "description": "mismatch",
+ "data": 1,
+ "valid": false
+ },
+ {
+ "description": "other mismatch",
+ "data": true,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "not more complex schema",
+ "schema": {
+ "not": {
+ "type": "object",
+ "properties": {
+ "foo": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "tests": [
+ {
+ "description": "match",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "other match",
+ "data": {"foo": 1},
+ "valid": true
+ },
+ {
+ "description": "mismatch",
+ "data": {"foo": "bar"},
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "oneOf",
+ "schema": {
+ "oneOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "minimum": 2
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "first oneOf valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "second oneOf valid",
+ "data": 2.5,
+ "valid": true
+ },
+ {
+ "description": "both oneOf valid",
+ "data": 3,
+ "valid": false
+ },
+ {
+ "description": "neither oneOf valid",
+ "data": 1.5,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "oneOf with base schema",
+ "schema": {
+ "type": "string",
+ "oneOf" : [
+ {
+ "minLength": 2
+ },
+ {
+ "maxLength": 4
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "mismatch base schema",
+ "data": 3,
+ "valid": false
+ },
+ {
+ "description": "one oneOf valid",
+ "data": "foobar",
+ "valid": true
+ },
+ {
+ "description": "both oneOf valid",
+ "data": "foo",
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "pattern validation",
+ "schema": {"pattern": "^a*$"},
+ "tests": [
+ {
+ "description": "a matching pattern is valid",
+ "data": "aaa",
+ "valid": true
+ },
+ {
+ "description": "a non-matching pattern is invalid",
+ "data": "abc",
+ "valid": false
+ },
+ {
+ "description": "ignores non-strings",
+ "data": true,
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description":
+ "patternProperties validates properties matching a regex",
+ "schema": {
+ "patternProperties": {
+ "f.*o": {"type": "integer"}
+ }
+ },
+ "tests": [
+ {
+ "description": "a single valid match is valid",
+ "data": {"foo": 1},
+ "valid": true
+ },
+ {
+ "description": "multiple valid matches is valid",
+ "data": {"foo": 1, "foooooo" : 2},
+ "valid": true
+ },
+ {
+ "description": "a single invalid match is invalid",
+ "data": {"foo": "bar", "fooooo": 2},
+ "valid": false
+ },
+ {
+ "description": "multiple invalid matches is invalid",
+ "data": {"foo": "bar", "foooooo" : "baz"},
+ "valid": false
+ },
+ {
+ "description": "ignores non-objects",
+ "data": 12,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "multiple simultaneous patternProperties are validated",
+ "schema": {
+ "patternProperties": {
+ "a*": {"type": "integer"},
+ "aaa*": {"maximum": 20}
+ }
+ },
+ "tests": [
+ {
+ "description": "a single valid match is valid",
+ "data": {"a": 21},
+ "valid": true
+ },
+ {
+ "description": "a simultaneous match is valid",
+ "data": {"aaaa": 18},
+ "valid": true
+ },
+ {
+ "description": "multiple matches is valid",
+ "data": {"a": 21, "aaaa": 18},
+ "valid": true
+ },
+ {
+ "description": "an invalid due to one is invalid",
+ "data": {"a": "bar"},
+ "valid": false
+ },
+ {
+ "description": "an invalid due to the other is invalid",
+ "data": {"aaaa": 31},
+ "valid": false
+ },
+ {
+ "description": "an invalid due to both is invalid",
+ "data": {"aaa": "foo", "aaaa": 31},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "regexes are not anchored by default and are case sensitive",
+ "schema": {
+ "patternProperties": {
+ "[0-9]{2,}": { "type": "boolean" },
+ "X_": { "type": "string" }
+ }
+ },
+ "tests": [
+ {
+ "description": "non recognized members are ignored",
+ "data": { "answer 1": "42" },
+ "valid": true
+ },
+ {
+ "description": "recognized members are accounted for",
+ "data": { "a31b": null },
+ "valid": false
+ },
+ {
+ "description": "regexes are case sensitive",
+ "data": { "a_x_3": 3 },
+ "valid": true
+ },
+ {
+ "description": "regexes are case sensitive, 2",
+ "data": { "a_X_3": 3 },
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "object properties validation",
+ "schema": {
+ "properties": {
+ "foo": {"type": "integer"},
+ "bar": {"type": "string"}
+ }
+ },
+ "tests": [
+ {
+ "description": "both properties present and valid is valid",
+ "data": {"foo": 1, "bar": "baz"},
+ "valid": true
+ },
+ {
+ "description": "one property invalid is invalid",
+ "data": {"foo": 1, "bar": {}},
+ "valid": false
+ },
+ {
+ "description": "both properties invalid is invalid",
+ "data": {"foo": [], "bar": {}},
+ "valid": false
+ },
+ {
+ "description": "doesn't invalidate other properties",
+ "data": {"quux": []},
+ "valid": true
+ },
+ {
+ "description": "ignores non-objects",
+ "data": [],
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description":
+ "properties, patternProperties, additionalProperties interaction",
+ "schema": {
+ "properties": {
+ "foo": {"type": "array", "maxItems": 3},
+ "bar": {"type": "array"}
+ },
+ "patternProperties": {"f.o": {"minItems": 2}},
+ "additionalProperties": {"type": "integer"}
+ },
+ "tests": [
+ {
+ "description": "property validates property",
+ "data": {"foo": [1, 2]},
+ "valid": true
+ },
+ {
+ "description": "property invalidates property",
+ "data": {"foo": [1, 2, 3, 4]},
+ "valid": false
+ },
+ {
+ "description": "patternProperty invalidates property",
+ "data": {"foo": []},
+ "valid": false
+ },
+ {
+ "description": "patternProperty validates nonproperty",
+ "data": {"fxo": [1, 2]},
+ "valid": true
+ },
+ {
+ "description": "patternProperty invalidates nonproperty",
+ "data": {"fxo": []},
+ "valid": false
+ },
+ {
+ "description": "additionalProperty ignores property",
+ "data": {"bar": []},
+ "valid": true
+ },
+ {
+ "description": "additionalProperty validates others",
+ "data": {"quux": 3},
+ "valid": true
+ },
+ {
+ "description": "additionalProperty invalidates others",
+ "data": {"quux": "foo"},
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "root pointer ref",
+ "schema": {
+ "properties": {
+ "foo": {"$ref": "#"}
+ },
+ "additionalProperties": false
+ },
+ "tests": [
+ {
+ "description": "match",
+ "data": {"foo": false},
+ "valid": true
+ },
+ {
+ "description": "recursive match",
+ "data": {"foo": {"foo": false}},
+ "valid": true
+ },
+ {
+ "description": "mismatch",
+ "data": {"bar": false},
+ "valid": false
+ },
+ {
+ "description": "recursive mismatch",
+ "data": {"foo": {"bar": false}},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "relative pointer ref to object",
+ "schema": {
+ "properties": {
+ "foo": {"type": "integer"},
+ "bar": {"$ref": "#/properties/foo"}
+ }
+ },
+ "tests": [
+ {
+ "description": "match",
+ "data": {"bar": 3},
+ "valid": true
+ },
+ {
+ "description": "mismatch",
+ "data": {"bar": true},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "relative pointer ref to array",
+ "schema": {
+ "items": [
+ {"type": "integer"},
+ {"$ref": "#/items/0"}
+ ]
+ },
+ "tests": [
+ {
+ "description": "match array",
+ "data": [1, 2],
+ "valid": true
+ },
+ {
+ "description": "mismatch array",
+ "data": [1, "foo"],
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "escaped pointer ref",
+ "schema": {
+ "tilda~field": {"type": "integer"},
+ "slash/field": {"type": "integer"},
+ "percent%field": {"type": "integer"},
+ "properties": {
+ "tilda": {"$ref": "#/tilda~0field"},
+ "slash": {"$ref": "#/slash~1field"},
+ "percent": {"$ref": "#/percent%25field"}
+ }
+ },
+ "tests": [
+ {
+ "description": "slash",
+ "data": {"slash": "aoeu"},
+ "valid": false
+ },
+ {
+ "description": "tilda",
+ "data": {"tilda": "aoeu"},
+ "valid": false
+ },
+ {
+ "description": "percent",
+ "data": {"percent": "aoeu"},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "nested refs",
+ "schema": {
+ "definitions": {
+ "a": {"type": "integer"},
+ "b": {"$ref": "#/definitions/a"},
+ "c": {"$ref": "#/definitions/b"}
+ },
+ "$ref": "#/definitions/c"
+ },
+ "tests": [
+ {
+ "description": "nested ref valid",
+ "data": 5,
+ "valid": true
+ },
+ {
+ "description": "nested ref invalid",
+ "data": "a",
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "remote ref, containing refs itself",
+ "schema": {"$ref": "http://json-schema.org/draft-04/schema#"},
+ "tests": [
+ {
+ "description": "remote ref valid",
+ "data": {"minLength": 1},
+ "valid": true
+ },
+ {
+ "description": "remote ref invalid",
+ "data": {"minLength": -1},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "circular refs",
+ "schema": {
+ "definitions": {
+ "a": {
+ "properties": {
+ "more": {"$ref": "#/definitions/a"}
+ }
+ }
+ },
+ "properties": {
+ "prop": {"$ref": "#/definitions/a"}
+ }
+ },
+ "tests": []
+ }
+]
--- /dev/null
+[
+ {
+ "description": "remote ref",
+ "schema": {"$ref": "http://localhost:1234/integer.json"},
+ "tests": [
+ {
+ "description": "remote ref valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "remote ref invalid",
+ "data": "a",
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "fragment within remote ref",
+ "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"},
+ "tests": [
+ {
+ "description": "remote fragment valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "remote fragment invalid",
+ "data": "a",
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "ref within remote ref",
+ "schema": {
+ "$ref": "http://localhost:1234/subSchemas.json#/refToInteger"
+ },
+ "tests": [
+ {
+ "description": "ref within ref valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "ref within ref invalid",
+ "data": "a",
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "change resolution scope",
+ "schema": {
+ "id": "http://localhost:1234/",
+ "items": {
+ "id": "folder/",
+ "items": {"$ref": "folderInteger.json"}
+ }
+ },
+ "tests": [
+ {
+ "description": "changed scope ref valid",
+ "data": [[1]],
+ "valid": true
+ },
+ {
+ "description": "changed scope ref invalid",
+ "data": [["a"]],
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "required validation",
+ "schema": {
+ "properties": {
+ "foo": {},
+ "bar": {}
+ },
+ "required": ["foo"]
+ },
+ "tests": [
+ {
+ "description": "present required property is valid",
+ "data": {"foo": 1},
+ "valid": true
+ },
+ {
+ "description": "non-present required property is invalid",
+ "data": {"bar": 1},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "required default validation",
+ "schema": {
+ "properties": {
+ "foo": {}
+ }
+ },
+ "tests": [
+ {
+ "description": "not required by default",
+ "data": {},
+ "valid": true
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "schema": {
+ "id": "http://json-schema.org/draft-04/schema#",
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Core schema meta-schema",
+ "definitions": {
+ "schemaArray": {
+ "type": "array",
+ "minItems": 1,
+ "items": { "$ref": "#" }
+ },
+ "positiveInteger": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "positiveIntegerDefault0": {
+ "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
+ },
+ "simpleTypes": {
+ "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
+ },
+ "stringArray": {
+ "type": "array",
+ "items": { "type": "string" },
+ "minItems": 1,
+ "uniqueItems": true
+ }
+ },
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uri"
+ },
+ "$schema": {
+ "type": "string",
+ "format": "uri"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "default": {},
+ "multipleOf": {
+ "type": "number",
+ "minimum": 0,
+ "exclusiveMinimum": true
+ },
+ "maximum": {
+ "type": "number"
+ },
+ "exclusiveMaximum": {
+ "type": "boolean",
+ "default": false
+ },
+ "minimum": {
+ "type": "number"
+ },
+ "exclusiveMinimum": {
+ "type": "boolean",
+ "default": false
+ },
+ "maxLength": { "$ref": "#/definitions/positiveInteger" },
+ "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
+ "pattern": {
+ "type": "string",
+ "format": "regex"
+ },
+ "additionalItems": {
+ "anyOf": [
+ { "type": "boolean" },
+ { "$ref": "#" }
+ ],
+ "default": {}
+ },
+ "items": {
+ "anyOf": [
+ { "$ref": "#" },
+ { "$ref": "#/definitions/schemaArray" }
+ ],
+ "default": {}
+ },
+ "maxItems": { "$ref": "#/definitions/positiveInteger" },
+ "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
+ "uniqueItems": {
+ "type": "boolean",
+ "default": false
+ },
+ "maxProperties": { "$ref": "#/definitions/positiveInteger" },
+ "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
+ "required": { "$ref": "#/definitions/stringArray" },
+ "additionalProperties": {
+ "anyOf": [
+ { "type": "boolean" },
+ { "$ref": "#" }
+ ],
+ "default": {}
+ },
+ "definitions": {
+ "type": "object",
+ "additionalProperties": { "$ref": "#" },
+ "default": {}
+ },
+ "properties": {
+ "type": "object",
+ "additionalProperties": { "$ref": "#" },
+ "default": {}
+ },
+ "patternProperties": {
+ "type": "object",
+ "additionalProperties": { "$ref": "#" },
+ "default": {}
+ },
+ "dependencies": {
+ "type": "object",
+ "additionalProperties": {
+ "anyOf": [
+ { "$ref": "#" },
+ { "$ref": "#/definitions/stringArray" }
+ ]
+ }
+ },
+ "enum": {
+ "type": "array",
+ "minItems": 1,
+ "uniqueItems": true
+ },
+ "type": {
+ "anyOf": [
+ { "$ref": "#/definitions/simpleTypes" },
+ {
+ "type": "array",
+ "items": { "$ref": "#/definitions/simpleTypes" },
+ "minItems": 1,
+ "uniqueItems": true
+ }
+ ]
+ },
+ "allOf": { "$ref": "#/definitions/schemaArray" },
+ "anyOf": { "$ref": "#/definitions/schemaArray" },
+ "oneOf": { "$ref": "#/definitions/schemaArray" },
+ "not": { "$ref": "#" }
+ },
+ "dependencies": {
+ "exclusiveMaximum": [ "maximum" ],
+ "exclusiveMinimum": [ "minimum" ]
+ },
+ "default": {}
+ }
+
+ }]
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Docson Test</title>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="../css/docson.css">
+ <script src="../lib/require.js"></script></head>
+ <style>
+ body {
+ font-family: verdana, helvetica;
+ }
+ </style>
+</head>
+<body>
+<script charset="utf-8">
+ var tests = [ "invoice$Invoice", "enum", "schema","additionalProperties", "address", "fstab", "basic", "not", "oneOf", "anyOf", "allOf", "example2", "properties", "ref"]
+ require.config({ baseUrl: ".."});
+ require(["docson", "lib/jquery"], function(docson) {
+ docson.templateBaseUrl="../templates";
+ $(function() {
+ $.each(tests, function(k, test) {
+ var block = $("<div/>");
+ var segments = test.split("$");
+ $("body").append("<h2>"+segments[0]+"</h2>");
+ $("body").append(block);
+ $.get(segments[0]+".json").done(function(items) {
+ $.each(items, function(k, item) {
+ var element = $("<div/>");
+ block.append(element);
+ if(!item.schema.description) {
+ item.schema.description = item.description;
+ }
+ docson.doc(element, item.schema, segments[1]);
+ });
+ });
+ });
+ });
+ });
+</script>
+</body>
+</html>
--- /dev/null
+[
+ {
+ "description": "integer type matches integers",
+ "schema": {"type": "integer"},
+ "tests": [
+ {
+ "description": "an integer is an integer",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "a float is not an integer",
+ "data": 1.1,
+ "valid": false
+ },
+ {
+ "description": "a string is not an integer",
+ "data": "foo",
+ "valid": false
+ },
+ {
+ "description": "an object is not an integer",
+ "data": {},
+ "valid": false
+ },
+ {
+ "description": "an array is not an integer",
+ "data": [],
+ "valid": false
+ },
+ {
+ "description": "a boolean is not an integer",
+ "data": true,
+ "valid": false
+ },
+ {
+ "description": "null is not an integer",
+ "data": null,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "number type matches numbers",
+ "schema": {"type": "number"},
+ "tests": [
+ {
+ "description": "an integer is a number",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "a float is a number",
+ "data": 1.1,
+ "valid": true
+ },
+ {
+ "description": "a string is not a number",
+ "data": "foo",
+ "valid": false
+ },
+ {
+ "description": "an object is not a number",
+ "data": {},
+ "valid": false
+ },
+ {
+ "description": "an array is not a number",
+ "data": [],
+ "valid": false
+ },
+ {
+ "description": "a boolean is not a number",
+ "data": true,
+ "valid": false
+ },
+ {
+ "description": "null is not a number",
+ "data": null,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "string type matches strings",
+ "schema": {"type": "string"},
+ "tests": [
+ {
+ "description": "1 is not a string",
+ "data": 1,
+ "valid": false
+ },
+ {
+ "description": "a float is not a string",
+ "data": 1.1,
+ "valid": false
+ },
+ {
+ "description": "a string is a string",
+ "data": "foo",
+ "valid": true
+ },
+ {
+ "description": "an object is not a string",
+ "data": {},
+ "valid": false
+ },
+ {
+ "description": "an array is not a string",
+ "data": [],
+ "valid": false
+ },
+ {
+ "description": "a boolean is not a string",
+ "data": true,
+ "valid": false
+ },
+ {
+ "description": "null is not a string",
+ "data": null,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "object type matches objects",
+ "schema": {"type": "object"},
+ "tests": [
+ {
+ "description": "an integer is not an object",
+ "data": 1,
+ "valid": false
+ },
+ {
+ "description": "a float is not an object",
+ "data": 1.1,
+ "valid": false
+ },
+ {
+ "description": "a string is not an object",
+ "data": "foo",
+ "valid": false
+ },
+ {
+ "description": "an object is an object",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "an array is not an object",
+ "data": [],
+ "valid": false
+ },
+ {
+ "description": "a boolean is not an object",
+ "data": true,
+ "valid": false
+ },
+ {
+ "description": "null is not an object",
+ "data": null,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "array type matches arrays",
+ "schema": {"type": "array"},
+ "tests": [
+ {
+ "description": "an integer is not an array",
+ "data": 1,
+ "valid": false
+ },
+ {
+ "description": "a float is not an array",
+ "data": 1.1,
+ "valid": false
+ },
+ {
+ "description": "a string is not an array",
+ "data": "foo",
+ "valid": false
+ },
+ {
+ "description": "an object is not an array",
+ "data": {},
+ "valid": false
+ },
+ {
+ "description": "an array is not an array",
+ "data": [],
+ "valid": true
+ },
+ {
+ "description": "a boolean is not an array",
+ "data": true,
+ "valid": false
+ },
+ {
+ "description": "null is not an array",
+ "data": null,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "boolean type matches booleans",
+ "schema": {"type": "boolean"},
+ "tests": [
+ {
+ "description": "an integer is not a boolean",
+ "data": 1,
+ "valid": false
+ },
+ {
+ "description": "a float is not a boolean",
+ "data": 1.1,
+ "valid": false
+ },
+ {
+ "description": "a string is not a boolean",
+ "data": "foo",
+ "valid": false
+ },
+ {
+ "description": "an object is not a boolean",
+ "data": {},
+ "valid": false
+ },
+ {
+ "description": "an array is not a boolean",
+ "data": [],
+ "valid": false
+ },
+ {
+ "description": "a boolean is not a boolean",
+ "data": true,
+ "valid": true
+ },
+ {
+ "description": "null is not a boolean",
+ "data": null,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "null type matches only the null object",
+ "schema": {"type": "null"},
+ "tests": [
+ {
+ "description": "an integer is not null",
+ "data": 1,
+ "valid": false
+ },
+ {
+ "description": "a float is not null",
+ "data": 1.1,
+ "valid": false
+ },
+ {
+ "description": "a string is not null",
+ "data": "foo",
+ "valid": false
+ },
+ {
+ "description": "an object is not null",
+ "data": {},
+ "valid": false
+ },
+ {
+ "description": "an array is not null",
+ "data": [],
+ "valid": false
+ },
+ {
+ "description": "a boolean is not null",
+ "data": true,
+ "valid": false
+ },
+ {
+ "description": "null is null",
+ "data": null,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "multiple types can be specified in an array",
+ "schema": {"type": ["integer", "string"]},
+ "tests": [
+ {
+ "description": "an integer is valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "a string is valid",
+ "data": "foo",
+ "valid": true
+ },
+ {
+ "description": "a float is invalid",
+ "data": 1.1,
+ "valid": false
+ },
+ {
+ "description": "an object is invalid",
+ "data": {},
+ "valid": false
+ },
+ {
+ "description": "an array is invalid",
+ "data": [],
+ "valid": false
+ },
+ {
+ "description": "a boolean is invalid",
+ "data": true,
+ "valid": false
+ },
+ {
+ "description": "null is invalid",
+ "data": null,
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "description": "uniqueItems validation",
+ "schema": {"uniqueItems": true},
+ "tests": [
+ {
+ "description": "unique array of integers is valid",
+ "data": [1, 2],
+ "valid": true
+ },
+ {
+ "description": "non-unique array of integers is invalid",
+ "data": [1, 1],
+ "valid": false
+ },
+ {
+ "description": "numbers are unique if mathematically unequal",
+ "data": [1.0, 1.00, 1],
+ "valid": false
+ },
+ {
+ "description": "unique array of objects is valid",
+ "data": [{"foo": "bar"}, {"foo": "baz"}],
+ "valid": true
+ },
+ {
+ "description": "non-unique array of objects is invalid",
+ "data": [{"foo": "bar"}, {"foo": "bar"}],
+ "valid": false
+ },
+ {
+ "description": "unique array of nested objects is valid",
+ "data": [
+ {"foo": {"bar" : {"baz" : true}}},
+ {"foo": {"bar" : {"baz" : false}}}
+ ],
+ "valid": true
+ },
+ {
+ "description": "non-unique array of nested objects is invalid",
+ "data": [
+ {"foo": {"bar" : {"baz" : true}}},
+ {"foo": {"bar" : {"baz" : true}}}
+ ],
+ "valid": false
+ },
+ {
+ "description": "unique array of arrays is valid",
+ "data": [["foo"], ["bar"]],
+ "valid": true
+ },
+ {
+ "description": "non-unique array of arrays is invalid",
+ "data": [["foo"], ["foo"]],
+ "valid": false
+ },
+ {
+ "description": "1 and true are unique",
+ "data": [1, true],
+ "valid": true
+ },
+ {
+ "description": "0 and false are unique",
+ "data": [0, false],
+ "valid": true
+ },
+ {
+ "description": "unique heterogeneous types are valid",
+ "data": [{}, [1], true, null, 1],
+ "valid": true
+ },
+ {
+ "description": "non-unique heterogeneous types are invalid",
+ "data": [{}, [1], true, null, {}, 1],
+ "valid": false
+ }
+ ]
+ }
+]
--- /dev/null
+/*
+ * Copyright 2013 Laurent Bovet <laurent.bovet@windmaster.ch>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var scripts = document.getElementsByTagName('script');
+var script = scripts[ scripts.length - 1 ];
+
+if (script.attributes["data-schema"]) {
+ var docson;
+ if (script.attributes["data-docson"]) {
+ docson = script.attributes["data-docson"].value;
+ } else {
+ docson = script.src.replace("widget.js", "index.html");
+ }
+ document.write("<iframe id='" + script.attributes["data-schema"].value +
+ "' style='padding: 0; border: 0; width:100%; background: transparent' src='" +
+ docson + "#" +
+ script.attributes["data-schema"].value + "'></iframe>");
+ function receiveMessage(event) {
+ console.log("<", event)
+ if (event.data.id && event.data.id == "docson") {
+ var frame = document.getElementById(event.data.url);
+ if(event.data.action == "resized") {
+ frame.height = event.data.height + 18;
+ }
+ if(event.data.action == "ready") {
+ console.log(frame.parentNode)
+ frame.contentWindow.postMessage({ id: "docson", font: window.getComputedStyle(frame.parentNode).fontFamily}, "*");
+ }
+ }
+
+ }
+ window.addEventListener("message", receiveMessage, false);
+} else {
+ alert("<p style='color:red'>Missing data-schema (url to schema)</p>")
+}
--- /dev/null
+{"$schema":"http://json-schema.org/draft-04/schema#","id":"http://jsonschema.net","type":"object","properties":{"seqs":{"id":"http://jsonschema.net/seqs","type":"array","items":{"id":"http://jsonschema.net/seqs/0","type":"object","properties":{"name":{"id":"http://jsonschema.net/seqs/0/name","type":"string","description":"Sequence name"},"start":{"id":"http://jsonschema.net/seqs/0/start","type":"integer","description":"Start residue position"},"svid":{"id":"http://jsonschema.net/seqs/0/svid","type":"string","description":"Serial version id for sequence object"},"end":{"id":"http://jsonschema.net/seqs/0/end","type":"integer","description":"End residue position"},"id":{"id":"http://jsonschema.net/seqs/0/id","type":"string","description":"Sequence unique identifier"},"seq":{"id":"http://jsonschema.net/seqs/0/seq","type":"string","description":"Sequence Residues"},"order":{"id":"http://jsonschema.net/seqs/0/order","type":"integer","description":"Sequence order in an alignment space"}},"required":["name","start","svid","end","id","seq"]},"required":["0"],"description":"Sequences in the Alignemnt","minItems":"1","maxItems":"*"},"appSettings":{"id":"http://jsonschema.net/appSettings","type":"object","properties":{"globalColorScheme":{"id":"http://jsonschema.net/appSettings/globalColorScheme","type":"string","description":"Global colour schem for the alignment"},"webStartUrl":{"id":"http://jsonschema.net/appSettings/webStartUrl","type":"string","description":"Jalview specific setting which points to a url for launching Jalview"},"application":{"id":"http://jsonschema.net/appSettings/application","type":"string","description":"Application which generated the Json"},"showSeqFeatures":{"id":"http://jsonschema.net/appSettings/showSeqFeatures","type":"string","description":"Determines if sequence features are visible or not"},"version":{"id":"http://jsonschema.net/appSettings/version","type":"string","description":"Verion of the application which generated the JSON"},"hiddenCols":{"id":"http://jsonschema.net/appSettings/hiddenCols","type":"string","description":"Delimited lists of hidden colums ranges i.e [2-3,5-5,11-23]"}},"description":"Application specific settings"},"seqGroups":{"id":"http://jsonschema.net/seqGroups","type":"array","items":[{"id":"http://jsonschema.net/seqGroups/0","type":"object","properties":{"displayText":{"id":"http://jsonschema.net/seqGroups/0/displayText","type":"boolean","description":"Determines if the texts of the group is displayed or not"},"startRes":{"id":"http://jsonschema.net/seqGroups/0/startRes","type":"integer","description":"Start residue position for a given group"},"groupName":{"id":"http://jsonschema.net/seqGroups/0/groupName","type":"string","description":"Group name"},"endRes":{"id":"http://jsonschema.net/seqGroups/0/endRes","type":"integer","description":"End residue position for a given group"},"colourText":{"id":"http://jsonschema.net/seqGroups/0/colourText","type":"boolean","description":"Determines if the Residues text for the group is coloured"},"seqsHash":{"id":"http://jsonschema.net/seqGroups/0/seqsHash","type":"array","items":[],"minItems":"0","maxItems":"*","description":"The id's of the sequences which belongs to the group"},"svid":{"id":"http://jsonschema.net/seqGroups/0/svid","type":"string","description":"Serial version id for a given group"},"showNonconserved":{"id":"http://jsonschema.net/seqGroups/0/showNonconserved","type":"boolean","description":"Determines if non conserved regions of a group is shown or not"},"colourScheme":{"id":"http://jsonschema.net/seqGroups/0/colourScheme","type":"string","description":"Colour Scheme for the sequence group"},"displayBoxes":{"id":"http://jsonschema.net/seqGroups/0/displayBoxes","type":"boolean","description":"Determines if the group border should be visible or not"}}}],"description":"Sequence groups in the Alignment","minItems":"0","maxItems":"*"},"alignAnnotation":{"id":"http://jsonschema.net/alignAnnotation","type":"array","items":{"id":"http://jsonschema.net/alignAnnotation/0","type":"object","properties":{"svid":{"id":"http://jsonschema.net/alignAnnotation/0/svid","type":"string","description":"Serial version id for the annotation object"},"annotations":{"id":"http://jsonschema.net/alignAnnotation/0/annotations","type":"array","items":[{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0","type":"object","properties":{"displayCharacter":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0/displayCharacter","type":"string","description":"Display character to denote the given annotation"},"value":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0/value","type":"integer","description":"Value of the annotation"},"secondaryStructure":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/0/secondaryStructure","type":"string","description":"Secondary structure symbol for the given annotation"}}},{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1","type":"object","properties":{"displayCharacter":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1/displayCharacter","type":"string"},"value":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1/value","type":"integer"},"secondaryStructure":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/1/secondaryStructure","type":"string"}}},{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2","type":"object","properties":{"displayCharacter":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2/displayCharacter","type":"string"},"value":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2/value","type":"integer"},"secondaryStructure":{"id":"http://jsonschema.net/alignAnnotation/0/annotations/2/secondaryStructure","type":"string"}}}]},"description":{"id":"http://jsonschema.net/alignAnnotation/0/description","type":"string","description":"Description of the Alignment Annotation"},"label":{"id":"http://jsonschema.net/alignAnnotation/0/label","type":"string","description":"Label for the Annotation"}}},"description":"Alignment Annotations","minItems":"0","maxItems":"*"},"svid":{"id":"http://jsonschema.net/svid","type":"string","description":"Serial version id"},"seqFeatures":{"id":"http://jsonschema.net/seqFeatures","type":"array","items":{"id":"http://jsonschema.net/seqFeatures/0","type":"object","properties":{"fillColor":{"id":"http://jsonschema.net/seqFeatures/0/fillColor","type":"string","description":"Fill colour"},"score":{"id":"http://jsonschema.net/seqFeatures/0/score","type":"integer","description":"Score"},"sequenceRef":{"id":"http://jsonschema.net/seqFeatures/0/sequenceRef","type":"string","description":"Reference to the Sequence in the alignement (More like a foreign key)"},"featureGroup":{"id":"http://jsonschema.net/seqFeatures/0/featureGroup","type":"string","description":"Feature Group"},"svid":{"id":"http://jsonschema.net/seqFeatures/0/svid","type":"string","description":"Serial version id for the SeqFeature object"},"description":{"id":"http://jsonschema.net/seqFeatures/0/description","type":"string","description":"Description of Feature"},"xStart":{"id":"http://jsonschema.net/seqFeatures/0/xStart","type":"integer","description":"Start residue position for the sequence feature"},"xEnd":{"id":"http://jsonschema.net/seqFeatures/0/xEnd","type":"integer","description":"End residue position for the sequence feature"},"type":{"id":"http://jsonschema.net/seqFeatures/0/type","type":"string","description":"The name of the SequenceFeature"}}},"minItems":"0","maxItems":"*","description":"Sequence Features within the alignment"}},"required":["seqs","appSettings","seqGroups","alignAnnotation","svid","seqFeatures"]}
\ No newline at end of file
package ext.edu.ucsf.rbvi.strucviz2;
+import jalview.ws.HttpClientUtils;
+
import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
import ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads;
-import jalview.ws.HttpClientUtils;
-
/**
* This object maintains the Chimera communication information.
*/
for (String chimeraPath : chimeraPaths)
{
File path = new File(chimeraPath);
- // enable the next line to simulate Chimera not installed
- // File path = new File(chimeraPath + "x");
+ // uncomment the next line to simulate Chimera not installed
+ // path = new File(chimeraPath + "x");
if (!path.canExecute())
{
error += "File '" + path + "' does not exist.\n";
{
List<String> args = new ArrayList<String>();
args.add(chimeraPath);
+ // shows Chimera output window but suppresses REST responses:
+ // args.add("--debug");
args.add("--start");
args.add("RESTServer");
ProcessBuilder pb = new ProcessBuilder(args);
// TODO: [Optional] Check Chimera version and show a warning if below 1.8
// Ask Chimera to give us updates
// startListening(); // later - see ChimeraListener
- return true;
+ return (chimeraRestPort > 0);
}
// Tell the user that Chimera could not be started because of an error
InputStream readChan = chimera.getInputStream();
BufferedReader lineReader = new BufferedReader(new InputStreamReader(
readChan));
- String response = null;
+ StringBuilder responses = new StringBuilder();
try
{
- // expect: REST server on host 127.0.0.1 port port_number
- response = lineReader.readLine();
- String [] tokens = response.split(" ");
- if (tokens.length == 7 && "port".equals(tokens[5])) {
- port = Integer.parseInt(tokens[6]);
- logger.info("Chimera REST service listening on port "
- + chimeraRestPort);
+ String response = lineReader.readLine();
+ while (response != null)
+ {
+ responses.append("\n" + response);
+ // expect: REST server on host 127.0.0.1 port port_number
+ if (response.startsWith("REST server"))
+ {
+ String[] tokens = response.split(" ");
+ if (tokens.length == 7 && "port".equals(tokens[5]))
+ {
+ port = Integer.parseInt(tokens[6]);
+ break;
+ }
+ }
+ response = lineReader.readLine();
}
} catch (Exception e)
{
- logger.error("Failed to get REST port number from " + response + ": "
+ logger.error("Failed to get REST port number from " + responses
+ + ": "
+ e.getMessage());
} finally
{
{
}
}
+ if (port == 0)
+ {
+ System.err
+ .println("Failed to start Chimera with REST service, response was: "
+ + responses);
+ }
+ logger.info("Chimera REST service listening on port " + chimeraRestPort);
return port;
}
// array holds #seqs, #ungapped, then codon counts indexed by codon
final int[] codonCounts = (int[]) hci.get(PROFILE);
int totalCount = 0;
- StringBuilder mouseOver = new StringBuilder(32);
/*
* First pass - get total count and find the highest
*/
/*
- * Scan sorted array backwards for most frequent values first.
+ * Scan sorted array backwards for most frequent values first. Show
+ * repeated values compactly.
*/
+ StringBuilder mouseOver = new StringBuilder(32);
+ StringBuilder samePercent = new StringBuilder();
+ String percent = null;
+ String lastPercent = null;
+ Format fmt = getPercentageFormat(nseqs);
+
for (int j = codons.length - 1; j >= 0; j--)
{
int codonCount = sortedCodonCounts[j];
if (codonCount == 0)
{
+ /*
+ * remaining codons are 0% - ignore, but finish off the last one if
+ * necessary
+ */
+ if (samePercent.length() > 0)
+ {
+ mouseOver.append(samePercent).append(": ").append(percent)
+ .append("% ");
+ }
break;
}
int codonEncoded = codons[j];
final int pct = codonCount * 100 / totalCount;
String codon = String
.valueOf(CodingUtils.decodeCodon(codonEncoded));
- Format fmt = getPercentageFormat(nseqs);
- String formatted = fmt == null ? Integer.toString(pct) : fmt
+ percent = fmt == null ? Integer.toString(pct) : fmt
.form(pct);
if (showProfileLogo || codonCount == modalCodonCount)
{
- mouseOver.append(codon).append(": ").append(formatted)
- .append("% ");
+ if (percent.equals(lastPercent) && j > 0)
+ {
+ samePercent.append(samePercent.length() == 0 ? "" : ", ");
+ samePercent.append(codon);
+ }
+ else
+ {
+ if (samePercent.length() > 0)
+ {
+ mouseOver.append(samePercent).append(": ")
+ .append(lastPercent)
+ .append("% ");
+ }
+ samePercent.setLength(0);
+ samePercent.append(codon);
+ }
+ lastPercent = percent;
}
}
aa.visible = visible;
}
alignPanel.validateAnnotationDimensions(true);
+ validate();
+ repaint();
}
private void setAnnotationSortOrder(SequenceAnnotationOrder order)
*/
package jalview.appletgui;
+import jalview.analysis.AnnotationSorter;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.bin.JalviewLite;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SequenceI;
+import jalview.structure.StructureSelectionManager;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ComponentEvent;
import java.util.List;
-import jalview.analysis.AnnotationSorter;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.JalviewLite;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
-import jalview.datamodel.SequenceI;
-import jalview.structure.StructureSelectionManager;
-
public class AlignmentPanel extends Panel implements AdjustmentListener,
AlignmentViewPanel
{
}
/**
- * calculate the annotation dimensions and refresh slider values accordingly.
- * need to do repaints/notifys afterwards.
+ * Calculate the annotation dimensions and refresh slider values accordingly.
+ * Need to do repaints/notifys afterwards.
*/
protected void validateAnnotationDimensions(boolean adjustPanelHeight)
{
- boolean modified = false;
- int height = av.calcPanelHeight();
- int minsize = 0;
- if (hscroll.isVisible())
- {
- height += (minsize = hscroll.getPreferredSize().height);
- }
- if (apvscroll.isVisible())
- {
- minsize += apvscroll.getPreferredSize().height;
- }
- int mheight = height;
- Dimension d = sequenceHolderPanel.getSize(), e = idPanel.getSize();
- int seqandannot = d.height - scalePanelHolder.getSize().height;
+ int rowHeight = av.getCharHeight();
+ int alignmentHeight = rowHeight * av.getAlignment().getHeight();
+ int annotationHeight = av.calcPanelHeight();
+
+ int mheight = annotationHeight;
+ Dimension d = sequenceHolderPanel.getSize();
+
+ int availableHeight = d.height - scalePanelHolder.getHeight();
if (adjustPanelHeight)
{
- // NOTE: this logic is different in the application. Need a better
- // algorithm to define behaviour
- // sets initial preferred height
- // try and set height according to alignment
- float sscaling = (float) ((av.getCharHeight() * av.getAlignment()
- .getHeight()) / (1.0 * mheight));
- if (sscaling > 0.5)
- {
- // if the alignment is too big then
- // default is 0.5 split
- height = seqandannot / 2;
- }
- else
+ /*
+ * If not enough vertical space, maximize annotation height while keeping
+ * at least two rows of alignment visible
+ */
+ if (annotationHeight + alignmentHeight > availableHeight)
{
- // otherwise just set the panel so that one row of sequence is visible
- height = -av.getCharHeight() * 1
- + (int) (seqandannot * (1 - sscaling));
+ annotationHeight = Math.min(annotationHeight, availableHeight - 2
+ * rowHeight);
}
}
else
{
// maintain same window layout whilst updating sliders
- height = annotationPanelHolder.getSize().height;
+ annotationHeight = annotationPanelHolder.getSize().height;
}
- if (seqandannot - height < 5)
+ if (availableHeight - annotationHeight < 5)
{
- height = seqandannot;
+ annotationHeight = availableHeight;
}
- annotationPanel.setSize(new Dimension(d.width, height));
- alabels.setSize(new Dimension(e.width, height));
- annotationSpaceFillerHolder.setSize(new Dimension(e.width, height));
- annotationPanelHolder.setSize(new Dimension(d.width, height));
+
+ annotationPanel.setSize(new Dimension(d.width, annotationHeight));
+ annotationPanelHolder.setSize(new Dimension(d.width, annotationHeight));
// seqPanelHolder.setSize(d.width, seqandannot - height);
seqPanel.seqCanvas
.setSize(d.width, seqPanel.seqCanvas.getSize().height);
+
+ Dimension e = idPanel.getSize();
+ alabels.setSize(new Dimension(e.width, annotationHeight));
+ annotationSpaceFillerHolder.setSize(new Dimension(e.width,
+ annotationHeight));
+
int s = apvscroll.getValue();
- if (s > mheight - height)
+ if (s > mheight - annotationHeight)
{
s = 0;
}
- apvscroll.setValues(s, height, 0, mheight);
+ apvscroll.setValues(s, annotationHeight, 0, mheight);
annotationPanel.setScrollOffset(apvscroll.getValue(), false);
alabels.setScrollOffset(apvscroll.getValue(), false);
}
desktop.checkForNews();
}
- BioJsHTMLOutput.updateBioJS();
+ if (!isHeadlessMode())
+ {
+ BioJsHTMLOutput.updateBioJS();
+ }
String file = null, protocol = null, format = null, data = null;
- jalview.io.FileLoader fileLoader = new jalview.io.FileLoader();
+ jalview.io.FileLoader fileLoader = new jalview.io.FileLoader(!headless);
Vector getFeatures = null; // vector of das source nicknames to fetch
// features from
// loading is done.
}
else if (format.equalsIgnoreCase("eps"))
{
- System.out.println("Creating EPS file: " + file);
- af.createEPS(new java.io.File(file));
+ File outputFile = new java.io.File(file);
+ System.out.println("Creating EPS file: "
+ + outputFile.getAbsolutePath());
+ af.createEPS(outputFile);
continue;
}
}
return ff;
}
+
+ public static boolean isHeadlessMode()
+ {
+ String isheadless = System.getProperty("java.awt.headless");
+ if (isheadless != null && isheadless.equalsIgnoreCase("true"))
+ {
+ return true;
+ }
+ return false;
+ }
}
/**
return queued == 0 && running == 0;
}
-};
+}
*/
package jalview.datamodel;
+import jalview.analysis.AlignSeq;
+import jalview.util.StringUtils;
+
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import fr.orsay.lri.varna.models.rna.RNA;
-import jalview.analysis.AlignSeq;
-import jalview.util.StringUtils;
-
/**
*
* Implements the SequenceI interface for a char[] based sequence object.
public void deleteChars(int i, int j)
{
int newstart = start, newend = end;
- if (i >= sequence.length)
+ if (i >= sequence.length || i < 0)
{
return;
}
*/
package jalview.datamodel.xdb.embl;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Vector;
-
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.datamodel.FeatureProperties;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
+import java.util.Hashtable;
+import java.util.Map.Entry;
+import java.util.Vector;
+
/**
* Data model for one entry returned from an EMBL query, as marshalled by a
* Castor binding file
boolean noPeptide, String sourceDb)
{ // TODO: ensure emblEntry.getSequences behaves correctly for returning all
// cases of noNa and noPeptide
- Vector seqs = new Vector();
+ Vector<SequenceI> seqs = new Vector<SequenceI>();
Sequence dna = null;
if (!noNa)
{
// TODO: transform EMBL Database refs to canonical form
if (dbRefs != null)
{
- for (Iterator i = dbRefs.iterator(); i.hasNext(); dna
- .addDBRef((DBRefEntry) i.next()))
+ for (DBRefEntry dbref : dbRefs)
{
- ;
+ dna.addDBRef(dbref);
}
}
}
try
{
- for (Iterator i = features.iterator(); i.hasNext();)
+ for (EmblFeature feature: features)
{
- EmblFeature feature = (EmblFeature) i.next();
if (!noNa)
{
- if (feature.dbRefs != null && feature.dbRefs.size() > 0)
+ if (feature.dbRefs != null)
{
- for (Iterator dbr = feature.dbRefs.iterator(); dbr.hasNext(); dna
- .addDBRef((DBRefEntry) dbr.next()))
+ for (DBRefEntry dbref : feature.dbRefs)
{
- ;
+ dna.addDBRef(dbref);
}
}
}
else
{
// General feature type.
+ // TODO this is just duplicated code ??
if (!noNa)
{
- if (feature.dbRefs != null && feature.dbRefs.size() > 0)
+ if (feature.dbRefs != null)
{
- for (Iterator dbr = feature.dbRefs.iterator(); dbr.hasNext(); dna
- .addDBRef((DBRefEntry) dbr.next()))
+ for (DBRefEntry dbref : feature.dbRefs)
{
- ;
+ dna.addDBRef(dbref);
}
}
}
SequenceI[] sqs = new SequenceI[seqs.size()];
for (int i = 0, j = seqs.size(); i < j; i++)
{
- sqs[i] = (SequenceI) seqs.elementAt(i);
+ sqs[i] = seqs.elementAt(i);
seqs.set(i, null);
}
return sqs;
* flag for generation of Peptide sequence objects
*/
private void parseCodingFeature(EmblFeature feature, String sourceDb,
- Vector seqs, Sequence dna, boolean noPeptide)
+ Vector<SequenceI> seqs, Sequence dna, boolean noPeptide)
{
boolean isEmblCdna = sourceDb.equals(DBRefSource.EMBLCDS);
// extract coding region(s)
jalview.datamodel.Mapping map = null;
int[] exon = null;
- if (feature.locations != null && feature.locations.size() > 0)
+ if (feature.locations != null)
{
- for (Enumeration locs = feature.locations.elements(); locs
- .hasMoreElements();)
+ for (EmblFeatureLocations loc : feature.locations)
{
- EmblFeatureLocations loc = (EmblFeatureLocations) locs
- .nextElement();
int[] se = loc.getElementRanges(accession);
if (exon == null)
{
String prseq = null;
String prname = new String();
String prid = null;
- Hashtable vals = new Hashtable();
+ Hashtable<String, String> vals = new Hashtable<String, String>();
int prstart = 1;
// get qualifiers
- if (feature.getQualifiers() != null
- && feature.getQualifiers().size() > 0)
+ if (feature.getQualifiers() != null)
{
- for (Iterator quals = feature.getQualifiers().iterator(); quals
- .hasNext();)
+ for (Qualifier q : feature.getQualifiers())
{
- Qualifier q = (Qualifier) quals.next();
- if (q.getName().equals("translation"))
+ String qname = q.getName();
+ if (qname.equals("translation"))
{
- StringBuffer prsq = new StringBuffer(q.getValues()[0]);
+ StringBuilder prsq = new StringBuilder(q.getValues()[0]);
int p = prsq.indexOf(" ");
while (p > -1)
{
prsq = null;
}
- else if (q.getName().equals("protein_id"))
+ else if (qname.equals("protein_id"))
{
prid = q.getValues()[0];
}
- else if (q.getName().equals("codon_start"))
+ else if (qname.equals("codon_start"))
{
prstart = Integer.parseInt(q.getValues()[0]);
}
- else if (q.getName().equals("product"))
+ else if (qname.equals("product"))
{
prname = q.getValues()[0];
}
{
// throw anything else into the additional properties hash
String[] s = q.getValues();
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
if (s != null)
{
for (int i = 0; i < s.length; i++)
sb.append("\n");
}
}
- vals.put(q.getName(), sb.toString());
+ vals.put(qname, sb.toString());
}
}
}
Sequence product = null;
DBRefEntry protEMBLCDS = null;
exon = adjustForPrStart(prstart, exon);
- boolean noProteinDbref=true;
-
+ boolean noProteinDbref = true;
+
if (prseq != null && prname != null && prid != null)
{
// extract proteins.
protEMBLCDS = new DBRefEntry(pcdnaref);
protEMBLCDS.setSource(DBRefSource.EMBLCDSProduct);
product.addDBRef(protEMBLCDS);
-
- }
-
+
+ }
+
}
}
// add cds feature to dna seq - this may include the stop codon
sf.setEnd(exon[xint + 1]);
sf.setType(feature.getName());
sf.setFeatureGroup(sourceDb);
- sf.setDescription("Exon " + (1 + xint / 2)
- + " for protein '" + prname + "' EMBLCDS:" + prid);
+ sf.setDescription("Exon " + (1 + xint / 2) + " for protein '"
+ + prname + "' EMBLCDS:" + prid);
sf.setValue(FeatureProperties.EXONPOS, new Integer(1 + xint));
sf.setValue(FeatureProperties.EXONPRODUCT, prname);
- if (vals != null && vals.size() > 0)
+ if (vals != null)
{
- Enumeration kv = vals.keys();
- while (kv.hasMoreElements())
+ for (Entry<String, String> val : vals.entrySet())
{
- Object key = kv.nextElement();
- if (key != null)
- {
- sf.setValue(key.toString(), vals.get(key));
- }
+ sf.setValue(val.getKey(), val.getValue());
}
}
dna.addSequenceFeature(sf);
}
}
// add dbRefs to sequence
- if (feature.dbRefs != null && feature.dbRefs.size() > 0)
+ if (feature.dbRefs != null)
{
- for (Iterator dbr = feature.dbRefs.iterator(); dbr.hasNext();)
+ for (DBRefEntry ref : feature.dbRefs)
{
- DBRefEntry ref = (DBRefEntry) dbr.next();
ref.setSource(jalview.util.DBRefUtils.getCanonicalName(ref
.getSource()));
// Hard code the kind of protein product accessions that EMBL cite
.setMap(new Mapping(product, map.getMap().getInverse()));
}
product.addDBRef(protEMBLCDS);
-
+
// Add converse mapping reference
if (map != null)
{
package jalview.ext.varna;
-import fr.orsay.lri.varna.models.rna.RNA;
-
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.SequenceI;
+import fr.orsay.lri.varna.models.rna.RNA;
+
/**
* Data bean wrapping the data items that define one RNA view
*/
public final RNA rna;
- // path to a file holding VARNA session state XML
- public final String varnaSession;
-
public RnaModel(String t, AlignmentAnnotation aa, SequenceI s, RNA r,
- boolean g,
- String sessionFile)
+ boolean g)
{
title = t;
ann = aa;
seq = s;
- gapped = g;
rna = r;
- varnaSession = sessionFile;
+ gapped = g;
}
}
\ No newline at end of file
package jalview.gui;
import jalview.api.AlignExportSettingI;
+import jalview.bin.Jalview;
import jalview.jbgui.GAlignExportSettings;
import java.awt.event.ActionEvent;
String alignFileFormat)
{
super(hasHiddenSeq, hasHiddenCols, alignFileFormat);
- if (isShowDialog())
+ if (!Jalview.isHeadlessMode() && isShowDialog())
{
JOptionPane pane = new JOptionPane(null, JOptionPane.DEFAULT_OPTION,
JOptionPane.DEFAULT_OPTION, null, new Object[]
import jalview.api.ViewStyleI;
import jalview.api.analysis.ScoreModelI;
import jalview.bin.Cache;
+import jalview.bin.Jalview;
import jalview.commands.CommandI;
import jalview.commands.EditCommand;
import jalview.commands.EditCommand.Action;
*/
void init()
{
- progressBar = new ProgressBar(this.statusPanel, this.statusBar);
+ if (!Jalview.isHeadlessMode())
+ {
+ progressBar = new ProgressBar(this.statusPanel, this.statusBar);
+ }
avc = new jalview.controller.AlignViewController(this, viewport,
alignPanel);
{
warningMessage("Cannot save file " + fileName + " using format "
+ format, "Alignment output format not supported");
- saveAs_actionPerformed(null);
- // JBPNote need to have a raise_gui flag here
+ if (!Jalview.isHeadlessMode())
+ {
+ saveAs_actionPerformed(null);
+ }
return false;
}
viewport.getSelectionGroup().getEndRes() + groupAdjustment);
}
+ /*
+ * just extend the last slide command if compatible; but not if in
+ * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
+ */
boolean appendHistoryItem = false;
Deque<CommandI> historyList = viewport.getHistoryList();
- if (historyList != null
+ boolean inSplitFrame = getSplitViewContainer() != null;
+ if (!inSplitFrame && historyList != null
&& historyList.size() > 0
&& historyList.peek() instanceof SlideSequencesCommand)
{
public AnnotationPanel(AlignmentPanel ap)
{
- MAC = new jalview.util.Platform().isAMac();
+ MAC = jalview.util.Platform.isAMac();
ToolTipManager.sharedInstance().registerComponent(this);
ToolTipManager.sharedInstance().setInitialDelay(0);
*/
package jalview.gui;
+import jalview.analysis.AlignSeq;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.RnaViewerModel;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.ext.varna.RnaModel;
+import jalview.structure.SecondaryStructureListener;
+import jalview.structure.SelectionListener;
+import jalview.structure.SelectionSource;
+import jalview.structure.StructureSelectionManager;
+import jalview.structure.VamsasSource;
+import jalview.util.Comparison;
+import jalview.util.MessageManager;
+import jalview.util.ShiftList;
+
import java.awt.BorderLayout;
import java.awt.Color;
-import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import javax.swing.JInternalFrame;
import javax.swing.JSplitPane;
import fr.orsay.lri.varna.models.rna.ModeleBase;
import fr.orsay.lri.varna.models.rna.RNA;
-import jalview.analysis.AlignSeq;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.RnaViewerModel;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.ext.varna.RnaModel;
-import jalview.structure.SecondaryStructureListener;
-import jalview.structure.SelectionListener;
-import jalview.structure.SelectionSource;
-import jalview.structure.StructureSelectionManager;
-import jalview.structure.VamsasSource;
-import jalview.util.Comparison;
-import jalview.util.MessageManager;
-import jalview.util.ShiftList;
-
public class AppVarna extends JInternalFrame implements SelectionListener,
SecondaryStructureListener, InterfaceVARNASelectionListener,
VamsasSource
{
- private static final Pattern PAIRS_PATTERN = Pattern
- .compile("[^([{<>}])]");
+ private static final byte[] PAIRS = new byte[]
+ { '(', ')', '[', ']', '{', '}', '<', '>' };
private AppVarnaBinding vab;
setTitle(theTitle);
String gappedTitle = sname + " (with gaps)";
- RnaModel gappedModel = new RnaModel(gappedTitle, aa, seq, null, true,
- null);
+ RnaModel gappedModel = new RnaModel(gappedTitle, aa, seq, null, true);
addModel(gappedModel, gappedTitle);
String trimmedTitle = "trimmed " + sname;
- RnaModel trimmedModel = new RnaModel(trimmedTitle, aa, seq, null,
- false, null);
+ RnaModel trimmedModel = new RnaModel(trimmedTitle, aa, seq, null, false);
addModel(trimmedModel, trimmedTitle);
vab.setSelectedIndex(0);
}
+
/**
* Constructor that links the viewer to a parent panel (but has no structures
* yet - use addModel to add them)
showPanel(true);
}
- public String replaceOddGaps(String oldStr)
- {
- Matcher matcher = PAIRS_PATTERN.matcher(oldStr);
- String newStr = matcher.replaceAll(".");
- return newStr;
- }
-
/**
* Constructs a new RNA model from the given one, without gaps. Also
* calculates and saves a 'shift list'
RNA rnaTrim = new RNA(name);
try
{
- rnaTrim.setRNA(rna.getSeq(), replaceOddGaps(rna.getStructDBN()));
+ String structDBN = rna.getStructDBN(true);
+ rnaTrim.setRNA(rna.getSeq(), replaceOddGaps(structDBN));
} catch (ExceptionUnmatchedClosingParentheses e2)
{
e2.printStackTrace();
String seq = rnaTrim.getSeq();
StringBuilder struc = new StringBuilder(256);
- struc.append(rnaTrim.getStructDBN());
+ struc.append(rnaTrim.getStructDBN(true));
int ofstart = -1;
int sleng = seq.length();
ofstart = i;
}
/*
- * mark base or base pair in the structure with *
+ * mark base or base & pair in the structure with *
*/
if (!rnaTrim.findPair(i).isEmpty())
{
if (rnaModel.seq == sequence)
{
int highlightPos = rnaModel.gapped ? index : position - 1;
- // int highlightPos = index;
- // ShiftList shift = offsets.get(rna);
- // if (shift != null)
- // {
- // System.err.print("Orig pos:" + index);
- // highlightPos = shift.shift(index);
- // System.err.println("\nFinal pos:" + index);
- // }
mouseOverHighlighter.highlightRegion(rna, highlightPos, highlightPos);
vab.updateSelectedRNA(rna);
}
}
/*
- * loaded from project file with Varna session data
- */
- if (model.varnaSession != null)
- {
- try
- {
- FullBackup fromSession = vab.vp.loadSession(model.varnaSession);
- vab.addStructure(fromSession.rna, fromSession.config);
- RNA rna = fromSession.rna;
- // copy the model, but now including the RNA object
- RnaModel newModel = new RnaModel(model.title, model.ann, model.seq,
- rna, model.gapped, model.varnaSession);
- if (!model.gapped)
- {
- registerOffset(rna, buildOffset(model.seq));
- }
- models.put(rna, newModel);
- // capture rna selection state when saved
- selectionHighlighter = new VarnaHighlighter(rna);
- return fromSession.rna;
- } catch (ExceptionLoadingFailed e)
- {
- e.printStackTrace();
- return null;
- }
- }
-
- /*
* opened on request in Jalview session
*/
RNA rna = new RNA(modelName);
rna = trimRNA(rna, modelName);
}
models.put(rna, new RnaModel(modelName, model.ann, model.seq, rna,
- model.gapped, null));
+ model.gapped));
vab.addStructure(rna);
return rna;
}
/**
* Set the selected index in the model selection list
*
- * @param selectedR
+ * @param selectedIndex
*/
public void setInitialSelection(final int selectedIndex)
{
+ /*
+ * empirically it needs a second for Varna/AWT to finish loading/drawing
+ * models for this to work; SwingUtilities.invokeLater _not_ a solution;
+ * explanation and/or better solution welcome!
+ */
+ synchronized (this)
+ {
+ try
+ {
+ wait(1000);
+ } catch (InterruptedException e)
+ {
+ // meh
+ }
+ }
vab.setSelectedIndex(selectedIndex);
}
+
+
+ /**
+ * Add a model with associated Varna session file
+ *
+ * @param rna
+ * @param modelName
+ */
+ public RNA addModelSession(RnaModel model, String modelName,
+ String sessionFile)
+ {
+ if (!model.ann.isValidStruc())
+ {
+ throw new IllegalArgumentException("Invalid RNA structure annotation");
+ }
+
+ try
+ {
+ FullBackup fromSession = vab.vp.loadSession(sessionFile);
+ vab.addStructure(fromSession.rna, fromSession.config);
+ RNA rna = fromSession.rna;
+ // copy the model, but now including the RNA object
+ RnaModel newModel = new RnaModel(model.title, model.ann, model.seq,
+ rna, model.gapped);
+ if (!model.gapped)
+ {
+ registerOffset(rna, buildOffset(model.seq));
+ }
+ models.put(rna, newModel);
+ // capture rna selection state when saved
+ selectionHighlighter = new VarnaHighlighter(rna);
+ return fromSession.rna;
+ } catch (ExceptionLoadingFailed e)
+ {
+ System.err
+ .println("Error restoring Varna session: " + e.getMessage());
+ return null;
+ }
+ }
+
+
+ /**
+ * Replace everything except RNA secondary structure characters with a period
+ *
+ * @param s
+ * @return
+ */
+ public static String replaceOddGaps(String s)
+ {
+ if (s == null)
+ {
+ return null;
+ }
+
+ // this is measured to be 10 times faster than a regex replace
+ boolean changed = false;
+ byte[] bytes = s.getBytes();
+ for (int i = 0; i < bytes.length; i++)
+ {
+ boolean ok = false;
+ // todo check for ((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')) if
+ // wanted also
+ for (int j = 0; !ok && (j < PAIRS.length); j++)
+ {
+ if (bytes[i] == PAIRS[j])
+ {
+ ok = true;
+ }
+ }
+ if (!ok)
+ {
+ bytes[i] = '.';
+ changed = true;
+ }
+ }
+ return changed ? new String(bytes) : s;
+ }
}
*/
package jalview.gui;
+import jalview.datamodel.SequenceI;
+import jalview.ext.varna.JalviewVarnaBinding;
+import jalview.structure.AtomSpec;
+import jalview.util.MessageManager;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import fr.orsay.lri.varna.models.VARNAConfig;
import fr.orsay.lri.varna.models.rna.RNA;
-import jalview.datamodel.SequenceI;
-import jalview.ext.varna.JalviewVarnaBinding;
-import jalview.structure.AtomSpec;
-import jalview.util.MessageManager;
-
public class AppVarnaBinding extends JalviewVarnaBinding
{
public VARNAPanel vp;
- // remove unused (commented out) fields?
- // protected JPanel _tools = new JPanel();
- //
- // private JPanel _input = new JPanel();
- //
- // private JPanel _strPanel = new JPanel();
- //
- // private JTextField _str = new JTextField();
- //
- // private JTextField _seq = new JTextField();
- //
- // private JLabel _strLabel = new JLabel(
- // MessageManager.getString("label.str"));
- //
- // private JButton _updateButton = new JButton(
- // MessageManager.getString("action.update"));
- //
- // private JButton _deleteButton = new JButton(
- // MessageManager.getString("action.delete"));
- //
- // private JButton _duplicateButton = new JButton(
- // MessageManager.getString("action.snapshot"));
- //
protected JPanel _listPanel = new JPanel();
private ReorderableJList _sideList = null;
vp.setBackground(_backgroundColor);
- // MC commented out stuff not added to panel - remove?
- // Font textFieldsFont = Font.decode("MonoSpaced-PLAIN-12");
- //
- // _seq.setFont(textFieldsFont);
- // if (!rnaList.isEmpty())
- // {
- // _seq.setText(rnaList.get(0).getSeq());
- // }
-
- // _updateButton.addActionListener(new ActionListener()
- // {
- // public void actionPerformed(ActionEvent e)
- // {
- // FullBackup sel = (FullBackup) _sideList.getSelectedValue();
- // sel.rna.setSequence("A");
- // }
- // });
- //
- // _strLabel.setPreferredSize(new Dimension(marginTools, 15));
- // _strLabel.setHorizontalTextPosition(JLabel.LEFT);
- // _str.setFont(textFieldsFont);
- // _strPanel.setLayout(new BorderLayout());
- // _strPanel.add(_strLabel, BorderLayout.WEST);
- // _strPanel.add(_str, BorderLayout.CENTER);
- //
- // _input.setLayout(new GridLayout(1, 0));
- // _input.add(_strPanel);
- //
- // JPanel goPanel = new JPanel();
- // goPanel.setLayout(new BorderLayout());
- //
- // _tools.setLayout(new BorderLayout());
- // _tools.add(_input, BorderLayout.CENTER);
- // _tools.add(goPanel, BorderLayout.EAST);
- //
- // goPanel.add(_updateButton, BorderLayout.CENTER);
- //
- // JPanel ops = new JPanel();
- // ops.setLayout(new GridLayout(1, 2));
- // ops.add(_deleteButton);
- // ops.add(_duplicateButton);
-
JLabel j = new JLabel(
MessageManager.getString("label.structures_manager"),
JLabel.CENTER);
*/
public void ok_actionPerformed(ActionEvent e)
{
- String format = new IdentifyFile().Identify(getText(), "Paste");
+ String text = getText();
+ if (text.trim().length() < 1)
+ {
+ return;
+ }
+
+ String format = new IdentifyFile().Identify(text, "Paste");
// TODO: identify feature, annotation or tree file and parse appropriately.
AlignmentI al = null;
String sessionState = ss.getViewerState();
String tempStateFile = copyJarEntry(jprovider, sessionState,
"varna");
- RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped,
- tempStateFile);
- appVarna.addModel(rna, rnaTitle);
+ RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
+ appVarna.addModelSession(rna, rnaTitle, tempStateFile);
}
appVarna.setInitialSelection(viewer.getSelectedRna());
}
newFileLoc.append(";");
}
- if (newFileLoc.length() == 0)
+ if (newFileLoc.length() > 0)
{
- return;
- }
- int histbug = newFileLoc.indexOf("history = ");
- if (histbug > -1)
- {
- /*
- * change "history = [true|false];" to "history = [1|0];"
- */
+ int histbug = newFileLoc.indexOf("history = ");
histbug += 10;
int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
String val = (diff == -1) ? null : newFileLoc
.substring(histbug, diff);
if (val != null && val.length() >= 4)
{
- if (val.contains("e")) // eh? what can it be?
+ if (val.contains("e"))
{
if (val.trim().equals("true"))
{
newFileLoc.replace(histbug, diff, val);
}
}
- }
- final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
- .size()]);
- final String[] id = pdbids.toArray(new String[pdbids.size()]);
- final SequenceI[][] sq = seqmaps
- .toArray(new SequenceI[seqmaps.size()][]);
- final String fileloc = newFileLoc.toString();
- final String sviewid = viewerData.getKey();
- final AlignFrame alf = af;
- final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
- svattrib.getWidth(), svattrib.getHeight());
- try
- {
- javax.swing.SwingUtilities.invokeAndWait(new Runnable()
+ final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
+ .size()]);
+ final String[] id = pdbids.toArray(new String[pdbids.size()]);
+ final SequenceI[][] sq = seqmaps
+ .toArray(new SequenceI[seqmaps.size()][]);
+ final String fileloc = newFileLoc.toString();
+ final String sviewid = viewerData.getKey();
+ final AlignFrame alf = af;
+ final Rectangle rect = new Rectangle(svattrib.getX(),
+ svattrib.getY(), svattrib.getWidth(), svattrib.getHeight());
+ try
{
- @Override
- public void run()
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable()
{
- JalviewStructureDisplayI sview = null;
- try
- {
- sview = new StructureViewer(alf.alignPanel
- .getStructureSelectionManager()).createView(
- StructureViewer.ViewerType.JMOL, pdbf, id, sq,
- alf.alignPanel, svattrib, fileloc, rect, sviewid);
- addNewStructureViewer(sview);
- } catch (OutOfMemoryError ex)
+ @Override
+ public void run()
{
- new OOMWarning("restoring structure view for PDB id " + id,
- (OutOfMemoryError) ex.getCause());
- if (sview != null && sview.isVisible())
+ JalviewStructureDisplayI sview = null;
+ try
+ {
+ sview = new StructureViewer(alf.alignPanel
+ .getStructureSelectionManager()).createView(
+ StructureViewer.ViewerType.JMOL, pdbf, id, sq,
+ alf.alignPanel, svattrib, fileloc, rect, sviewid);
+ addNewStructureViewer(sview);
+ } catch (OutOfMemoryError ex)
{
- sview.closeViewer(false);
- sview.setVisible(false);
- sview.dispose();
+ new OOMWarning("restoring structure view for PDB id " + id,
+ (OutOfMemoryError) ex.getCause());
+ if (sview != null && sview.isVisible())
+ {
+ sview.closeViewer(false);
+ sview.setVisible(false);
+ sview.dispose();
+ }
}
}
- }
- });
- } catch (InvocationTargetException ex)
- {
- warn("Unexpected error when opening Jmol view.", ex);
+ });
+ } catch (InvocationTargetException ex)
+ {
+ warn("Unexpected error when opening Jmol view.", ex);
- } catch (InterruptedException e)
- {
- // e.printStackTrace();
+ } catch (InterruptedException e)
+ {
+ // e.printStackTrace();
+ }
}
}
package jalview.gui;
+import jalview.util.MessageManager;
+
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
-import jalview.util.MessageManager;
-
/**
* A class to manage multiple progress bars embedded in a JPanel.
*/
{ "HTML files" }, "HTML files");
jvFileChooser.setFileView(new JalviewFileView());
- // TODO uncomment when supported by MassageManager
jvFileChooser.setDialogTitle(MessageManager
.getString("label.save_as_biojs_html"));
jvFileChooser.setDialogTitle("save as BioJs HTML");
try
{
String gitRepoPkgJson = getURLContentAsString(BJS_TEMPLATE_GIT_REPO);
- BioJSRepositoryPojo release = new BioJSRepositoryPojo(
- gitRepoPkgJson);
- syncUpdates(BJS_TEMPLATES_LOCAL_DIRECTORY, release);
- refreshBioJSVersionsInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
+ if (gitRepoPkgJson != null)
+ {
+ BioJSRepositoryPojo release = new BioJSRepositoryPojo(
+ gitRepoPkgJson);
+ syncUpdates(BJS_TEMPLATES_LOCAL_DIRECTORY, release);
+ refreshBioJSVersionsInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
+ }
} catch (URISyntaxException e)
{
e.printStackTrace();
import jalview.api.ComplexAlignFile;
import jalview.api.FeaturesDisplayedI;
+import jalview.bin.Jalview;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
{
format = new IdentifyFile().Identify(file, protocol);
}
+
+ }
+
+ if (format == null || format.equalsIgnoreCase("EMPTY DATA FILE"))
+ {
+ Desktop.instance.stopLoading();
+ System.err.println("The input file \"" + file
+ + "\" has no data content!");
+ if (!Jalview.isHeadlessMode())
+ {
+ JOptionPane.showMessageDialog(null, "The input file \""
+ + file + "\" has no data content!", "Empty data file",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ return;
}
// TODO: cache any stream datasources as a temporary file (eg. PDBs
// retrieved via URL)
}
while ((data = source.nextLine()) != null)
{
- length += data.length();
+ length += data.trim().length();
if (!lineswereskipped)
{
for (int i = 0; !isBinary && i < data.length(); i++)
*/
package jalview.jbgui;
+import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
+import jalview.api.SplitContainerI;
+import jalview.bin.Cache;
+import jalview.gui.JvSwingUtils;
+import jalview.gui.Preferences;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.util.MessageManager;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
-import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
-import jalview.api.SplitContainerI;
-import jalview.bin.Cache;
-import jalview.gui.JvSwingUtils;
-import jalview.gui.Preferences;
-import jalview.schemes.ColourSchemeProperty;
-import jalview.util.MessageManager;
-
public class GAlignFrame extends JInternalFrame
{
protected JMenuBar alignFrameMenuBar = new JMenuBar();
System.err.println(e.toString());
}
- if (!new jalview.util.Platform().isAMac())
+ if (!jalview.util.Platform.isAMac())
{
closeMenuItem.setMnemonic('C');
outputTextboxMenu.setMnemonic('T');
{
case SEARCH_SUMMARY:
columnNames = new String[]
- { "PDB Feild", "Show in search summary" };
+ { "PDB Field", "Show in search summary" };
break;
case STRUCTURE_CHOOSER:
columnNames = new String[]
- { "PDB Feild", "Show in structure summary" };
+ { "PDB Field", "Show in structure summary" };
break;
case PREFERENCES:
columnNames = new String[]
- { "PDB Feild", "Show in search summary", "Show in structure summary" };
+ { "PDB Field", "Show in search summary", "Show in structure summary" };
break;
default:
break;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import java.util.Objects;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@SuppressWarnings("unchecked")
private void parse(String jsonString) throws ParseException
{
+ Objects.requireNonNull(jsonString,
+ "Supplied jsonString must not be null");
JSONParser jsonParser = new JSONParser();
JSONObject JsonObj = (JSONObject) jsonParser.parse(jsonString);
this.description = (String) JsonObj.get("description");
private FontMetrics fm;
- private final boolean MAC = new jalview.util.Platform().isAMac();
+ private final boolean MAC = jalview.util.Platform.isAMac();
boolean av_renderHistogram = true, av_renderProfile = true,
av_normaliseProfile = false;
*/
package jalview.util;
+import jalview.bin.Jalview;
import jalview.gui.EPSOptions;
import jalview.gui.SVGOptions;
import jalview.io.JalviewFileChooser;
static JalviewFileChooser getPNGChooser()
{
+ if (Jalview.isHeadlessMode())
+ {
+ return null;
+ }
return new jalview.io.JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
{ "png" }, new String[]
static JalviewFileChooser getEPSChooser()
{
+ if (Jalview.isHeadlessMode())
+ {
+ return null;
+ }
return new jalview.io.JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
{ "eps" }, new String[]
static JalviewFileChooser getSVGChooser()
{
+ if (Jalview.isHeadlessMode())
+ {
+ return null;
+ }
return new jalview.io.JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
{ "svg" }, new String[]
*/
public static final char[] deleteChars(char[] in, int from, int to)
{
- if (from >= in.length)
+ if (from >= in.length || from < 0)
{
return in;
}
* table. The PDB Id serves as a unique identifier for a given row in the
* summary table
*
- * @param wantedFeilds
+ * @param wantedFields
* the available table columns in no particular order
* @return the pdb id field column index
*/
public static int getPDBIdColumIndex(
- Collection<PDBDocField> wantedFeilds, boolean hasRefSeq)
+ Collection<PDBDocField> wantedFields, boolean hasRefSeq)
{
// If a reference sequence is attached then start counting from 1 else
// start from zero
- int pdbFeildIndexCounter = hasRefSeq ? 1 : 0;
+ int pdbFieldIndexCounter = hasRefSeq ? 1 : 0;
- for (PDBDocField feild : wantedFeilds)
+ for (PDBDocField field : wantedFields)
{
- if (feild.equals(PDBDocField.PDB_ID))
+ if (field.equals(PDBDocField.PDB_ID))
{
break; // Once PDB Id index is determined exit iteration
}
- ++pdbFeildIndexCounter;
+ ++pdbFieldIndexCounter;
}
- return pdbFeildIndexCounter;
+ return pdbFieldIndexCounter;
}
/**
* Test the constructor that parses a PDB file format ATOM line. Fields are in
* fixed column positions
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testStringConstructor()
{
Atom a = new Atom(
* Test the case where occupancy and temp factor are blank - should default to
* 1
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testStringConstructor_blankOccupancyTempFactor()
{
Atom a = new Atom(
/**
* Parsing non-numeric data as Atom throws an exception
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testStringConstructor_malformed()
{
try
public class BondTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testTranslate()
{
Atom a1 = new Atom(1f, 2f, 3f);
c = new PDBChain("1GAQ", "A");
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetNewlineString()
{
assertEquals(System.lineSeparator(), c.getNewlineString());
assertEquals("gaga", c.getNewlineString());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testPrint()
{
c.offset = 7;
* Test the method that constructs a Bond between two atoms and adds it to the
* chain's list of bonds
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeBond()
{
/*
assertEquals(3f, b2.end[2], 0.0001f);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSetChainColours_colour()
{
c.makeBond(a1, a2);
* Test setting bond start/end colours based on a colour scheme i.e. colour by
* residue
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSetChainColours_colourScheme()
{
Color alaColour = new Color(204, 255, 0);
assertEquals(Color.gray, b.endCol);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetChargeColour()
{
assertEquals(Color.red, PDBChain.getChargeColour("ASP"));
/**
* Test the method that sets bond start/end colours by residue charge property
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSetChargeColours()
{
a1.resName = "ASP"; // red
/**
* Test the method that converts the raw list of atoms to a list of residues
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeResidueList_noAnnotation()
{
Vector<Atom> atoms = new Vector<Atom>();
* Test the method that converts the raw list of atoms to a list of residues,
* including parsing of tempFactor to an alignment annotation
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeResidueList_withTempFactor()
{
Vector<Atom> atoms = new Vector<Atom>();
* Test the method that constructs bonds between successive residues' CA or P
* atoms
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeCaBondList()
{
c.isNa = true;
assertTrue(c.isNa);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeCaBondList_nucleotide()
{
c.isNa = false;
/**
* Test the method that updates atoms with their alignment positions
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeExactMapping()
{
Vector<Atom> atoms = new Vector<Atom>();
public class PDBfileTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testIsRna()
{
SequenceI seq = new Sequence("Seq1", "CGAU");
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testParse() throws IOException
{
/*
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testParse_withAnnotations_noSS() throws IOException
{
PDBfile pf = new PDBfile(true, false, false, "examples/3W5V.pdb",
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testParse_withJmol_noAnnotations() throws IOException
{
PDBfile pf = new PDBfile(false, true, false, "examples/3W5V.pdb",
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testParse_withJmolAddAlignmentAnnotations()
throws IOException
{
* @throws IOException
*/
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void testParse_withAnnotate3D() throws IOException
{
// TODO requires a mock for Annotate3D processing
public class ResidueTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testFindAtom()
{
Atom a1 = new Atom(1f, 2f, 3f);
import java.io.IOException;
import java.io.StringWriter;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* an input string
* @throws Exception
*/
+
+ @Test(groups =
+ { "Functional" }, dataProvider = "testWriteParam")
void test(String re, String inp) throws IOException
{
StringWriter sw = new StringWriter();
}
}
- @Test
- public void testWrite() throws IOException
+ // @Test(groups ={ "Functional" })
+ // public void testWrite() throws IOException
+ // {
+ // for (int n = 1; n <= 1; n++)
+ // {
+ // test("s/x/y/", "-----x123456789");
+ // test("s/x/y/", "x123456789");
+ // test("s/x/y/", "-----x");
+ // test("s/x.*?x/y/", ".xx..x..x...x...x....x....x");
+ // test("s/x.*x/[$&]/", "--x........x--xx");
+ // test("s/x.*x/[$&]/", "--x........x------");
+ // test("s/.$/a/m", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbbbbbbbbbbbb");
+ // test("s/.$/a/", "123");
+ // test("s/.$/a/", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb");
+ // test("s/^./a/", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb");
+ // test("s/$/a/", "bbb");
+ // test("s/^/a/", "bbb");
+ // test("s/^/a/", "");
+ // test("s{.*}{N}", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+ // test("s/.{0,7}/y/", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
+ // test("s/x/$&/", "xxx");
+ // }
+ // }
+
+ @DataProvider(name = "testWriteParam")
+ public Object[][] regexTestParams()
{
- for (int n = 1; n <= 1; n++)
+ return new Object[][]
{
- test("s/x/y/", "-----x123456789");
- test("s/x/y/", "x123456789");
- test("s/x/y/", "-----x");
- test("s/x.*?x/y/", ".xx..x..x...x...x....x....x");
- test("s/x.*x/[$&]/", "--x........x--xx");
- test("s/x.*x/[$&]/", "--x........x------");
- test("s/.$/a/m", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbbbbbbbbbbbb");
- test("s/.$/a/", "123");
- test("s/.$/a/", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb");
- test("s/^./a/", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb");
- test("s/$/a/", "bbb");
- test("s/^/a/", "bbb");
- test("s/^/a/", "");
- test("s{.*}{N}", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- test("s/.{0,7}/y/", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
- test("s/x/$&/", "xxx");
- }
+ { "s/x/y/", "-----x123456789" },
+ { "s/x/y/", "x123456789" },
+ { "s/x/y/", "-----x" },
+ { "s/x.*?x/y/", ".xx..x..x...x...x....x....x" },
+ { "s/x.*x/[$&]/", "--x........x--xx" },
+ { "s/x.*x/[$&]/", "--x........x------" },
+ { "s/.$/a/m", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbbbbbbbbbbbb" },
+ { "s/.$/a/", "123" },
+ { "s/.$/a/", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb" },
+ { "s/^./a/", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb" },
+ { "s/$/a/", "bbb" },
+ { "s/^/a/", "bbb" },
+ { "s/^/a/", "" },
+ { "s{.*}{N}", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" },
+ { "s/.{0,7}/y/", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" },
+ { "s/x/$&/", "xxx" } };
}
}
private static final String P = AAFrequency.PROFILE;
- @Test
+ @Test(groups ={ "Functional" })
public void testCalculate_noProfile()
{
SequenceI seq1 = new Sequence("Seq1", "CAGT");
assertEquals("T", col.get(R));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testCalculate_withProfile()
{
SequenceI seq1 = new Sequence("Seq1", "CAGT");
assertEquals(4, profile[1][1]);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testCalculate_withProfileTiming()
{
SequenceI seq1 = new Sequence("Seq1", "CAGT");
System.out.println(System.currentTimeMillis() - start);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetPercentageFormat()
{
assertNull(AAFrequency.getPercentageFormat(0));
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
-import org.junit.Test;
+import org.testng.annotations.Test;
public class AlignSeqTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testExtractGaps()
{
assertNull(AlignSeq.extractGaps(null, null));
/**
* Test method that converts a (possibly null) array to a list.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAsList()
{
// null array
/**
* Test a mixture of show/hidden annotations in/outside selection group.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetShownHiddenTypes_forSelectionGroup()
{
Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
* Test case where there are 'grouped' annotations, visible and hidden, within
* and without the selection group.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetShownHiddenTypes_withGraphGroups()
{
final int GROUP_3 = 3;
/**
* Test method that determines visible graph groups.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetVisibleGraphGroups()
{
AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
* Test for case where no sequence is selected. Shouldn't normally arise but
* check it handles it gracefully.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetShownHiddenTypes_noSequenceSelected()
{
Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
public static Sequence ts = new Sequence("short",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm");
- @Test
+ @Test(groups ={ "Functional" })
public void testExpandContext()
{
AlignmentI al = new Alignment(new Sequence[] {});
/**
* Test that annotations are correctly adjusted by expandContext
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testExpandContext_annotation()
{
AlignmentI al = new Alignment(new Sequence[]
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetSequencesByName() throws IOException
{
final String data = ">Seq1Name\nKQYL\n" + ">Seq2Name\nRFPW\n"
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMapProteinToCdna_noXrefs() throws IOException
{
List<SequenceI> protseqs = new ArrayList<SequenceI>();
/**
* Test for the alignSequenceAs method that takes two sequences and a mapping.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignSequenceAs_withMapping_noIntrons()
{
MapList map = new MapList(new int[]
/**
* Test for the alignSequenceAs method that takes two sequences and a mapping.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignSequenceAs_withMapping_withIntrons()
{
/*
/**
* Test for the case where not all of the protein sequence is mapped to cDNA.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignSequenceAs_withMapping_withUnmappedProtein()
{
/**
* Test for the alignSequenceAs method where we preserve gaps in introns only.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignSequenceAs_keepIntronGapsOnly()
{
* Test for the method that generates an aligned translated sequence from one
* mapping.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetAlignedTranslation_dnaLikeProtein()
{
// dna alignment will be replaced
/**
* Test the method that realigns protein to match mapped codon alignment.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignProteinAsDna()
{
// seq1 codons are [1,2,3] [4,5,6] [7,8,9] [10,11,12]
* Test the method that tests whether a CDNA sequence translates to a protein
* sequence
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testTranslatesAs()
{
assertTrue(AlignmentUtils.translatesAs("tttcccaaaggg".toCharArray(), 0,
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMapProteinToCdna_withStartAndStopCodons()
throws IOException
{
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMapProteinToCdna_withXrefs() throws IOException
{
List<SequenceI> protseqs = new ArrayList<SequenceI>();
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMapProteinToCdna_prioritiseXrefs() throws IOException
{
List<SequenceI> protseqs = new ArrayList<SequenceI>();
* Test the method that shows or hides sequence annotations by type(s) and
* selection group.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testShowOrHideSequenceAnnotations()
{
SequenceI seq1 = new Sequence("Seq1", "AAA");
/**
* Tests for the method that checks if one sequence cross-references another
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testHasCrossRef()
{
assertFalse(AlignmentUtils.hasCrossRef(null, null));
* Tests for the method that checks if either sequence cross-references the
* other
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testHaveCrossRef()
{
assertFalse(AlignmentUtils.hasCrossRef(null, null));
/**
* Test the method that extracts the exon-only part of a dna alignment.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeExonAlignment()
{
SequenceI dna1 = new Sequence("dna1", "aaaGGGcccTTTaaa");
* already has a protein product (Uniprot translation) which in turn has an
* x-ref to the EMBLCDS record.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeExonSequences()
{
SequenceI dna1 = new Sequence("dna1", "aaaGGGcccTTTaaa");
* its product mappings, for the case where there are multiple exon mappings
* to different protein products.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeExonAlignment_multipleProteins()
{
SequenceI dna1 = new Sequence("dna1", "aaaGGGcccTTTaaa");
* sequence ref</li>
* </ul>
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSortBySequenceAndType_autocalcLast()
{
// @formatter:off
/**
* Variant with autocalculated annotations sorting to front
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSortBySequenceAndType_autocalcFirst()
{
// @formatter:off
* sequence ref</li>
* </ul>
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSortByTypeAndSequence_autocalcLast()
{
// @formatter:off
/**
* Variant of test with autocalculated annotations sorted to front
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSortByTypeAndSequence_autocalcFirst()
{
// @formatter:off
* Variant of test with autocalculated annotations sorted to front but
* otherwise no change.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testNoSort_autocalcFirst()
{
// @formatter:off
assertEquals("Structure", anns[6].label);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSort_timingPresorted()
{
testTiming_presorted(50, 100);
*/
private void testTiming_presorted(final int numSeqs, final int numAnns)
{
- al = buildAlignment(numSeqs);
- anns = buildAnnotations(numAnns);
+ Alignment alignment = buildAlignment(numSeqs);
+ AlignmentAnnotation[] annotations = buildAnnotations(numAnns);
/*
* Set the annotations presorted by label
*/
Random r = new Random();
- final SequenceI[] sequences = al.getSequencesArray();
- for (int i = 0; i < anns.length; i++)
+ final SequenceI[] sequences = alignment.getSequencesArray();
+ for (int i = 0; i < annotations.length; i++)
{
SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
- anns[i].sequenceRef = randomSequenceRef;
- anns[i].label = "label" + i;
+ annotations[i].sequenceRef = randomSequenceRef;
+ annotations[i].label = "label" + i;
}
long startTime = System.currentTimeMillis();
- AnnotationSorter testee = new AnnotationSorter(al, false);
- testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ AnnotationSorter testee = new AnnotationSorter(alignment, false);
+ testee.sort(annotations, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
long endTime = System.currentTimeMillis();
final long elapsed = endTime - startTime;
System.out.println("Timing test for presorted " + numSeqs
/**
* Timing tests for sorting randomly sorted annotations for various sizes.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSort_timingUnsorted()
{
testTiming_unsorted(50, 100);
*/
private void testTiming_unsorted(final int numSeqs, final int numAnns)
{
- al = buildAlignment(numSeqs);
- anns = buildAnnotations(numAnns);
+ Alignment alignment = buildAlignment(numSeqs);
+ AlignmentAnnotation[] annotations = buildAnnotations(numAnns);
/*
* Set the annotations in random order with respect to the sequences
*/
Random r = new Random();
- final SequenceI[] sequences = al.getSequencesArray();
- for (int i = 0; i < anns.length; i++)
+ final SequenceI[] sequences = alignment.getSequencesArray();
+ for (int i = 0; i < annotations.length; i++)
{
SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
- anns[i].sequenceRef = randomSequenceRef;
- anns[i].label = "label" + i;
+ annotations[i].sequenceRef = randomSequenceRef;
+ annotations[i].label = "label" + i;
}
long startTime = System.currentTimeMillis();
- AnnotationSorter testee = new AnnotationSorter(al, false);
- testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ AnnotationSorter testee = new AnnotationSorter(alignment, false);
+ testee.sort(annotations, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
long endTime = System.currentTimeMillis();
final long elapsed = endTime - startTime;
System.out.println("Timing test for unsorted " + numSeqs
/**
* Timing test for sorting annotations with a limited range of types (labels).
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSort_timingSemisorted()
{
testTiming_semiSorted(50, 100);
*/
private void testTiming_semiSorted(final int numSeqs, final int numAnns)
{
- al = buildAlignment(numSeqs);
- anns = buildAnnotations(numAnns);
+ Alignment alignment = buildAlignment(numSeqs);
+ AlignmentAnnotation[] annotations = buildAnnotations(numAnns);
String[] labels = new String[]
{ "label1", "label2", "label3", "label4", "label5", "label6" };
* Set the annotations in sequence order with randomly assigned labels.
*/
Random r = new Random();
- final SequenceI[] sequences = al.getSequencesArray();
- for (int i = 0; i < anns.length; i++)
+ final SequenceI[] sequences = alignment.getSequencesArray();
+ for (int i = 0; i < annotations.length; i++)
{
SequenceI sequenceRef = sequences[i % sequences.length];
- anns[i].sequenceRef = sequenceRef;
- anns[i].label = labels[r.nextInt(labels.length)];
+ annotations[i].sequenceRef = sequenceRef;
+ annotations[i].label = labels[r.nextInt(labels.length)];
}
long startTime = System.currentTimeMillis();
- AnnotationSorter testee = new AnnotationSorter(al, false);
- testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ AnnotationSorter testee = new AnnotationSorter(alignment, false);
+ testee.sort(annotations, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
long endTime = System.currentTimeMillis();
long elapsed = endTime - startTime;
System.out.println("Sort by label for semisorted " + numSeqs
// now resort by sequence
startTime = System.currentTimeMillis();
- testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ testee.sort(annotations, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
endTime = System.currentTimeMillis();
elapsed = endTime - startTime;
System.out.println("Resort by sequence for semisorted " + numSeqs
// now resort by label
startTime = System.currentTimeMillis();
- testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ testee.sort(annotations, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
endTime = System.currentTimeMillis();
elapsed = endTime - startTime;
System.out.println("Resort by label for semisorted " + numSeqs
public class CodingUtilsTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testDecodeCodon()
{
assertTrue(Arrays.equals(new char[]
{ 'T', 'T', 'T' }, CodingUtils.decodeCodon(63)));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testDecodeNucleotide()
{
assertEquals('A', CodingUtils.decodeNucleotide(0));
assertEquals('0', CodingUtils.decodeNucleotide(4));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testEncodeCodon()
{
assertTrue(CodingUtils.encodeCodon('Z') < 0);
public class CrossRefTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testFindXDbRefs()
{
DBRefEntry ref1 = new DBRefEntry("UNIPROT", "1", "A123");
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testTranslateCdna_withUntranslatableCodons()
throws IOException
{
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testTranslateCdna_withUntranslatableCodonsAndHiddenColumns()
throws IOException
{
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testTranslateCdna_simple() throws IOException
{
AlignmentI alf = new FormatAdapter().readFile(fasta,
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testTranslateCdna_hiddenColumns() throws IOException
{
AlignmentI alf = new FormatAdapter().readFile(fasta,
/**
* Use this test to help debug into any cases of interest.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testCompareCodonPos_oneOnly()
{
assertFollows("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1
/**
* Tests for method that compares 'alignment' of two codon position triplets.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testCompareCodonPos()
{
/*
* reorders the cDNA and retranslates, and verifies that the translations are
* the same (apart from ordering).
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testTranslateCdna_sequenceOrderIndependent()
{
/*
* Test that all the cases in testCompareCodonPos have a 'symmetric'
* comparison (without checking the actual comparison result).
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testCompareCodonPos_isSymmetric()
{
assertSymmetric("AAA", "GGG");
/**
* Weirdly, maybe worth a test to prove the helper method of this test class.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testConvertCodon()
{
assertEquals("[0, 1, 2]", convertCodon("AAA").toString());
int[] positions = new int[]
{ 1, 7, 9 };
- @Test
+ @Test(groups ={ "Functional" })
public void testMakeGroupsWithBoth()
{
ArrayList<String> str = new ArrayList<String>();
* more 'number characters' (0-9+.), i.e. greedily matches any trailing
* numeric part of the string
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetScoresFromDescription()
{
String regex = ".*([-0-9.+]+)";
* character, followed by at least one 'number character', then any trailing
* characters.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetScoresFromDescription_twoScores()
{
String regex = ".*([-0-9.+]+).+([-0-9.+]+).*";
*
* @see AlignFrame.extractScores_actionPerformed
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetScoresFromDescription_wordBoundaries()
{
String regex = "\\W*([-+eE0-9.]+)";
--- /dev/null
+package jalview.analysis;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.fail;
+
+import jalview.analysis.SecStrConsensus.SimpleBP;
+
+import java.util.Vector;
+
+import org.testng.annotations.Test;
+public class RnaTest
+{
+ @Test(groups ={ "Functional" })
+ public void testGetSimpleBPs() throws WUSSParseException
+ {
+ String rna = "([{})]"; // JAL-1081 example
+ Vector<SimpleBP> bps = Rna.GetSimpleBPs(rna);
+ assertEquals(3, bps.size());
+
+ /*
+ * the base pairs are added in the order in which the matching base is found
+ */
+ assertEquals(2, bps.get(0).bp5); // {
+ assertEquals(3, bps.get(0).bp3); // }
+ assertEquals(0, bps.get(1).bp5); // (
+ assertEquals(4, bps.get(1).bp3); // )
+ assertEquals(1, bps.get(2).bp5); // [
+ assertEquals(5, bps.get(2).bp3); // ]
+ }
+
+ @Test(groups ={ "Functional" })
+ public void testGetSimpleBPs_unmatchedOpener()
+ {
+ String rna = "(([{})]";
+ try
+ {
+ Rna.GetSimpleBPs(rna);
+ fail("expected exception");
+ } catch (WUSSParseException e)
+ {
+ // expected
+ }
+ }
+
+ @Test(groups ={ "Functional" })
+ public void testGetSimpleBPs_unmatchedCloser()
+ {
+ String rna = "([{})]]";
+ try
+ {
+ Rna.GetSimpleBPs(rna);
+ fail("expected exception");
+ } catch (WUSSParseException e)
+ {
+ // expected
+ }
+ }
+}
}
- @Test
+ @Test(groups ={ "Functional" })
/**
* simple test that mapping from alignment corresponds identical positions.
*/
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testExtractGaps()
{
assertNull(AlignSeq.extractGaps(null, null));
assertEquals("ABCD", AlignSeq.extractGaps(" .-", ". -A-B.C D."));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testPrintAlignment()
{
AlignSeq as = AlignSeq.doGlobalNWAlignment(s1, s3, AlignSeq.PEP);
int[] sf3 = new int[]
{ -1, -1, -1, -1, -1, -1, 76, 77 };
- @Test
+ @Test(groups ={ "Functional" })
public void testFeatureScoreModel() throws Exception
{
AlignFrame alf = new FileLoader(false).LoadFileWaitTillLoaded(alntestFile,
import java.io.InputStreamReader;
import org.testng.Assert;
-import org.testng.AssertJUnit;
+import org.testng.FileAssert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class CommandLineOperations
String _cmd = "java "
+ (withAwt ? "-Djava.awt.headless=true" : "")
+ " -Djava.ext.dirs=./lib -classpath ./classes jalview.bin.Jalview ";
- System.out.println("###############Jalview CMD: " + _cmd + cmd);
+ System.out.println("############ Testing Jalview CMD: " + _cmd + cmd);
Process ls2_proc = Runtime.getRuntime().exec(_cmd + cmd);
BufferedReader outputReader = new BufferedReader(new InputStreamReader(
ls2_proc.getInputStream()));
Worker worker = new Worker(ls2_proc);
worker.start();
worker.join(timeout);
- System.out.println("Output: ");
- String ln = null;
- while ((ln = outputReader.readLine()) != null)
+ // System.out.println("Output: ");
+ // String ln = null;
+ // while ((ln = outputReader.readLine()) != null)
+ // {
+ // System.out.println(ln);
+ // }
+ //
+ // System.out.println("Error: ");
+ // while ((ln = errorReader.readLine()) != null)
+ // {
+ // System.out.println(ln);
+ // }
+ return worker;
+ }
+
+ @BeforeTest
+ public void initialize()
+ {
+ new CommandLineOperations();
+ }
+
+ @Test(groups =
+ { "Functional" }, dataProvider = "headlessModeOutputParams")
+ public void testHeadlessModeOutputs(String harg, String type,
+ String fileName, boolean withAWT, int expectedMinFileSize)
+ {
+ String cmd = harg + type + " " + fileName;
+ // System.out.println(">>>>>>>>>>>>>>>> Command : " + cmd);
+ File file = new File(fileName);
+ Worker worker = null;
+ try
{
- System.out.println(ln);
+ worker = jalviewDesktopRunner(withAWT, cmd, 9000);
+ } catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
}
- System.out.println("Error: ");
- while ((ln = errorReader.readLine()) != null)
+ FileAssert.assertFile(file, "Didn't create an output" + type
+ + " file.[" + harg + "]");
+ FileAssert.assertMinLength(new File(fileName), expectedMinFileSize);
+ if (worker != null && worker.exit == null)
{
- System.out.println(ln);
+ worker.interrupt();
+ Thread.currentThread().interrupt();
+ worker.process.destroy();
+ Assert.fail("Jalview did not exit after "
+ + type
+ + " generation (try running test again to verify - timeout at 9000ms). ["
+ + harg + "]");
}
- return worker;
+ new File(fileName).delete();
}
- @Test
- public void testHeadlessModeEPS() throws Exception
+ @DataProvider(name = "headlessModeOutputParams")
+ public static Object[][] headlessModeOutput()
{
- String[] headlessArgs = new String[]
- { "nodisplay", "headless", "nogui" };
- for (String _harg : headlessArgs)
+ return new Object[][]
{
- boolean _switch = false, withAwt = false;
- do
- {
- if (_switch)
- {
- withAwt = true;
- }
- _switch = true;
- String jalview_input = "examples/uniref50.fa";
- String jalview_output = "test_uniref50_out.eps";
- String cmd = "" + _harg + " -open " + jalview_input + " -eps "
- + jalview_output;
- String harg = _harg
- + (withAwt ? "-Djava.awt.headless=true"
- : " NO AWT.HEADLESS");
- System.out.println("Testing with Headless argument: '" + harg
- + "'\n");
- Worker worker = jalviewDesktopRunner(withAwt, cmd, 9000);
- AssertJUnit.assertTrue("Didn't create an output EPS file.[" + harg
- + "]", new File("test_uniref50_out.eps").exists());
- AssertJUnit.assertTrue(
- "Didn't create an EPS file with any content[" + harg + "]",
- new File("test_uniref50_out.eps").length() > 4096);
- if (worker.exit == null)
- {
- worker.interrupt();
- Thread.currentThread().interrupt();
- worker.process.destroy();
- Assert.fail("Jalview did not exit after EPS generation (try running test again to verify - timeout at 9000ms). ["
- + harg + "]");
- }
- } while (!withAwt);
- }
+ { "nodisplay -open examples/uniref50.fa", " -eps",
+ "test_uniref50_out.eps", true, 4096 },
+ { "nodisplay -open examples/uniref50.fa", " -eps",
+ "test_uniref50_out.eps", false, 4096 },
+ { "headless -open examples/uniref50.fa", " -eps",
+ "test_uniref50_out.eps", true, 4096 },
+ { "headless -open examples/uniref50.fa", " -eps",
+ "test_uniref50_out.eps", false, 4096 },
+ { "nogui -open examples/uniref50.fa", " -eps",
+ "test_uniref50_out.eps", true, 4096 },
+ { "nogui -open examples/uniref50.fa", " -eps",
+ "test_uniref50_out.eps", false, 4096 },
+ { "headless -open examples/uniref50.fa", " -svg",
+ "test_uniref50_out.svg", true, 4096 },
+ { "headless -open examples/uniref50.fa", " -svg",
+ "test_uniref50_out.svg", false, 4096 },
+ { "headless -open examples/uniref50.fa", " -png",
+ "test_uniref50_out.png", true, 4096 },
+ { "headless -open examples/uniref50.fa", " -png",
+ "test_uniref50_out.png", false, 4096 },
+ { "headless -open examples/uniref50.fa", " -html",
+ "test_uniref50_out.html", true, 4096 },
+ { "headless -open examples/uniref50.fa", " -html",
+ "test_uniref50_out.html", false, 4096 },
+ { "headless -open examples/uniref50.fa", " -fasta",
+ "test_uniref50_out.mfa", true, 2096 },
+ { "headless -open examples/uniref50.fa", " -fasta",
+ "test_uniref50_out.mfa", false, 2096 },
+ { "headless -open examples/uniref50.fa", " -clustal",
+ "test_uniref50_out.aln", true, 2096 },
+ { "headless -open examples/uniref50.fa", " -clustal",
+ "test_uniref50_out.aln", false, 2096 },
+ { "headless -open examples/uniref50.fa", " -msf",
+ "test_uniref50_out.msf", true, 2096 },
+ { "headless -open examples/uniref50.fa", " -msf",
+ "test_uniref50_out.msf", false, 2096 },
+ { "headless -open examples/uniref50.fa", " -pileup",
+ "test_uniref50_out.aln", true, 2096 },
+ { "headless -open examples/uniref50.fa", " -pileup",
+ "test_uniref50_out.aln", false, 2096 },
+ { "headless -open examples/uniref50.fa", " -pir",
+ "test_uniref50_out.pir", true, 2096 },
+ { "headless -open examples/uniref50.fa", " -pir",
+ "test_uniref50_out.pir", false, 2096 },
+ { "headless -open examples/uniref50.fa", " -pfam",
+ "test_uniref50_out.pfam", true, 2096 },
+ { "headless -open examples/uniref50.fa", " -pfam",
+ "test_uniref50_out.pfam", false, 2096 },
+ { "headless -open examples/uniref50.fa", " -blc",
+ "test_uniref50_out.blc", true, 2096 },
+ { "headless -open examples/uniref50.fa", " -blc",
+ "test_uniref50_out.blc", false, 2096 },
+ { "headless -open examples/uniref50.fa", " -jalview",
+ "test_uniref50_out.jvp", true, 2096 },
+ { "headless -open examples/uniref50.fa", " -jalview",
+ "test_uniref50_out.jvp", false, 2096 },
+ };
}
- // @Test
- // public void testJalview2XMLDataset() throws Exception
- // {
- // String jalview_input = "examples/uniref50.fa";
- // String jalview_output = "test_uniref50_out.eps";
- // String cmd = ""+" -open "+ jalview_input + " -eps " + jalview_output;
- // //String harg = _harg+(withAwt ?
- // "-Djava.awt.headless=true":" NO AWT.HEADLESS");
- // System.out.println("Testing with Headless argument: '"+harg+"'\n");
- // Worker worker = jalviewDesktopRunner(withAwt, cmd, 9000);
- // assertTrue("Didn't create an output EPS file.["+harg+"]", new
- // File("test_uniref50_out.eps").exists());
- // assertTrue("Didn't create an EPS file with any content["+harg+"]", new
- // File("test_uniref50_out.eps").length()>4096);
- // if (worker.exit == null){
- // worker.interrupt();
- // Thread.currentThread().interrupt();
- // worker.process.destroy();
- // fail("Jalview did not exit after EPS generation (try running test again to verify - timeout at 9000ms). ["+harg+"]");
- // }
- // }
+
+
}
/**
* Test inserting gap characters
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAppendEdit_insertGap()
{
// set a non-standard gap character to prove it is actually used
* Test deleting characters from sequences. Note the deleteGap() action does
* not check that only gap characters are being removed.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAppendEdit_deleteGap()
{
testee.appendEdit(Action.DELETE_GAP, seqs, 4, 3, al, true);
* Test a cut action. The command should store the cut characters to support
* undo.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testCut()
{
Edit ec = testee.new Edit(Action.CUT, seqs, 4, 3, al);
/**
* Test a Paste action, where this adds sequences to an alignment.
*/
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
// TODO fix so it works
public void testPaste_addToAlignment()
{
/**
* Test insertGap followed by undo command
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testUndo_insertGap()
{
// Edit ec = testee.new Edit(Action.INSERT_GAP, seqs, 4, 3, '?');
/**
* Test deleteGap followed by undo command
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testUndo_deleteGap()
{
testee.appendEdit(Action.DELETE_GAP, seqs, 4, 3, al, true);
/**
* Test several commands followed by an undo command
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testUndo_multipleCommands()
{
// delete positions 3/4/5 (counting from 1)
* Unit test for JAL-1594 bug: click and drag sequence right to insert gaps -
* undo did not remove them all.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testUndo_multipleInsertGaps()
{
testee.appendEdit(Action.INSERT_GAP, seqs, 4, 1, al, true);
/**
* Test cut followed by undo command
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testUndo_cut()
{
testee.appendEdit(Action.CUT, seqs, 4, 3, al, true);
/**
* Test the replace command (used to manually edit a sequence)
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testReplace()
{
// seem to need a dataset sequence on the edited sequence here
* Test that the addEdit command correctly merges insert gap commands when
* possible.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAddEdit_multipleInsertGap()
{
/*
* Test that the addEdit command correctly merges delete gap commands when
* possible.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAddEdit_multipleDeleteGap()
{
/*
* case when they appear contiguous but are acting on different sequences.
* They should not be merged.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAddEdit_removeAllGaps()
{
seqs[0].setSequence("a???bcdefghjk");
* Test that the addEdit command correctly merges insert gap commands acting
* on a multi-sequence selection.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAddEdit_groupInsertGaps()
{
/*
* <li>last: --A--B-CDEF</li>
* </ul>
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testPriorState_multipleInserts()
{
EditCommand command = new EditCommand();
* <li>End: ABC</li>
* </ul>
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testPriorState_removeAllGaps()
{
EditCommand command = new EditCommand();
/**
* Test for 'undoing' a single delete edit.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testPriorState_singleDelete()
{
EditCommand command = new EditCommand();
/**
* Test 'undoing' a single gap insertion edit command.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testPriorState_singleInsert()
{
EditCommand command = new EditCommand();
* Test that mimics 'remove all gaps' action. This generates delete gap edits
* for contiguous gaps in each sequence separately.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testPriorState_removeGapsMultipleSeqs()
{
EditCommand command = new EditCommand();
* series Delete Gap edits that each act on all sequences that share a gapped
* column region.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testPriorState_removeGappedCols()
{
EditCommand command = new EditCommand();
/**
* Test the method that locates the first aligned sequence that has a mapping.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testFindAlignedSequence()
{
AlignmentI cdna = new Alignment(new SequenceI[]
/**
* Test the method that locates the mapped codon for a protein position.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetMappedRegion()
{
// introns lower case, exons upper case
assertNull(acf.getMappedRegion(seq1, aseq2, 1));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetMappedCodon()
{
final Sequence seq1 = new Sequence("Seq1", "c-G-TA-gC-gT-T");
/**
* Test normal case for iterating over aligned codons.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testNext()
{
SequenceI from = new Sequence("Seq1", "-CgC-C-cCtAG-AtG-Gc");
/**
* Test weird case where the mapping skips over a peptide.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testNext_unmappedPeptide()
{
SequenceI from = new Sequence("Seq1", "-CgC-C-cCtAG-AtG-Gc");
/**
* Test for exception thrown for an incomplete codon.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testNext_incompleteCodon()
{
SequenceI from = new Sequence("Seq1", "-CgC-C-cCgTt");
/**
* Test normal case for iterating over aligned codons.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAnother()
{
SequenceI from = new Sequence("Seq1", "TGCCATTACCAG-");
public class AlignedCodonTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testEquals()
{
AlignedCodon ac = new AlignedCodon(1, 3, 4);
assertTrue(ac.equals(ac));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testToString() {
AlignedCodon ac = new AlignedCodon(1, 3, 4);
assertEquals("[1, 3, 4]", ac.toString());
public class AlignmentAnnotationTests
{
- @Test
+ @Test(groups ={ "Functional" })
public void testCopyConstructor()
{
SequenceI sq = new Sequence("Foo", "ARAARARARAWEAWEAWRAWEAWE");
* different dataset frames (annotation transferred by mapping between
* sequences)
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testLiftOver()
{
SequenceI sqFrom = new Sequence("fromLong", "QQQCDEWGH");
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testAdjustForAlignment()
{
SequenceI seq = new Sequence("TestSeq", "ABCDEFG");
/**
* Test method that returns annotations that match on calcId.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testFindAnnotation_byCalcId()
{
Iterable<AlignmentAnnotation> anns = al
assertFalse(iter.hasNext());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testDeleteAllAnnotations_includingAutocalculated()
{
AlignmentAnnotation aa = new AlignmentAnnotation("Consensus",
assertEquals("Not all deleted", 0, al.getAlignmentAnnotation().length);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testDeleteAllAnnotations_excludingAutocalculated()
{
AlignmentAnnotation aa = new AlignmentAnnotation("Consensus",
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignAs_dnaAsDna() throws IOException
{
// aligned cDNA:
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignAs_proteinAsCdna() throws IOException
{
// see also AlignmentUtilsTests
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignAs_cdnaAsProtein() throws IOException
{
/*
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignAs_dnaAsProtein_withIntrons() throws IOException
{
/*
public class ColumnSelectionTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testAddElement()
{
ColumnSelection cs = new ColumnSelection();
* Test the remove method - in particular to verify that remove(int i) removes
* the element whose value is i, _NOT_ the i'th element.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testRemoveElement()
{
ColumnSelection cs = new ColumnSelection();
* Test the method that finds the visible column position of an alignment
* column, allowing for hidden columns.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testFindColumnPosition()
{
ColumnSelection cs = new ColumnSelection();
/**
* Tests for the method that compares equality of reference (but not mapping)
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testEqualRef()
{
DBRefEntry ref1 = new DBRefEntry("UNIPROT", "1", "V71633");
* trite test of the intersectVisContigs method for a simple DNA -> Protein
* exon map and a range of visContigs
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testIntersectVisContigs()
{
MapList fk = new MapList(new int[]
{
}
- @Test
+ @Test(groups ={ "Functional" })
public void test()
{
try
public class SearchResultsTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testToString()
{
SequenceI seq = new Sequence("", "abcdefghijklm");
*
* TODO: split into separate tests
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSomething() throws Exception
{
String o_seq = "asdfktryasdtqwrtsaslldddptyipqqwaslchvhttt";
package jalview.datamodel;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import org.testng.annotations.Test;
-import org.junit.Assert;
-import org.junit.Test;
public class SequenceDummyTest
{
/**
* test for become method
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBecome()
{
SequenceI seq = new Sequence("OrigSeq", "ASEQUENCE");
SequenceDummy dummySeq = new SequenceDummy("OrigSeq");
dummySeq.addSequenceFeature(ofeat);
dummySeq.become(seq);
- Assert.assertFalse("Dummy sequence did not become a full sequence",
+ assertFalse("Dummy sequence did not become a full sequence",
dummySeq.isDummy());
- Assert.assertTrue("Sequence was not updated from template", seq
+ assertTrue("Sequence was not updated from template", seq
.getSequenceAsString().equals(dummySeq.getSequenceAsString()));
boolean found = false;
for (SequenceFeature sf : dummySeq.getSequenceFeatures())
break;
}
}
- Assert.assertTrue("Didn't retain original sequence feature", found);
+ assertTrue("Didn't retain original sequence feature", found);
// todo - should test all aspect of copy constructor
}
{
seq = new Sequence("FER1", "AKPNGVL");
}
- @Test
+ @Test(groups ={ "Functional" })
public void testInsertGapsAndGapmaps()
{
SequenceI aseq = seq.deriveSequence();
assertEquals("Gap interval 2 end wrong", 8, gapInt.get(1)[1]);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetAnnotation()
{
// initial state returns null not an empty array
assertNull(seq.getAnnotation());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetAnnotation_forLabel()
{
AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1", 1f);
return annotation;
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetAlignmentAnnotations_forCalcIdAndLabel()
{
AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1",
* setting the sequenceRef on the annotation. Adding the same annotation twice
* should be ignored.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testAddAlignmentAnnotation()
{
assertNull(seq.getAnnotation());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetStartGetEnd()
{
SequenceI seq = new Sequence("test", "ABCDEF");
* Tests for the method that returns an alignment column position (base 1) for
* a given sequence position (base 1).
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testFindIndex()
{
SequenceI seq = new Sequence("test", "ABCDEF");
* Tests for the method that returns a dataset sequence position (base 1) for
* an aligned column position (base 0).
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testFindPosition()
{
SequenceI seq = new Sequence("test", "ABCDEF");
assertEquals(7, seq.findPosition(11));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testDeleteChars()
{
SequenceI seq = new Sequence("test", "ABCDEF");
assertEquals(6, seq.getEnd());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testInsertCharAt()
{
// non-static methods:
* Test the method that returns an array of aligned sequence positions where
* the array index is the data sequence position (both base 0).
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGapMap()
{
SequenceI seq = new Sequence("test", "-A--B-CD-E--F-");
* Test the method that gets sequence features, either from the sequence or
* its dataset.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetSequenceFeatures()
{
SequenceI seq = new Sequence("test", "GATCAT");
* entries are the residue positions at the sequence position (or to the right
* if a gap)
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testFindPositionMap()
{
/*
/**
* Test for getSubsequence
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetSubsequence()
{
SequenceI seq = new Sequence("TestSeq", "ABCDEFG");
/**
* Test for deriveSequence applied to a sequence with a dataset
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testDeriveSequence_existingDataset()
{
SequenceI seq = new Sequence("Seq1", "CD");
/**
* Test for deriveSequence applied to an ungapped sequence with no dataset
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testDeriveSequence_noDatasetUngapped()
{
SequenceI seq = new Sequence("Seq1", "ABCDEF");
/**
* Test for deriveSequence applied to a gapped sequence with no dataset
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testDeriveSequence_noDatasetGapped()
{
SequenceI seq = new Sequence("Seq1", "AB-C.D EF");
+ "</locationElement></location></feature>"
+ "<sequence type=\"mRNA\" version=\"2\">GTGACG</sequence></entry></EMBL_Services>";
- @Test
+ @Test(groups ={ "Functional" })
public void testGetEmblFile()
{
Vector<EmblEntry> entries = EmblFile.getEmblFile(
Boolean.TRUE.toString());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testAlignmentLoader() throws Exception
{
for (String f : testFile)
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testFileParser() throws Exception
{
for (String pdbStr : testFile)
public class TestAnnotate3D
{
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void test1GIDbyId() throws Exception
{
// use same ID as standard tests given at
testRNAMLcontent(ids, null);
}
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void testIdVsContent2GIS() throws Exception
{
Iterator<Reader> ids = Annotate3D.getRNAMLForPDBId("2GIS");
*
* @throws Exception
*/
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void testPDBfileVsRNAML() throws Exception
{
PDBfile pdbf = new PDBfile(true, false, true, "examples/2GIS.pdb",
testRNAMLcontent(readers, pdbf);
}
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
private void testRNAMLcontent(Iterator<Reader> readers, PDBfile pdbf)
throws Exception
{
public class ChimeraCommandsTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testAddColourRange()
{
Map<Color, Map<Integer, Map<String, List<int[]>>>> map = new LinkedHashMap<Color, Map<Integer, Map<String, List<int[]>>>>();
{ 5, 9 }, posList.get(0)));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildColourCommands()
{
public class ChimeraConnect
{
- @Test
+ @Test(groups ={ "Functional" })
public void testLaunchAndExit()
{
final StructureManager structureManager = new StructureManager(true);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSingleSeqViewJMol()
{
String inFile = "examples/1gaq.txt";
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSingleSeqViewChimera()
{
String inFile = "examples/1gaq.txt";
testee = new AlignViewport(al);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testCollateForPdb()
{
/*
/**
* Test creation of panel with OK and Cancel buttons
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildActionButtonsPanel()
{
testee = new AnnotationChooser(parentPanel);
* Test 'Apply to' has 3 radio buttons enabled, 'Selected Sequences' selected,
* when there is a current selection group.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildApplyToOptionsPanel_withSelectionGroup()
{
selectSequences(0, 2, 3);
* Test 'Apply to' has 1 radio button enabled, 'All Sequences' selected, when
* there is no current selection group.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildApplyToOptionsPanel_noSelectionGroup()
{
testee = new AnnotationChooser(parentPanel);
/**
* Test Show and Hide radio buttons created, with Hide initially selected.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildShowHidePanel()
{
testee = new AnnotationChooser(parentPanel);
/**
* Test construction of panel containing two sub-panels
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildShowHideOptionsPanel()
{
testee = new AnnotationChooser(parentPanel);
* Test that annotation types are (uniquely) identified.
*
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetAnnotationTypes()
{
selectSequences(1);
* We expect all annotations of that type to be set hidden. Other annotations
* should be left visible.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSelectType_hideForAll()
{
selectSequences(1, 2);
* We expect the annotations of that type, linked to the sequence group, to be
* set hidden. Other annotations should be left visible.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSelectType_hideForSelected()
{
selectSequences(1, 2);
* We expect all annotations of that type to be set visible. Other annotations
* should be left unchanged.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testDeselectType_hideForAll()
{
selectSequences(1, 2);
* We expect the annotations of that type, linked to the sequence group, to be
* set visible. Other annotations should be left unchanged.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testDeselectType_hideForSelected()
{
selectSequences(1, 2);
* We expect all annotations of that type to be set visible. Other annotations
* should be left unchanged
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSelectType_showForAll()
{
selectSequences(1, 2);
* We expect all annotations of that type, linked to the sequence group, to be
* set visible. Other annotations should be left unchanged
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSelectType_showForSelected()
{
// sequences 1 and 2 have annotations IUPred and Jmol
* We expect all annotations of that type to be set hidden. Other annotations
* should be left unchanged.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testDeselectType_showForAll()
{
selectSequences(1, 2);
* We expect the annotations of that type, linked to the sequence group, to be
* set hidden. Other annotations should be left unchanged.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testDeselectType_showForSelected()
{
selectSequences(1, 2);
* Test cases include sequences in the selection group, and others not in the
* group.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testIsInActionScope_selectedScope()
{
// sequences 1 and 2 have annotations 4 and 3 respectively
* Test cases include sequences in the selection group, and others not in the
* group.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testIsInActionScope_unselectedScope()
{
// sequences 1 and 2 have annotations 4 and 3 respectively
/**
* Test that the reset method restores previous visibility flags.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testResetOriginalState()
{
testee = new AnnotationChooser(parentPanel);
--- /dev/null
+package jalview.gui;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertSame;
+
+import org.testng.annotations.Test;
+
+public class AppVarnaTest
+{
+ @Test
+ public void testReplaceOddGaps()
+ {
+ String struct = "{(<]}>)";
+ String replaced = AppVarna.replaceOddGaps(struct);
+ assertEquals(struct, replaced);
+ assertSame(struct, replaced);
+ assertEquals("..{.([.<.].}.>)",
+ AppVarna.replaceOddGaps("..{ ([*<-]?} >)"));
+ assertEquals("....", AppVarna.replaceOddGaps("cgta"));
+ assertEquals("", AppVarna.replaceOddGaps(""));
+ assertNull(AppVarna.replaceOddGaps(null));
+ }
+}
* available, plain) fonts and point sizes that would be rejected by Jalview's
* FontChooser as having an I-width of less than 1.0.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void dumpInvalidFonts()
{
String[] fonts = java.awt.GraphicsEnvironment
public class HelpTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void checkHelpTargets() throws HelpSetException
{
ClassLoader cl = Desktop.class.getClassLoader();
volatile boolean finish = false;
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void test()
{
Cache.initLogger();
public class JvSwingUtilsTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testGetScrollBarProportion()
{
/*
assertEquals(0.25f, JvSwingUtils.getScrollBarProportion(sb), 0.001f);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetScrollValueForProportion()
{
/*
{
}
- @Test
+ @Test(groups ={ "Functional" })
public void populateCmbSearchTargetOptionsTest()
{
PDBSearchPanel searchPanel = new PDBSearchPanel(null);
searchPanel.populateCmbSearchTargetOptions();
}
- @Test
+ @Test(groups ={ "Functional" })
public void testDecodeSearchTerm()
{
String expectedString = "1xyz OR text:2xyz OR text:3xyz";
assertEquals(expectedString, outcome);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testgetPDBIdwithSpecifiedChain()
{
assertEquals(expectedString, outcome);
}
- @Test
+ @Test(groups =
+ { "Network" }, timeOut = 5000)
public void txt_search_ActionPerformedTest()
{
PDBSearchPanel searchPanel = new PDBSearchPanel(null);
PaintRefresher.components.clear();
}
- @Test
+ @Test(groups ={ "Functional" })
public void testRegister()
{
JPanel jp = new JPanel();
assertTrue(registered.get("44").contains(jp4));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testRemoveComponent()
{
Map<String, List<Component>> registered = PaintRefresher.components;
assertTrue(registered.get("22").contains(jp2));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetAssociatedPanels()
{
SequenceI [] seqs = new SequenceI[]{new Sequence("", "ABC")};
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testConfigureReferenceAnnotationsMenu_noSequenceSelected()
{
JMenuItem menu = new JMenuItem();
* are no reference annotations to add to the alignment. The menu item should
* be disabled.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testConfigureReferenceAnnotationsMenu_noReferenceAnnotations()
{
JMenuItem menu = new JMenuItem();
* reference annotations are already on the alignment. The menu item should be
* disabled.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testConfigureReferenceAnnotationsMenu_alreadyAdded()
{
JMenuItem menu = new JMenuItem();
* The menu item should be enabled, and acquire a tooltip which lists the
* annotation sources (calcIds) and type (labels).
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testConfigureReferenceAnnotationsMenu()
{
JMenuItem menu = new JMenuItem();
* on the alignment. The menu item should be enabled, and acquire a tooltip
* which lists the annotation sources (calcIds) and type (labels).
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testConfigureReferenceAnnotationsMenu_notOnAlignment()
{
JMenuItem menu = new JMenuItem();
* The menu item should be enabled, and acquire a tooltip which lists the
* annotation sources (calcIds) and type (labels).
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testConfigureReferenceAnnotationsMenu_twoViews()
{
}
* Test for building menu options including 'show' and 'hide' annotation
* types.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildAnnotationTypesMenus()
{
JMenu showMenu = new JMenu();
/**
* Test for building menu options with only 'hide' annotation types enabled.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildAnnotationTypesMenus_showDisabled()
{
JMenu showMenu = new JMenu();
/**
* Test for building menu options with only 'show' annotation types enabled.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildAnnotationTypesMenus_hideDisabled()
{
JMenu showMenu = new JMenu();
private JLabel statusBar;
- @Test
+ @Test(groups ={ "Functional" })
public void testConstructor_prematureInstantiation()
{
try
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testConstructor_wrongLayout()
{
statusPanel = new JPanel();
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSetProgressBar()
{
statusPanel = new JPanel();
public class SequenceRendererTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testGetResidueBoxColour_zappo()
{
SequenceI seq = new Sequence("name", "MATVLGSPRAPAFF"); // FER1_MAIZE...
- @Test
+ @Test(groups ={ "Functional" })
public void buildQueryTest()
{
String query = StructureChooser.buildQuery(seq);
query);
}
- @Test
+ @Test(groups ={ "Functional" })
public void populateFilterComboBoxTest()
{
SequenceI[] selectedSeqs = new SequenceI[]
// should be populated
}
- @Test
+ @Test(groups ={ "Functional" })
public void fetchStructuresInfoTest()
{
SequenceI[] selectedSeqs = new SequenceI[]
.get(0).getId();
}
- @Test
+ @Test(groups ={ "Functional" })
public void checkNoDuplicates()
{
// not strictly a requirement, but strange things may happen if multiple
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void checkPDBannotationSource()
{
/**
* Check sequence features have been added
*/
- @Test
+ @Test(groups ={ "Functional" })
public void checkPDBSequenceFeatures()
{
StructureSelectionManager ssm = StructureSelectionManager
assertEquals("TYR:314 1gaqC", sf[295].getDescription());
}
- @Test
+ @Test(groups ={ "Functional" })
public void checkAnnotationWiring()
{
assertTrue(al.getAlignmentAnnotation() != null);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testJalviewProjectRelocationAnnotation() throws Exception
{
{ "Test hiding/showing of insertions on sequence_ref",
"examples/uniref50.fa", "examples/testdata/uniref50_seqref.jva" } };
- @Test
+ @Test(groups ={ "Functional" })
public void exampleAnnotationFileIO() throws Exception
{
for (String[] testPair : TestFiles)
* f
*/
- // @Test
+ // @Test(groups ={ "Functional" })
public static void testAnnotationFileIO(String testname, File f,
File annotFile)
{
public class BioJsHTMLOutputTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void getJalviewAlignmentAsJsonString()
{
String bjsTemplate = null;
Assert.assertNotNull(bjsTemplate);
}
- @Test(expectedExceptions = NullPointerException.class)
+ @Test(groups =
+ { "Functional" }, expectedExceptions = NullPointerException.class)
public void expectedNullPointerException()
{
try
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void getBioJsMSAVersions()
{
TreeMap<String, File> versions = null;
}
- @Test
+ @Test(groups =
+ { "Network" })
public void testBioJsUpdate()
{
String url = BioJsHTMLOutput.BJS_TEMPLATE_GIT_REPO;
+ "' identified as '" + type + "'", type.equalsIgnoreCase(fmt));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testStarsInFasta1() throws IOException
{
String uri;
assertValidFormat("FASTA", uri, fp);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testStarsInFasta2() throws IOException
{
String uri;
assertValidFormat("FASTA", uri, fp);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGzipIo() throws IOException
{
String uri;
assertValidFormat("FASTA", uri, fp);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGziplocalFileIO() throws IOException
{
String filepath;
assertValidFormat("FASTA", filepath, fp);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testNonGzipURLIO() throws IOException
{
String uri;
assertValidFormat("FASTA", uri, fp);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testNonGziplocalFileIO() throws IOException
{
String filepath;
package jalview.io;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertTrue;
+
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceDummy;
import java.io.IOException;
-import org.junit.Assert;
-import org.junit.Test;
+import org.testng.annotations.Test;
public class Gff3tests
{
exonerateOutput = "examples/testdata/exonerateoutput.gff",
simpleGff3file = "examples/testdata/simpleGff3.gff";
- @Test
+ @Test(groups ={ "Functional" })
public void testExonerateImport()
{
// exonerate does not tag sequences after features, so we have a more
AlignFrame af = loader.LoadFileWaitTillLoaded(exonerateSeqs,
FormatAdapter.FILE);
- Assert.assertEquals("Unexpected number of DNA protein associations", 0,
+ assertEquals("Unexpected number of DNA protein associations", 0,
af.getViewport().getAlignment().getCodonFrames().size());
af.loadJalviewDataFile(exonerateOutput, FormatAdapter.FILE, null, null);
- Assert.assertNotEquals("Expected at least one DNA protein association",
- 0, af.getViewport().getAlignment().getDataset()
- .getCodonFrames().size());
+ assertTrue("Expected at least one DNA protein association", af
+ .getViewport().getAlignment().getDataset().getCodonFrames()
+ .size() > 0);
}
- @Test
+ @Test(groups ={ "Functional" })
public void simpleGff3FileIdentify()
{
- Assert.assertEquals("Didn't recognise file correctly.",
+ assertEquals("Didn't recognise file correctly.",
IdentifyFile.GFF3File,
new IdentifyFile().Identify(simpleGff3file, FormatAdapter.FILE));
}
- @Test
+ @Test(groups ={ "Functional" })
public void simpleGff3FileClass() throws IOException
{
AlignmentI dataset = new Alignment(new SequenceI[]
FormatAdapter.FILE);
boolean parseResult = ffile.parse(dataset, null, null, false, false);
- Assert.assertTrue("return result should be true", parseResult);
+ assertTrue("return result should be true", parseResult);
checkDatasetfromSimpleGff3(dataset);
}
- @Test
+ @Test(groups ={ "Functional" })
public void simpleGff3FileLoader() throws IOException
{
AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
simpleGff3file, FormatAdapter.FILE);
- Assert.assertTrue(
+ assertTrue(
"Didn't read the alignment into an alignframe from Gff3 File",
af != null);
checkDatasetfromSimpleGff3(af.getViewport().getAlignment().getDataset());
}
- @Test
+ @Test(groups ={ "Functional" })
public void simpleGff3RelaxedIdMatching() throws IOException
{
AlignmentI dataset = new Alignment(new SequenceI[]
FormatAdapter.FILE);
boolean parseResult = ffile.parse(dataset, null, null, false, true);
- Assert.assertTrue("return result (relaxedID matching) should be true",
+ assertTrue("return result (relaxedID matching) should be true",
parseResult);
checkDatasetfromSimpleGff3(dataset);
}
- @Test
+ @Test(groups ={ "Functional" })
public void readGff3File() throws IOException
{
Gff3File gff3reader = new Gff3File(simpleGff3file, FormatAdapter.FILE);
private void checkDatasetfromSimpleGff3(AlignmentI dataset)
{
- Assert.assertEquals("no sequences extracted from GFF3 file", 2,
+ assertEquals("no sequences extracted from GFF3 file", 2,
dataset.getHeight());
SequenceI seq1 = dataset.findName("seq1"), seq2 = dataset
.findName("seq2");
- Assert.assertNotNull(seq1);
- Assert.assertNotNull(seq2);
- Assert.assertFalse(
+ assertNotNull(seq1);
+ assertNotNull(seq2);
+ assertFalse(
"Failed to replace dummy seq1 with real sequence",
seq1 instanceof SequenceDummy
&& ((SequenceDummy) seq1).isDummy());
- Assert.assertFalse(
+ assertFalse(
"Failed to replace dummy seq2 with real sequence",
seq2 instanceof SequenceDummy
&& ((SequenceDummy) seq2).isDummy());
String placeholderseq = new SequenceDummy("foo").getSequenceAsString();
- Assert.assertFalse("dummy replacement buggy for seq1",
+ assertFalse("dummy replacement buggy for seq1",
placeholderseq.equals(seq1.getSequenceAsString()));
- Assert.assertNotEquals("dummy replacement buggy for seq2",
+ assertFalse("dummy replacement buggy for seq2",
placeholderseq.equals(seq2.getSequenceAsString()));
- Assert.assertNotNull("No features added to seq1",
+ assertNotNull("No features added to seq1",
seq1.getSequenceFeatures());// != null);
- Assert.assertEquals("Wrong number of features", 3,
+ assertEquals("Wrong number of features", 3,
seq1.getSequenceFeatures().length);
- Assert.assertNull(seq2.getSequenceFeatures());
- Assert.assertEquals("Wrong number of features", 0, seq2
+ assertNull(seq2.getSequenceFeatures());
+ assertEquals(
+ "Wrong number of features",
+ 0,
+ seq2
.getSequenceFeatures() == null ? 0
: seq2.getSequenceFeatures().length);
- Assert.assertTrue(
+ assertTrue(
"Expected at least one CDNA/Protein mapping for seq1",
dataset.getCodonFrame(seq1) != null
&& dataset.getCodonFrame(seq1).size() > 0);
}
- // @Test
+ // @Test(groups ={ "Functional" })
// public final void testPrintGFFFormatSequenceIArrayMapOfStringObject()
// {
// fail("Not yet implemented");
// }
//
- // @Test
+ // @Test(groups ={ "Functional" })
// public final void testAlignFileBooleanStringString()
// {
// fail("Not yet implemented");
public class HtmlFileTest
{
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void test()
{
fail("Not yet implemented");
jf = null;
}
- @Test
+ @Test(groups ={ "Functional" })
public void roundTripTest()
{
assertNotNull("JSON roundtrip test failed!", testJsonFile);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSeqParsed()
{
assertNotNull("Couldn't read supplied alignment data.", testAlignment);
TEST_SEQ_HEIGHT, passedCount);
}
- @Test
+ @Test(groups ={ "Functional" })
public void hiddenColsTest()
{
ColumnSelection cs = testJsonFile.getColumnSelection();
"Mismatched hidden columns!");
}
- @Test
+ @Test(groups ={ "Functional" })
public void hiddenSeqsTest()
{
Assert.assertNotNull(testJsonFile.getHiddenSequences(),
"Hidden sequece");
}
- @Test
+ @Test(groups ={ "Functional" })
public void colorSchemeTest()
{
Assert.assertNotNull(testJsonFile.getColourScheme(),
"Zappo colour scheme expected!");
}
- @Test
+ @Test(groups ={ "Functional" })
public void isShowSeqFeaturesSet()
{
Assert.assertTrue(testJsonFile.isShowSeqFeatures(),
"Sequence feature isDisplayed setting expected to be true");
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGrpParsed()
{
Assert.assertNotNull(testAlignment.getGroups());
TEST_GRP_HEIGHT, passedCount);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testAnnotationParsed()
{
Assert.assertNotNull(testAlignment.getAlignmentAnnotation());
return numdsann;
}
- @Test
+ @Test(groups ={ "Functional" })
public void testRNAStructureRecovery() throws Exception
{
String inFile = "examples/RF00031_folded.stk";
af.getViewport().getGlobalColourScheme() instanceof jalview.schemes.RNAHelicesColour);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testTCoffeeScores() throws Exception
{
String inFile = "examples/uniref50.fa", inAnnot = "examples/uniref50.score_ascii";
.println("T-Coffee score shading successfully recovered from project.");
}
- @Test
+ @Test(groups ={ "Functional" })
public void testColourByAnnotScores() throws Exception
{
String inFile = "examples/uniref50.fa", inAnnot = "examples/testdata/uniref50_iupred.jva";
.println("Per sequence (Group) colourscheme successfully applied and recovered.");
}
- @Test
+ @Test(groups ={ "Functional" })
public void gatherViewsHere() throws Exception
{
int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop
}
- @Test
+ @Test(groups ={ "Functional" })
public void viewRefPdbAnnotation() throws Exception
{
Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
}
- @Test
+ @Test(groups ={ "Functional" })
public void testCopyViewSettings() throws Exception
{
AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
{
}
- @Test
+ @Test(groups ={ "Functional" })
public void testTreeIO() throws Exception
{
String stage = "Init", treename = " '" + name + "' :";
*
* @throws Exception
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSequentialDataExtraction() throws Exception
{
testDataExtraction(sequentialFile);
*
* @throws Exception
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testInterleavedDataExtraction() throws Exception
{
testDataExtraction(interleavedFile);
*
* @throws Exception
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSequentialIO() throws Exception
{
testIO(sequentialFile);
*
* @throws Exception
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testInterleavedIO() throws Exception
{
testIO(interleavedFile);
{
}
- @Test
+ @Test(groups ={ "Functional" })
public void testRnamlToStockholmIO()
{
StockholmFileTest.testFileIOwithFormat(new File(
static String PfamFile = "examples/PF00111_seed.stk",
RfamFile = "examples/RF00031_folded.stk";
- @Test
+ @Test(groups ={ "Functional" })
public void pfamFileIO() throws Exception
{
testFileIOwithFormat(new File(PfamFile), "STH", -1, 0);
}
- @Test
+ @Test(groups ={ "Functional" })
public void pfamFileDataExtraction() throws Exception
{
AppletFormatAdapter af = new AppletFormatAdapter();
numpdb > 0);
}
- @Test
+ @Test(groups ={ "Functional" })
public void rfamFileIO() throws Exception
{
testFileIOwithFormat(new File(RfamFile), "STH", 2, 1);
final static File ALIGN_FILE = new File(
"test/jalview/io/tcoffee.fasta_aln");
- @Test
+ @Test(groups ={ "Functional" })
public void testReadHeader() throws IOException
{
AssertJUnit.assertEquals(90, header.getScoreFor("cons"));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testWrongFile()
{
try
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testHeightAndWidth() throws IOException
{
TCoffeeScoreFile result = new TCoffeeScoreFile(SCORE_FILE.getPath(),
AssertJUnit.assertEquals(83, result.getWidth());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testReadBlock() throws IOException
{
block.getConsensus());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testParse() throws IOException
{
parser.getScoresFor("cons"));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetAsList() throws IOException
{
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetAsArray() throws IOException
{
}
- @Test
+ @Test(groups ={ "Functional" })
public void testHeightAndWidthWithResidueNumbers() throws Exception
{
String file = "test/jalview/io/tcoffee.score_ascii_with_residue_numbers";
public class DnaCodonTests
{
- @Test
+ @Test(groups ={ "Functional" })
public void testAmbiguityCodeGeneration()
{
assertTrue(ResidueProperties.ambiguityCodes.size() > 0);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testAmbiguityCodon()
{
for (String ac : ResidueProperties.ambiguityCodes.keySet())
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void regenerateCodonTable()
{
for (Map.Entry<String, String> codon : ResidueProperties.codonHash2
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void checkOldCodonagainstNewCodonTable()
{
// note - this test will be removed once the old codon table (including
/**
* Test 'standard' codon translations (no ambiguity codes)
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testCodonTranslate()
{
// standard translation table order column 1/2/3/4
* Test a sample of codon translations involving ambiguity codes. Should
* return a protein value where the ambiguity does not affect the translation.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testCodonTranslate_ambiguityCodes()
{
// Y is C or T
assertNull(ResidueProperties.codonTranslate("WSK"));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetResidues_nucleotide()
{
/*
assertEquals("[A, C, G, I, N, R, T, U, X, Y]", residues.toString());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetResidues_peptide()
{
/*
public class ScoreMatrixPrinter
{
- @Test
+ @Test(groups ={ "Functional" })
public void printAllMatrices()
{
for (Map.Entry<String, ScoreModelI> sm : ResidueProperties.scoreMatrices
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void printHTMLMatrices()
{
for (Map.Entry<String, ScoreModelI> _sm : ResidueProperties.scoreMatrices
* 115 in PDB Res Numbering secondary structure numbers in jmol seem to be in
* msd numbering, not pdb res numbering.
*/
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void pdbEntryPositionMap() throws Exception
{
Assert.fail("This test intentionally left to fail");
}
}
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void testPDBentryMapping() throws Exception
{
Assert.fail("This test intentionally left to fail");
* transform
*
*/
- @Test
+ @Test(groups ={ "Functional" })
public void mapFer1From3W5V() throws Exception
{
AlignFrame seqf = new FileLoader(false)
* compare reference annotation for imported pdb sequence to identical
* seuqence with transferred annotation from mapped pdb file
*/
- @Test
+ @Test(groups ={ "Functional" })
public void compareTransferredToRefPDBAnnot() throws Exception
{
AlignFrame ref = new FileLoader(false)
ssm = new StructureSelectionManager();
}
- @Test
+ @Test(groups ={ "Functional" })
public void testAddMapping()
{
AlignedCodonFrame acf1 = new AlignedCodonFrame();
assertEquals(1, ssm.seqMappingRefCounts.get(acf2).intValue());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testAddMappings()
{
AlignedCodonFrame acf1 = new AlignedCodonFrame();
assertEquals(1, ssm.seqMappingRefCounts.get(acf3).intValue());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testRemoveMapping()
{
AlignedCodonFrame acf1 = new AlignedCodonFrame();
assertEquals(0, ssm.seqMappingRefCounts.size());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testRemoveMappings()
{
AlignedCodonFrame acf1 = new AlignedCodonFrame();
* Verify that the method determines that columns 2, 5 and 6 of the aligment
* are alignable in structure
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testFindSuperposableResidues()
{
SuperposeData[] structs = new SuperposeData[al.getHeight()];
assertTrue(matched[5]);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testFindSuperposableResidues_hiddenColumn()
{
SuperposeData[] structs = new SuperposeData[al.getHeight()];
Color darkColour = new Color(11, 30, 50); // dark blue
- @Test
+ @Test(groups ={ "Functional" })
public void testDarkerThan()
{
assertEquals("Wrong darker shade", new Color(32, 69, 37),
assertNull(ColorUtils.darkerThan(null));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testBrighterThan()
{
assertEquals("Wrong brighter shade", new Color(255, 255, 255), // white
/**
* @see http://www.rtapo.com/notes/named_colors.html
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testToTkCode()
{
assertEquals("#fffafa", ColorUtils.toTkCode(new Color(255, 250, 250))); // snow
public class ComparisonTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testIsGap()
{
assertTrue(Comparison.isGap('-'));
* Test for isNucleotide is that sequences in a dataset are more than 85%
* AGCTU. Test is not case-sensitive and ignores gaps.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testIsNucleotide() {
SequenceI seq = new Sequence("eightypercent", "agctuAGCPV");
assertFalse(Comparison.isNucleotide(new SequenceI[]
/**
* Test percentage identity calculation for two sequences.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testPID_matchGaps()
{
String seq1 = "ABCDEF";
* Test the method that selects DBRefEntry items whose source is in a supplied
* list
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSelectRefs()
{
assertNull(DBRefUtils.selectRefs(null, null));
* Test the method that converts (currently three) database names to a
* canonical name (not case-sensitive)
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetCanonicalName()
{
assertNull(DBRefUtils.getCanonicalName(null));
DBRefUtils.getCanonicalName("UNIPROTKB/SWISS-CHEESE"));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testIsDasCoordinateSystem()
{
assertFalse(DBRefUtils.isDasCoordinateSystem(null, null));
/**
* Test 'parsing' a DBRef - non PDB case
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testParseToDbRef()
{
SequenceI seq = new Sequence("Seq1", "ABCD");
/**
* Test 'parsing' a DBRef - Stockholm PDB format
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testParseToDbRef_PDB()
{
SequenceI seq = new Sequence("Seq1", "ABCD");
* Test the method that searches for matches references - case when we are
* matching a reference with no mappings
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSearchRefs_noMapping()
{
DBRefEntry target = new DBRefEntry("EMBL", "2", "A1234");
* Test the method that searches for matches references - case when we are
* matching a reference with a mapping
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSearchRefs_withMapping()
{
DBRefEntry target = new DBRefEntry("EMBL", "2", "A1234");
public class MapListTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testSomething()
{
MapList ml = new MapList(new int[]
* Tests for method that locates ranges in the 'from' map for given range in
* the 'to' map.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testLocateInFrom_noIntrons()
{
/*
* Tests for method that locates ranges in the 'from' map for given range in
* the 'to' map.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testLocateInFrom_withIntrons()
{
/*
* Tests for method that locates ranges in the 'to' map for given range in the
* 'from' map.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testLocateInTo_noIntrons()
{
/*
* Tests for method that locates ranges in the 'to' map for given range in the
* 'from' map.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testLocateInTo_withIntrons()
{
/*
/**
* Test equals method.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testEquals()
{
int[] codons = new int[]
/**
* Test for the method that flattens a list of ranges into a single array.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetRanges()
{
List<int[]> ranges = new ArrayList<int[]>();
/**
* Check state after construction
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testConstructor()
{
int[] codons =
/**
* Test the method that creates an inverse mapping
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetInverse()
{
int[] codons =
prettyPrint(ml2.getFromRanges()));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testToString()
{
MapList ml = new MapList(new int[]
/**
* Simple test of mapping with no intron involved.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildSearchResults()
{
final Sequence seq1 = new Sequence("Seq1", "C-G-TA-GC");
/**
* Simple test of mapping with introns involved.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testBuildSearchResults_withIntron()
{
final Sequence seq1 = new Sequence("Seq1", "C-G-TAGA-GCAGCTT");
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMapSequenceGroup_sequences() throws IOException
{
/*
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMapColumnSelection_proteinToDna() throws IOException
{
setupMappedAlignments();
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMapColumnSelection_dnaToProtein() throws IOException
{
setupMappedAlignments();
assertEquals("[0, 1, 3]", cs.getSelected().toString());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testMapColumnSelection_null() throws IOException
{
setupMappedAlignments();
* Tests for the method that converts a series of [start, end] ranges to
* single positions
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testFlattenRanges()
{
assertEquals("[1, 2, 3, 4]",
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMapSequenceGroup_columns() throws IOException
{
/*
*
* @throws IOException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testMapSequenceGroup_region() throws IOException
{
/*
assertEquals(4, mappedGroup.getEndRes());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testFindMappingsForSequence()
{
SequenceI seq1 = new Sequence("Seq1", "ABC");
{ c1, c2, c3, c4 };
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSort_byIntValues()
{
int[] values = new int[]
assertTrue(Arrays.equals(sortedThings, things));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSort_byFloatValues()
{
float[] values = new float[]
assertTrue(Arrays.equals(sortedThings, things));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSort_byDoubleValues()
{
double[] values = new double[]
/**
* Sort by String is descending order, case-sensitive
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSort_byStringValues()
{
String[] values = new String[]
/**
* Test whether sort is stable i.e. equal values retain their mutual ordering.
*/
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void testSort_withDuplicates()
{
int[] values = new int[]
* Test that exercises sort with a mostly zero-valued sortby array. May be of
* interest to check the sort algorithm is efficient.
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testSort_MostlyZeroValues()
{
char[] residues = new char[64];
public class ShiftListTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testParseMap()
{
assertNull(ShiftList.parseMap(null));
public class StringUtilsTest
{
- @Test
+ @Test(groups ={ "Functional" })
public void testInsertCharAt()
{
char[] c1 = "ABC".toCharArray();
StringUtils.insertCharAt(c1, 7, 2, 'w')));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testDeleteChars()
{
char[] c1 = "ABC".toCharArray();
assertTrue(Arrays.equals(c1, StringUtils.deleteChars(c1, 3, 4)));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testGetLastToken()
{
assertNull(StringUtils.getLastToken(null, null));
"file://localhost:8080/data/examples/file1.dat", "/"));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testSeparatorListToArray()
{
String[] result = StringUtils.separatorListToArray(
.separatorListToArray("abc='|'d|ef|g", "|")));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testArrayToSeparatorList()
{
assertEquals("*", StringUtils.arrayToSeparatorList(null, "*"));
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testCopyConstructor() throws IllegalArgumentException,
IllegalAccessException
{
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testEquals() throws IllegalArgumentException,
IllegalAccessException
{
sf = new SequenceFetcher(false);
}
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void testRnaSeqRetrieve() throws Exception
{
List<DbSourceProxy> sps = sf.getSourceProxy("PDB");
{
}
- @Test
+ @Test(groups =
+ { "External" })
public void executeRequestTest()
{
List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
assertTrue(response.getSearchSummary().size() > 99);
}
- @Test
+ @Test(groups ={ "Functional" })
public void getPDBDocFieldsAsCommaDelimitedStringTest()
{
List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
assertEquals("", expectedResult, actualResult);
}
- @Test
+ @Test(groups =
+ { "External" })
public void parsePDBJsonExceptionStringTest()
{
List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
assertEquals(expectedErrorMsg, parsedErrorResponse);
}
- @Test(expectedExceptions = Exception.class)
+ @Test(groups =
+ { "External" }, expectedExceptions = Exception.class)
public void testForExpectedRuntimeException() throws Exception
{
List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
new PDBRestClient().executeRequest(request);
}
- @Test
+ @Test(groups =
+ { "External" })
public void parsePDBJsonResponseTest()
{
List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
assertTrue(response.getSearchSummary().size() == 14);
}
- @Test
+ @Test(groups ={ "Functional" })
public void getPDBIdColumIndexTest()
{
List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
assertEquals(4, PDBRestClient.getPDBIdColumIndex(wantedFields, false));
}
- @Test
+ @Test(groups =
+ { "External" })
public void externalServiceIntegrationTest()
{
ClientConfig clientConfig = new DefaultClientConfig();
/**
* Test the method that unmarshals XML to a Uniprot model
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetUniprotEntries()
{
Uniprot u = new Uniprot();
/**
* Test the method that formats the sequence name in Fasta style
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testConstructSequenceFastaHeader()
{
Uniprot u = new Uniprot();
* rather than hang
*/
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void testJws2Gui()
{
Iterator<String> presetEnum = presetTests.iterator();
/**
* test for patches to JAL-1294
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testDisorderAnnotExport()
{
disorderClient = new AADisorderClient(iupreds.get(0), af, null, null);
{ "http://localhost:8080/jabaws",
"http://www.compbio.dundee.ac.uk/jabaws" };
- @Test(enabled = false)
+ @Test(groups =
+ { "Functional" }, enabled = false)
public void testAnnotExport()
{
fail("Not yet implemented");
for (Jws2Instance svc : disc.getServices())
{
-
if (svc.getServiceTypeURI().toLowerCase().contains("jpred"))
{
jpredws = svc;
}
System.out.println("State of jpredws: " + jpredws);
-
- if (jpredws == null)
- {
- Assert.fail("jpredws is null");
- }
-
+ Assert.assertNotNull(jpredws, "jpredws is null!");
jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
-
af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.FormatAdapter.FILE);
-
assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
-
}
@AfterClass
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testJPredStructOneSeqOnly()
{
af.selectAllSequenceMenuItem_actionPerformed(null);
}
- @Test
+ @Test(groups ={ "Functional" })
public void testJPredStructExport()
{
+ "\nCouldn't complete Annotation file roundtrip input/output/input test.");
}
- @Test
+ @Test(groups ={ "Functional" })
public void testJpredwsSettingsRecovery()
{
Assert.fail("not implemnented");
* @throws Exception
*/
@SuppressWarnings("rawtypes")
- @Test
+ @Test(groups =
+ { "Network" })
public void msaTest() throws Exception {
String url;
RegistryWS registry = Jws2Client
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testRNAAliFoldValidStructure()
{
}
}
- @Test
+ @Test(groups ={ "Functional" })
public void testRNAStructExport()
{
+ "\nCouldn't complete Annotation file roundtrip input/output/input test.");
}
- @Test
+ @Test(groups ={ "Functional" })
public void testRnaalifoldSettingsRecovery()
{
List<compbio.metadata.Argument> opts = new ArrayList<compbio.metadata.Argument>();
disc = JalviewJabawsTestUtils.getJabawsDiscoverer();
}
- @Test
+ @Test(groups ={ "Functional" })
public void testWriteParameterSet() throws WrongParameterException
{
for (Jws2Instance service : disc.getServices())
|| serviceTests.contains(service.serviceType.toLowerCase());
}
- @Test
+ @Test(groups ={ "Functional" })
public void testCopyOption()
{
for (Jws2Instance service : disc.getServices())
/**
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testCopyParameter()
{
for (Jws2Instance service : disc.getServices())
/**
* Refactored 'as is' from main method
*/
- @Test
+ @Test(groups ={ "Functional" })
public void testGetRestClient()
{
/*
public class ShmmrRSBSService
{
- @Test
+ @Test(groups ={ "Functional" })
public void testShmmrService()
{
RestClient.makeShmmrRestClient().service));
}
- @Test
+ @Test(groups ={ "Functional" })
public void testShmmrServiceDataprep() throws Exception
{
RestClient _rc = RestClient.makeShmmrRestClient();
public class DasSequenceFetcher
{
- @Test
+ @Test(groups ={ "Functional" })
public void testDasRegistryContact()
{
jalview.bin.Cache.getDasSourceRegistry().refreshSources();
{
}
- @Test
+ @Test(groups ={ "Functional" })
public void testStandardProtDbs()
{
String[] defdb = DBRefSource.PROTEINDBS;
uniprot != null && i < 2);
}
- @Test
+ @Test(groups =
+ { "External" })
public void testEmblUniprotProductRecovery() throws Exception
{
String retrievalId = "CAA23748"; // "V00488";
verifyProteinNucleotideXref(retrievalId, embl);
}
- @Test
+ @Test(groups =
+ { "External" })
public void testEmblCDSUniprotProductRecovery() throws Exception
{
String retrievalId = "AAH29712";
<string><![CDATA[664]]></string>
</property>
<property name="sourceName">
- <string><![CDATA[VARNAv3-91.jar]]></string>
+ <string><![CDATA[VARNAv3-93.jar]]></string>
</property>
<property name="overrideUnixPermissions">
<boolean>false</boolean>
<boolean>true</boolean>
</property>
<property name="destinationName">
- <string><![CDATA[VARNAv3-91.jar]]></string>
+ <string><![CDATA[VARNAv3-93.jar]]></string>
</property>
<property name="fileSize">
<long>663408</long>